网关在微服务系统中起到一个门户的作用,主要作用如下:
- 服务路由
- 鉴权
- 服务熔断
- 流控
- 灰度发布等
常用的网关有Zuul、Gateway、OpenResty + Lua、Kong、ApiSIX等等。本文以Zuul为例,虽然其性能可能表现的不是很好(Zuul 1.X),但是对于掌握网关的一些基础知识还是很有帮助的。
Spring Boot版本:2.0.9.RELEASE
Spring Cloud Netflix版本:Finchley.SR4(目前处于不维护状态)
1.父pom依赖如下
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>8</java.version>
<spring.cloud.version>Finchley.SR4</spring.cloud.version>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.9.RELEASE</version>
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring.cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
2. 注册中心
这里以Eureka为例,注册中心服务依赖如下:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
application.yml配置信息如下:
server:
port: 8000
spring:
application:
name: eureka-server
eureka:
client:
registerWithEureka: false
fetchRegistry: false
代码启动类如下:
@SpringBootApplication
@EnableEurekaServer
public class EurekaServer {
public static void main(String[] args) {
SpringApplication.run(EurekaServer.class, args);
}
}
3.服务提供方
依赖如下:
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
application.yml配置文件内容如下:
server:
port: 9000
spring:
application:
name: client
eureka:
client:
service-url:
defaultZone: http://localhost:8000/eureka
instance:
prefer-ip-address: true
启动类如下:
@SpringBootApplication
@EnableDiscoveryClient
public class ClientApp {
public static void main(String[] args) {
SpringApplication.run(ClientApp.class, args);
}
}
提供一个相加的处理类
@RestController
@RequestMapping("calc")
public class CalcController {
@Value("${server.port}")
private int serverPort;
@GetMapping("add")
public Integer add(@RequestParam("a") Integer a, @RequestParam("b") Integer b) {
System.err.println("From Port: " + serverPort);
return a + b;
}
}
4. Zuul网关
依赖如下:
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
</dependencies>
application.yml配置文件内容如下:
server:
port: 8100
spring:
application:
name: Zuul Server
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8000/eureka
instance:
prefer-ip-address: true
zuul:
routes:
client-service:
path: /client/**
serviceId: client
项目启动类如下:
@SpringBootApplication
//@EnableEurekaClient
@EnableDiscoveryClient
@EnableZuulProxy
public class ZuulServer {
public static void main(String[] args) {
SpringApplication.run(ZuulServer.class, args);
}
}
分别启动Eureka注册中心、Zuul网关、Client服务,
直接通过Client服务的IP端口,http://localhost:9000/calc/add?a=1&b=5能正常访问;
通过访问网关:http://localhost:8100/client/calc/add?a=1&b=5,也能正常访问,说明网关路由到了Client服务上。
通过设置Client服务端口的形式,新增一个服务提供方:
启动成功后,Client服务将会有两个服务实例,如下:
访问上述网关的地址,可以看到Client服务端控制台会交替输出对应的端口信息,说明Zuul网关在路由服务时也使用了负载均衡。
整体服务架构如下: