准备《JavaEE微服务框架》课程时,用了 Spring Cloud Alibaba 的示例项目。测试发现项目 sentinel-core-example 的授权规则实现中黑名单和白名单不起作用。通过跟踪执行源代码、问GPT终于搞清楚了原因,这个问题搞了一天才解决掉。不起作用的原因既包括客户端的问题,也包括服务端的问题:

  1. 客户端调用程序使用默认的RestTemplate不会向服务程序发送应用程序名称,所以自然就无法用程序名称限制程序的访问,客户端需要定制RestTemplate。
  2. 服务程序中使用注解 @SentinelResource("resource") 不会判断请求来源。在注解 @SentinelResource说明的控制器方法中,自己写代码获取context对象后设置origin,也没有阻止黑名单访问,应该是顺序问题,设置origin应该是晚了,进了注解 @SentinelResource说明的控制器方法,说明流量控制检查已经完成了。

  • 解决方案也是分为调用程序和服务程序两端的处理:

  • 客户端的调用程序,定制RestTemplate,发送应用程序名称
  • 通过拦截器,对发出的HTTP请求设置 headers信息。
  • 在下面的配置类中,为注入的 RestTemplate对象设置拦截器,发送客户端程序服务端口号和名称。
  • 使用定制的RestTemplate对象发送HTTP请求,请求的Headers信息中包含客户端程序名称。
  • 服务程序,自己进行流量控制检查
  • 下面是服务端控制器方法,可通过参数获取使用Headers里的信息。
  • 下面代码首先获取资源的上下文环境 context 对象,为其设置访问来源(客户端程序名称),通过 entry 方法尝试获取资源,如果规则允许,执行后面代码,如果规则不允许,则抛出 BlockException 阻塞访问异常。
  • 服务端配置文件中对sentinel进行配置
  • 授权文件中设置黑名单和白名单对应的程序名单。
  • 测试后,证明黑白名单是可以用的。

更多推荐