微服务没有网关,会有下面的问题:

  1. 客户端请求多个微服务,增加了客户端复杂性,每个微服务都要做用户认证,限流等,避免和多个微服务打交道的复杂性。
  2. 有跨域问题,不在同一个域。
  3. 认证复杂,每个服务都要独立认证,服务要求的权限不一致。
  4. 难以重构。因为微服务被客户端调用着,重构难以实施。

网关是介于客户端(外部调用方比如app,h5)和微服务的中间层。

1. zuul

Zuul是Netflix开源的微服务网关,核心是一系列过滤器。这些过滤器可以完成以下功能。

  1. 是所有微服务入口,进行分发。
  2. 身份认证与安全。
  3. 监控。
  4. 动态路由。
  5. 压力测试。可以逐渐增加对后端服务的流量,进行测试。
  6. 负载均衡。默认集成了ribbon。
  7. 限流。
  8. 服务熔断。默认集成了hystrix。

1.1 基本使用

1. 1.1 安装

maven安装

  1. <!-- eureka客户端 -->
  2. <dependency>
  3. <groupId>org.springframework.cloud</groupId>
  4. <artifactId>spring-cloud-starter-gateway</artifactId>
  5. </dependency>
  6. <!-- zuul 默认集成了 ribbon和hystrix -->
  7. <dependency>
  8. <groupId>org.springframework.cloud</groupId>
  9. <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
  10. </dependency>

gradle安装

  1. //eureka客户端
  2. implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
  3. //zuul 默认集成了 ribbon和hystrix
  4. implementation 'org.springframework.cloud:spring-cloud-starter-netflix-zuul'

1.1.2 配置

因为网关也是Eureka的客户端, 所以客户端该有的配置网关也该有。

  1. server.port=8000
  2. #设置一个服务名, 这里的服务名很重要, 后面的ribbon需要用到.
  3. spring.application.name=ZUUL
  4. #设置服务注册中心的URL
  5. eureka.client.service-url.defaultZone=http://localhost:8080/eureka/
  6. #表示eureka client间隔多久去拉取服务注册信息,默认为30秒,对于网关,如果要迅速获取服务注册状态,可以缩小该值,比如5秒
  7. eureka.client.registry-fetch-interval-seconds=1

1.1.3 启动类增加注解@EnableZuulProxy

  1. import org.springframework.boot.SpringApplication;
  2. import org.springframework.boot.autoconfigure.SpringBootApplication;
  3. import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
  4. import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
  5. @SpringBootApplication
  6. @EnableEurekaClient
  7. @EnableZuulProxy
  8. public class ZuulApplication {
  9. public static void main(String[] args) {
  10. SpringApplication.run(ZuulApplication.class, args);
  11. }
  12. }

1.1.4 测试

启动注册中心Eureka、用户中心user_center、订单中心order_center、网关zuul。 打开注册中心控制台
image.png

没有网关时访问用户中心接口地址: 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的负载均衡策略默认是轮询。可以修改某个服务的策略。

  1. #修改user_center服务的负载均衡策略为随机, 其中user_center是服务名
  2. user_center.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule

调试的时候,看网关请求的地址,以及映射是否正确、网关请求有误时,可以增加下面配置排查错误。

  1. management.endpoints.web.exposure.include=*
  2. management.endpoint.health.show-details=always
  3. management.endpoint.health.enabled=true
  4. management.endpoint.routes.enabled=true

还有一些其他配置

  1. #通过服务名配置(虚拟主机名)其中user_center是服务名
  2. zuul.routes.user_center=/xxoo/**
  3. #自定义映射规则,其中baidu是自定义path,符合“/baidu/**”的规则,全部转发到http://www.baodu.com
  4. zuul.routes.baidu.path=/baidu/**
  5. zuul.routes.baidu.url=http://www.baodu.com
  6. #忽略某个微服务
  7. zuul.ignored-services=user-provider
  8. #请求增加前缀
  9. zuul.prefix=/api/v1
  10. #转发是是否带上前缀, 默认是true。
  11. zuul.strip-prefix=false

2. getway

3. kong