一.简介
微服务架构系统中会有多个服务提供者,如果客户端直接与特定微服务交互则对客户端非常不友好、需要知道业务的处理逻辑。
微服务网关统一代理内部微服务调用,客户端只需要和网关交互,有利与项目开发迭代,使用网关统一对客户端请求进行认证。
Zuul实现的是路由网关微服务,所有路由网关微服务都需要注册到注册中心。Zuul网关路由微服务代理客户端访问微服务,即消费端不直接访问微服务,而是访问路由网关微服务,这样可以在消费端与网关服务之间构建过滤、认证操作,而不必在每个微服务中进行认证。
二.Zuul路由网关模块
1.新建zuul网关微服务模块service-gateway
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
2.编写application.yml配置文件
server:
port: 8050
spring:
application:
name: service-gateway
eureka:
client:
service-url:
defaultZone: http://admin:admin@localhost:8010/eureka
3.编写路由网关启动类
package com.vincent;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
@SpringBootApplication
@EnableZuulProxy
public class GatewayApp {
public static void main(String[] args) {
SpringApplication.run(GatewayApp.class,args);
}
}
@EnableZuulProxy 申明是一个zuul代理,该代理使用Ribbon定位注册到Eureka中的微服务
4.zuul默认会代理所有注册到Eureka中的服务,路由规则为http://zuul_host:zuul_port/微服务在Eureka上的serviceId/** 会被转发到serviceId对应的微服务。
访问http://localhost:8050/service-user/user/9
5.负载均衡
8021端口启动service-user
java -jar service-user\target\service-user-0.0.1-SNAPSHOT.jar --server.port=8021
多次访问http://localhost:8050/service-user/user/9
Zuul 也整合了Hystrix 熔断处理机制,对于内部一些耗时服务可能会存在调用超时。可通过如下配置超时时长,单位为毫秒且注意单词的大小写。但是一个服务长时间没有完成也将导致资源得不到释放。
ribbon.ConnectTimeout=xxx
ribbon.ReadTimeout=xxx
ribbon:
ConnectTimeout: 6000
ReadTimeout: 6000
三.Zuul路由配置
1.Zuul默认通过微服务名称进行代理访问,zuul 可以自定义路由访问规则,即给注册中心的微服务名称取一个别名
server:
port: 8050
spring:
application:
name: service-gateway
eureka:
client:
service-url:
defaultZone: http://admin:admin@localhost:8010/eureka
zuul:
#忽略所有的微服务
ignored-services: "*"
routes:
#自定义路由服务映射
service-user:
path: /proxy-user/**
service-id: service-user
2.访问http://localhost:8050/service-user/user/9时将不会有信息,访问http://localhost:8050/proxy-user/user/9
四.Zuul聚合微服务
更多的情况是外部请求发送到Zuul网关代理,Zuul再访问内部相关微服务并组织好数据后给外部请求,这样一个外部请求只需发送一次请求,网关代理访问局域网中的微服务。简化客户端侧开发、减小网络耗时。
1.service-gateway 中增加openfeign 依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2.application.yml配置忽略所有路由—服务映射
server:
port: 8050
spring:
application:
name: service-gateway
eureka:
client:
service-url:
defaultZone: http://admin:admin@localhost:8010/eureka
zuul:
#忽略所有的微服务
ignored-services: "*"
3.定义访问内部微服务的FeignClient,IUserFeign.java
package com.vincent.feign;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@FeignClient("service-user")
public interface IUserFeign {
@GetMapping("/user/{id}")
Object userById(@PathVariable("id") Integer id);
}
4.新建业务处理逻辑类,UserController.java
package com.vincent.controller;
import com.vincent.feign.IUserFeign;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
@RestController
public class UserController {
@Autowired
private IUserFeign userFeign;
@GetMapping("/user/{id}")
public Object getUser(@PathVariable("id") Integer id){
Map<String,Object> rst = new HashMap<>();
rst.putAll((Map<String,Object>)userFeign.userById(id));
rst.put("zuul","网关代理处理");
return rst;
}
}
5.访问http://localhost:8050/user/9
网关代理作为用户访问请求的入口,在网关代理上可以方便处理认证,业务处理逻辑。