携手创作,共同成长!这是我参与「日新计划 8 月更文挑战」的第11天,点击查看详情

介绍

zuul 是springcloud微服务的网关组件,用于构建边界服务,致力于动态路由、监控、过滤、弹性伸缩和安全。 zuul在微服务中起着至关重要的作用,它的作用主要体现在以下6个方面:

  1. Zuul 、 Ribbon 以及 Eureka 相结合,可以实现智能路由和负载均衡的功能, Zuul 能够将请求流量按某种策略分发到集群状态的多个服务实例。
  2. 网关将所有服务的 API 接口统一聚合,并统一对外暴露。外界系统调用 API 接口时,都是由网关对外暴露的 API 接口,外界系统不需要知道微服务系统中各服务相互调用的复杂性。微服务系统也保护了其内部微服务单元的 API 接口,防止其被外界直接调用,导致服务的敏感信息对外暴露。
  3. 网关服务可以做用户身份认证和权限认证,防止非法请求操作 API 接口,对服务器起到保护作用。
  4. 网关可以实现监控功能,实时日志输出,对请求进行记录。
  5. 网关可以用来实现流量监控,在高流量的情况下,对服务进行降级。
  6. 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服务的对外接口的访问路

springcloud 入门(6) 网关 zuul

修改为自定义的路由访问地址 zuul.routes后面是服务集群名,后面是自定义的服务集群名

zuul.routes.providers=providers-proxy/**

访问http://localhost:8501/providers-proxy/provider/getName/yy

springcloud 入门(6) 网关 zuul

现在访问http://localhost:8501/providers/provider/getName/yy 还是能访问到providers服务的,不让看到真实的路由,可以屏蔽路由访问前缀

# 忽略集群名,屏蔽服务对外访问的路由前缀
zuul.ignored-services=providers

再次重启访问 http://localhost:8501/providers/provider/getName/yy

springcloud 入门(6) 网关 zuul
每个屏蔽太麻烦,可以屏蔽所有的

# *是屏蔽所有的服务前缀
zuul.ignored-services=*

设置统一前缀,重启访问http://localhost:8501/zuul-proxy/providers-proxy/provider/getName/yy

# 设置公共前缀
zuul.prefix=/zuul-proxy

结果:

springcloud 入门(6) 网关 zuul

通过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 ,出现下面结果,降级处理成功

springcloud 入门(6) 网关 zuul
至此zuul的简单使用就完成了

上篇:springcloud多模块项目一步一步搭建(5)Hystrix Dashboard &Turbine

GitHub地址: github.com/ArronSun/mi…

参考书籍:

《重新定义springcloud实战》
《深入理解Spring cloud与微服务构建》