微服务没有网关,会有下面的问题:
- 客户端请求多个微服务,增加了客户端复杂性,每个微服务都要做用户认证,限流等,避免和多个微服务打交道的复杂性。
- 有跨域问题,不在同一个域。
- 认证复杂,每个服务都要独立认证,服务要求的权限不一致。
- 难以重构。因为微服务被客户端调用着,重构难以实施。
网关是介于客户端(外部调用方比如app,h5)和微服务的中间层。
1. zuul
Zuul是Netflix开源的微服务网关,核心是一系列过滤器。这些过滤器可以完成以下功能。
- 是所有微服务入口,进行分发。
- 身份认证与安全。
- 监控。
- 动态路由。
- 压力测试。可以逐渐增加对后端服务的流量,进行测试。
- 负载均衡。默认集成了ribbon。
- 限流。
- 服务熔断。默认集成了hystrix。
1.1 基本使用
1. 1.1 安装
maven安装
<!-- eureka客户端 --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency><!-- zuul 默认集成了 ribbon和hystrix --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency>
gradle安装
//eureka客户端implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'//zuul 默认集成了 ribbon和hystriximplementation 'org.springframework.cloud:spring-cloud-starter-netflix-zuul'
1.1.2 配置
因为网关也是Eureka的客户端, 所以客户端该有的配置网关也该有。
server.port=8000#设置一个服务名, 这里的服务名很重要, 后面的ribbon需要用到.spring.application.name=ZUUL#设置服务注册中心的URLeureka.client.service-url.defaultZone=http://localhost:8080/eureka/#表示eureka client间隔多久去拉取服务注册信息,默认为30秒,对于网关,如果要迅速获取服务注册状态,可以缩小该值,比如5秒eureka.client.registry-fetch-interval-seconds=1
1.1.3 启动类增加注解@EnableZuulProxy
import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.netflix.eureka.EnableEurekaClient;import org.springframework.cloud.netflix.zuul.EnableZuulProxy;@SpringBootApplication@EnableEurekaClient@EnableZuulProxypublic class ZuulApplication {public static void main(String[] args) {SpringApplication.run(ZuulApplication.class, args);}}
1.1.4 测试
启动注册中心Eureka、用户中心user_center、订单中心order_center、网关zuul。 打开注册中心控制台
没有网关时访问用户中心接口地址: http://localhost:9000/collect/orders/v3/1、 正常返回
{“code”:”0000”,”msg”:”success”,”rersult”:[{“name”:”name1”,”id”:”100034”},{“name”:”name2”,”id”:”100035”},{“name”:”name3”,”id”:”100036”}]}
使用网关代理后访问用户中心地址:http://localhost:8000/user-center/collect/orders/v3/1、 正常返回
{“code”:”0000”,”msg”:”success”,”rersult”:[{“name”:”name1”,”id”:”100034”},{“name”:”name2”,”id”:”100035”},{“name”:”name3”,”id”:”100036”}]}
路径中的user-center是服务名。 默认转小写。
两个返回的结果一样,网关代理成功。
1.2 其他配置
zuul的负载均衡策略默认是轮询。可以修改某个服务的策略。
#修改user_center服务的负载均衡策略为随机, 其中user_center是服务名user_center.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule
调试的时候,看网关请求的地址,以及映射是否正确、网关请求有误时,可以增加下面配置排查错误。
management.endpoints.web.exposure.include=*management.endpoint.health.show-details=alwaysmanagement.endpoint.health.enabled=truemanagement.endpoint.routes.enabled=true
还有一些其他配置
#通过服务名配置(虚拟主机名)其中user_center是服务名zuul.routes.user_center=/xxoo/**#自定义映射规则,其中baidu是自定义path,符合“/baidu/**”的规则,全部转发到http://www.baodu.comzuul.routes.baidu.path=/baidu/**zuul.routes.baidu.url=http://www.baodu.com#忽略某个微服务zuul.ignored-services=user-provider#请求增加前缀zuul.prefix=/api/v1#转发是是否带上前缀, 默认是true。zuul.strip-prefix=false
