经过前几个核心组件,能够构建一个简略(不完善)的微服务架构:html
在该架构中,咱们的服务集群包含:内部服务Service A和Service B,他们都会注册与订阅服务至Eureka Server,而Open Service是一个对外的服务,经过均衡负载公开至服务调用方。前端
当前架构存在的不足:java
解决思路:laravel
须要将权限控制这样的东西从咱们的服务单元中抽离出去,而最适合这些逻辑的地方就是处于对外访问最前端的地方,咱们须要一个更强大一些的均衡负载器,也就是服务网关。git
服务网关是微服务架构中一个不可或缺的部分。经过服务网关统一贯外系统提供REST API的过程当中,除了具有服务路由、均衡负载功能以外,它还具有了权限控制等功能。Spring Cloud Netflix中的Zuul就担任了这样的一个角色,为微服务架构提供了前门保护的做用,同时将权限控制这些较重的非业务逻辑内容迁移到服务路由层面,使得服务集群主体可以具有更高的可复用性和可测试性。github
2.1 基于以前工程,建立新模块zuul-service,选择Spring Initializr->Cloud Discovery->Eureka Discovery,并添加如下依赖:web
<dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zuul</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies>
2.2 启动类上添加@EnableZuulProxy开启Zuul功能spring
@SpringBootApplication @EnableZuulProxy public class ZuulServiceApplication { public static void main(String[] args) { SpringApplication.run(ZuulServiceApplication.class, args); } }
2.3 配置文件添加相关配置api
server: port: 8769 eureka: client: serviceUrl: defaultZone: http://localhost:8761/eureka/ spring: application: name: zuul-service #指明应用名称(服务与服务相互调用根据name属性) zuul: routes: api-a: path: /api-ribbon-service/** serviceId: ribbon-service api-b: path: /api-feign-service/** serviceId: feign-service
配置服务端口为8769,应用名称为 zuul-service;配置以/api-ribbon-service/开头的请求转发到ribbion-service服务,以/api-feign-service/开头的请求转发到feign-service服务。浏览器
2.4 依次启动服务注册中心、one-service、ribbon-service、feign-service、zuul-service
浏览器请求 http://localhost:8769/api-ribbon-service/one 结果:
浏览器请求http://localhost:8769/api-feign-service/one 结果:
说明zuul起到了路由功能。
添加自定义的受权过滤器,继承ZuulFilter
@Component public class MyAuthFilter extends ZuulFilter { private static final Logger LOGGER = LoggerFactory.getLogger(MyAuthFilter.class); @Override public String filterType() { return "pre"; } @Override public int filterOrder() { return 0; } @Override public boolean shouldFilter() { return true; } @Override public Object run() { RequestContext context = RequestContext.getCurrentContext(); HttpServletRequest request = context.getRequest(); LOGGER.info("{}--->{}", request.getMethod(), request.getRequestURL().toString()); Object token = request.getParameter("token"); if (token == null) { LOGGER.info("token is empty"); context.setSendZuulResponse(false); context.setResponseStatusCode(401); try { context.getResponse().getWriter().write("token is empty"); } catch (Exception e) { } return null; } LOGGER.info("ok"); return null; } }
① filterType定义:
Zuul Request Lifecycle
② filterOrder:过滤顺序
③ shouldFilter:是否须要过滤,返回boolean值
④ run:过滤逻辑
浏览器访问 http://localhost:8769/api-feign-service/one 结果:
添加token参数请求 http://localhost:8769/api-feign-service/one?token=haha 结果:
本文源码下载地址:
https://github.com/laravelshao/spring-cloud-learning/tree/master/setion04-zuul
翟永超->Spring Cloud构建微服务架构:服务网关(基础)