微服务没有网关,会有下面的问题:
- 客户端请求多个微服务,增加了客户端复杂性,每个微服务都要做用户认证,限流等,避免和多个微服务打交道的复杂性。
- 有跨域问题,不在同一个域。
- 认证复杂,每个服务都要独立认证,服务要求的权限不一致。
- 难以重构。因为微服务被客户端调用着,重构难以实施。
网关是介于客户端(外部调用方比如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和hystrix
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-zuul'
1.1.2 配置
因为网关也是Eureka的客户端, 所以客户端该有的配置网关也该有。
server.port=8000
#设置一个服务名, 这里的服务名很重要, 后面的ribbon需要用到.
spring.application.name=ZUUL
#设置服务注册中心的URL
eureka.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
@EnableZuulProxy
public 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=always
management.endpoint.health.enabled=true
management.endpoint.routes.enabled=true
还有一些其他配置
#通过服务名配置(虚拟主机名)其中user_center是服务名
zuul.routes.user_center=/xxoo/**
#自定义映射规则,其中baidu是自定义path,符合“/baidu/**”的规则,全部转发到http://www.baodu.com
zuul.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