前言:上篇尝试了进行在Eureka下进行服务注册和访问,这一篇我们尝试使用gateway配置所有的服务,进行中转访问,以及利用Feign进行服务客户端的互相调用
gateway网关配置
还是在父项目下新建一个Gateway项目,模拟网关,现在我们的父项目下就有六个项目了,一个Eureka服务端,一个网关,四个子服务
首先还是引入依赖,在gateway的pom.xml中加入
<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-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>2.0.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
其中包含了Eureka客户端依赖,gateway依赖,排除依赖(由于SpringCloud-Gateway是基于webflux的,它与spring boot mvc方式不兼容, 启动Gateway会报错,因此需排除spring-boot-starter-web),feign(调用器)依赖,hystrix依赖(熔断器)。
更新依赖后,在gateway的spring启动类中加入客户端和数据源注解
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
@EnableEurekaClient
然后编写服务层,服务层主要是对应几个子服务的feign接口
接口内容中加入feignclient注解,括号里的内容在访问时会作为接口标识,用以在网关内区别,第一个接口正常写
@FeignClient("SERVICE-ONE")
public interface ServiceOneFeign {
@RequestMapping("/ServiceOne")
String serviceOne();
}
第二个接口测试熔断器
熔断器的功能简而言之就是防止一个地方的故障造成它下游的服务和相关的服务受到波及,这种效应被称为 “雪崩效应 ”,熔断器Hystrix在工作时,会检测后台失败次数,如果超过一定数量,它就会实施断路,防止进一步的故障。
编写时首先在yml里加入如下内容,开启熔断器
然后编写一个熔断类,模拟异常情况
这里写一个返回字符内容的函数作为异常发生标志,然后在接口类里将异常类注入
@FeignClient(value = "SERVICE-TWO",fallbackFactory = ServiceTwoDown.class)
public interface ServiceTwoFeign {
//内部调用“SERVICE-TWO”微服务的“serviceOne”方法
@RequestMapping("/ServiceTwo/{id}")
String serviceTwo(@PathVariable int id);
}
最后不要忘了在启动类里加入注解开启熔断器,现在网关启动类是这样的
之后需要编写控制层,用以模拟网关配置服务地址,控制类内容:
@RestController
//restcontroller替代了重复的requestbody注解,用以返回字符串内容
@RequestMapping("/feignUniform")
//网关总访问地址
public class FeignUniformController {
//自动引入上一步编写的Feign接口
@Autowired
private ServiceOneFeign serviceOneFeign;
@Autowired
private ServiceTwoFeign serviceTwoFeign;
@Autowired
private ServiceThreeFeign serviceThreeFeign;
//内部调用“SERVICE-ONE”微服务的“serviceOne”方法
@RequestMapping("/ServiceOne")
public String serviceOne(){
return serviceOneFeign.serviceOne();
}
//内部调用“SERVICE-TWO”微服务的“serviceOne”方法
@RequestMapping("/ServiceTwo/{id}")
String serviceTwo(@PathVariable int id){
return serviceTwoFeign.serviceTwo(id);
}
//内部调用“SERVICE-THREE”微服务的“serviceThree_toOne”方法
@RequestMapping("/ServiceThree/one")
String serviceThreeToOne(){
return serviceThreeFeign.serviceThreeToOne();
}
//内部调用“SERVICE-THREE”微服务的“serviceThree_toTwo”方法
@RequestMapping("/ServiceThree/two")
String serviceThreeToTwo(){
return serviceThreeFeign.serviceThreeToTwo();
}
}
如注释里所写,自动注入几个服务接口后,就能调用其他子项目的方法
运行测试
运行几个项目的顺序是Eureka服务端,各个子服务,网关
查看8000地址
8089就是网关地址,访问Serviceone,功能正常
访问ServiceTwo,测试熔断器,功能正常
ServiceThree里调用了其他接口的内容,测试一下,功能正常
后续更新:网关的一些复杂配置
spring:
cloud:
gateway:
routes:
- id: shop-product # 路由的唯一标识
uri: lb://shop-product # 如果断言成功,将要转发去的地址
order: 0 # 优先级,越小优先级越高
predicates: # 断言,满足所有断言,才会进行转发
# 在这个时间之后才能进行访问
- After=2019-12-31T23:59:59.789+08:00[Asia/Shanghai]
这里的predicates比较有用,比如可以配置一个 /中间路径/ ,那么只有通过这个中间路径访问的才能通过,别的都会被拦截返回404
比如这样,只有hello/xxxx才是有效