插件扩展

    • 插件是 网关的核心执行者,每个插件在开启的情况下,都会对匹配的流量,进行自己的处理。
    • Apache ShenYu 网关里面,插件分为两类。
      • 一类是单一职责的调用链,不能对流量进行自定义的筛选。
      • 一类是能对匹配的流量,执行自己的职责调用链。
    • 用户可以参考 模块,新增自己的插件处理,如果有好的公用插件,可以向官网提交pr
    • 引入如下依赖:
    • 用户新增一个类 MyShenyuPlugin,直接实现 org.apache.shenyu.plugin.api.ShenyuPlugin
    1. public interface ShenyuPlugin {
    2. /**
    3. * Process the Web request and (optionally) delegate to the next
    4. * {@code WebFilter} through the given {@link ShenyuPluginChain}.
    5. *
    6. * @param exchange the current server exchange
    7. * @param chain provides a way to delegate to the next filter
    8. * @return {@code Mono<Void>} to indicate when request processing is complete
    9. */
    10. Mono<Void> execute(ServerWebExchange exchange, ShenyuPluginChain chain);
    11. /**
    12. * return plugin order .
    13. * This attribute To determine the plugin execution order in the same type plugin.
    14. *
    15. * @return int order
    16. */
    17. int getOrder();
    18. /**
    19. * acquire plugin name.
    20. * this is plugin name define you must Provide the right name.
    21. * if you impl AbstractShenyuPlugin this attribute not use.
    22. *
    23. * @return plugin name.
    24. */
    25. default String named() {
    26. return "";
    27. }
    28. /**
    29. * plugin is execute.
    30. * if return true this plugin can not execute.
    31. *
    32. * @param exchange the current server exchange
    33. * @return default false.
    34. */
    35. default Boolean skip(ServerWebExchange exchange) {
    36. return false;
    37. }
    38. }
      • getOrder() 指定插件的排序。

      • named() 指定插件的名称,命名采用Camel Case,如:dubbospringCloud

      • skip() 在特定的条件下,该插件是否被跳过。

    • 注册成Springbean,参考如下,或者直接在实现类上加 @Component 注解。

    1. @Bean
    2. return new MyShenyuPlugin();
    3. }
    • 引入如下依赖:
    • 新增一个类 CustomPlugin,继承 org.apache.shenyu.plugin.base.AbstractShenyuPlugin

    1. /**
    2. * This is your custom plugin.
    3. * He is running in after before plugin, implement your own functionality.
    4. * extends AbstractShenyuPlugin so you must user shenyu-admin And add related plug-in development.
    5. *
    6. * @author xiaoyu(Myth)
    7. */
    8. public class CustomPlugin extends AbstractShenyuPlugin {
    9. /**
    10. * return plugin order .
    11. * The same plugin he executes in the same order.
    12. *
    13. * @return int
    14. */
    15. @Override
    16. public int getOrder() {
    17. return 0;
    18. }
    19. /**
    20. * acquire plugin name.
    21. * return you custom plugin name.
    22. * It must be the same name as the plug-in you added in the admin background.
    23. *
    24. * @return plugin name.
    25. */
    26. @Override
    27. public String named() {
    28. return "shenYu";
    29. }
    30. /**
    31. * plugin is execute.
    32. * Do I need to skip.
    33. * if you need skip return true.
    34. *
    35. * @param exchange the current server exchange
    36. * @return default false.
    37. */
    38. @Override
    39. public Boolean skip(final ServerWebExchange exchange) {
    40. return false;
    41. }
    42. * this is Template Method child has Implement your own logic.
    43. *
    44. * @param exchange exchange the current server exchange
    45. * @param chain chain the current chain
    46. * @param selector selector
    47. * @param rule rule
    48. * @return {@code Mono<Void>} to indicate when request handling is complete
    49. @Override
    50. protected abstract Mono<Void> doExecute(ServerWebExchange exchange, ShenyuPluginChain chain, SelectorData selector, RuleData rule) {
    51. LOGGER.debug(".......... function plugin start..............");
    52. /*
    53. * Processing after your selector matches the rule.
    54. * rule.getHandle() is you Customize the json string to be processed.
    55. * for this example.
    56. * Convert your custom json string pass to an entity class.
    57. */
    58. final String ruleHandle = rule.getHandle();
    59. final Test test = GsonUtils.getInstance().fromJson(ruleHandle, Test.class);
    60. /*
    61. * Then do your own business processing.
    62. * The last execution chain.execute(exchange).
    63. * Let it continue on the chain until the end.
    64. */
    65. System.out.println(test.toString());
    66. return chain.execute(exchange);
    67. }
    68. }
    • 详细讲解:

      • 继承该类的插件,插件会进行选择器规则匹配。

      • 首先在 shenyu-admin 后台管理系统 —> 基础配置 —> 插件管理 中,新增一个插件,注意 名称与 你自定义插件的 named() 方法要一致。

      • 重新登陆 shenyu-admin 后台,可以看见刚新增的插件,然后就可以进行选择器规则匹配。

      • 在规则中,有个 handler 字段,是自定义处理数据,在 doExecute() 方法中,通过 final String ruleHandle = rule.getHandle(); 获取,然后进行你的操作。

    • 注册成Springbean,参考如下或者直接在实现类上加 @Component 注解。

    1. @Bean
    2. public ShenyuPlugin customPlugin() {
    3. return new CustomPlugin();
    4. }
    • 新增一个类 PluginDataHandler,实现 org.apache.shenyu.plugin.base.handler.PluginDataHandler
    • 注册成Springbean,参考如下或者直接在实现类上加 @Component 注解。

    1. @Bean
    2. public PluginDataHandler pluginDataHandler() {
    3. return new PluginDataHandler();
    4. }
    • 当使用此功能时候,上述扩展 ShenyuPlugin, PluginDataHandler, 不用成为 spring bean。只需要构建出扩展项目的jar包即可。

    • 使用以下配置:

    1. shenyu:
    2. extPlugin:
    3. path: //加载扩展插件jar包路径
    4. enabled: true //是否开启
    5. threads: 1 //加载插件线程数量
    6. scheduleTime: 300 //间隔时间(单位:秒)
    7. scheduleDelay: 30 //网关启动后延迟多久加载(单位:秒)

    插件加载路径详解

    • 此路径是为存放扩展插件jar包的目录。

    • 可以使用 -Dplugin-ext=xxxx 指定,也可以使用 shenyu.extPlugin.path配置文件指定,如果都没配置,默认会加载网关启动路径下的 ext-lib目录。