携手创作,共同成长!这是我参与「日新计划 8 月更文挑战」的第11天,点击查看详情
介绍
zuul 是springcloud微服务的网关组件,用于构建边界服务,致力于动态路由、监控、过滤、弹性伸缩和安全。 zuul在微服务中起着至关重要的作用,它的作用主要体现在以下6个方面:
- Zuul 、 Ribbon 以及 Eureka 相结合,可以实现智能路由和负载均衡的功能, Zuul 能够将请求流量按某种策略分发到集群状态的多个服务实例。
- 网关将所有服务的 API 接口统一聚合,并统一对外暴露。外界系统调用 API 接口时,都是由网关对外暴露的 API 接口,外界系统不需要知道微服务系统中各服务相互调用的复杂性。微服务系统也保护了其内部微服务单元的 API 接口,防止其被外界直接调用,导致服务的敏感信息对外暴露。
- 网关服务可以做用户身份认证和权限认证,防止非法请求操作 API 接口,对服务器起到保护作用。
- 网关可以实现监控功能,实时日志输出,对请求进行记录。
- 网关可以用来实现流量监控,在高流量的情况下,对服务进行降级。
- API 接口从内部服务分离出来,方便做测试
使用
新建一个zuul-gateway 项目,依赖如下:
<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.properties配置文件
server.port=8501
spring.application.name=zuul-gateway
# 此客户端是否应该从eureka server 获取eureka注册信息
eureka.client.register-with-eureka=false
# 和eureka服务器通讯的URL
eureka.client.service-url.defaultZone=http://localhost:8001/eureka
#eureka.instance.prefer-ip-address=true
启动类加注解EnableZuulProxy
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
@EnableZuulProxy
@SpringBootApplication
public class ZuulApplication {
public static void main(String[] args) {
SpringApplication.run(ZuulApplication.class, args);
}
}
启动,通过Zuul代理访问http://localhost:8501/providers/provider/getName/yy providers是我的providers服务的spring.application.name,providers后面的是providers服务的对外接口的访问路
修改为自定义的路由访问地址 zuul.routes后面是服务集群名,后面是自定义的服务集群名
zuul.routes.providers=providers-proxy/**
访问http://localhost:8501/providers-proxy/provider/getName/yy
现在访问http://localhost:8501/providers/provider/getName/yy 还是能访问到providers服务的,不让看到真实的路由,可以屏蔽路由访问前缀
# 忽略集群名,屏蔽服务对外访问的路由前缀
zuul.ignored-services=providers
再次重启访问 http://localhost:8501/providers/provider/getName/yy 每个屏蔽太麻烦,可以屏蔽所有的
# *是屏蔽所有的服务前缀
zuul.ignored-services=*
设置统一前缀,重启访问http://localhost:8501/zuul-proxy/providers-proxy/provider/getName/yy
# 设置公共前缀
zuul.prefix=/zuul-proxy
结果:
通过feign 访问zuul
之前consumer是通过feign访问providers的,现在zuul进行了代理再次访问就访问不到了,所以要修改consumer服务的接口,这样consumer的controller就不用修改了
//@FeignClient(name = "PROVIDER" , path = "provider" , fallback = ProviderServiceFallback.class)
@FeignClient(name = "ZUUL-GATEWAY" , path = "zuul-proxy/providers-proxy/provider" , fallback = ProviderServiceFallback.class)
//@FeignClient(name = "PROVIDER" , path = "provider" , fallbackFactory = ProviderFallbackFactory.class)
public interface ProviderService {
@GetMapping("hello")
public String test();
@GetMapping("getName/{name}")
public String testHystrix(@PathVariable String name);
}
zuul 熔断
虽然其他服务做了降级处理,zuul作为代理方也应该做降级处理 实现FallbackProvider接口,做一个简单的降级处理
@Component
public class ProviderFallback implements FallbackProvider {
@Override
public String getRoute() {
return "*";
}
@Override
public ClientHttpResponse fallbackResponse(String route, Throwable cause) {
final HttpStatus badRequest = HttpStatus.BAD_REQUEST;
return new ClientHttpResponse() {
@Override
public HttpStatus getStatusCode() throws IOException {
return badRequest;
}
@Override
public int getRawStatusCode() throws IOException {
return badRequest.value();
}
@Override
public String getStatusText() throws IOException {
return badRequest.getReasonPhrase();
}
@Override
public void close() {
}
@Override
public InputStream getBody() throws IOException {
final String s = route + "服务不可用";
return new ByteArrayInputStream(s.getBytes());
}
@Override
public HttpHeaders getHeaders() {
HttpHeaders headers = new HttpHeaders();
headers.set("Content-Type", "text/html; charset=UTF-8");
return headers;
}
};
}
}
停止服务提供者,访问http://localhost:8501/zuul-proxy/providers-proxy/provider/getName/yy ,出现下面结果,降级处理成功 至此zuul的简单使用就完成了
上篇:springcloud多模块项目一步一步搭建(5)Hystrix Dashboard &Turbine
GitHub地址: github.com/ArronSun/mi…
参考书籍:
《重新定义springcloud实战》
《深入理解Spring cloud与微服务构建》