Spring Cloud学习笔记(服务网关Zuul)
Zuul概述
Zuul是一个服务网关组件,能够通过与Eureka进行整合,将自身注册到Eureka Server中,与Eureka、RibbonHystrix等进行整合,同时从Eureka中获得其他微服务架构的实例信息。
Zuul快速入门
(1)搭建Spring Boot项目eureka-server。
(2)创建服务提供者eureka-provider,在eureka-provider中创建一个包,创建一个HystrixController类
package com.itheima.eurekaprovider.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HystrixController {
@RequestMapping("hi")
public String hi(String id){
return "hi,访问成功"+id;
}
}
配置application.yml变量
server:
port: 7006 #指定该provider的端口号
spring:
application: #指定应用名称
name: eureka-provider
eureka:
client:
service-url:
defaultZone: http://localhost:7000/eureka/
instance:
hostname: localhost
(3)创建服务消费者eureka-consumer,配置全局变量application.yml
spring:
application:
name: eureka-consumer
server:
port: 8764
eureka:
client:
service-url:
defaultZone: http://localhost:7000/eureka
创建一个config包,新建配置类RestConfig
package com.itheima.eurekaconsumer.config;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class RestConfig {
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
创建一个service包,在service包下创建LocalItemService类
package com.itheima.eurekaconsumer.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.client.RestTemplate;
@Service
public class LocalItemService {
@Autowired
RestTemplate restTemplate;
public String hi(@RequestParam(value = "id")String id){
return restTemplate.getForObject("http://eureka-provider/hi?id="+id,String.class);
}
}
创建一个controller包,新建LocalItemController类。
package com.itheima.eurekaconsumer.controller;
import com.itheima.eurekaconsumer.service.LocalItemService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
public class LocalController {
@Autowired
LocalItemService localItemService;
@GetMapping("/hi")
public String hi(String id){
return localItemService.hi(id);
}
}
(4)创建网关服务,新建一个gateway-zuul的服务网关项目,添加Zuul、Test、Eureka Client、Web依赖,在起启动类上添加@EnableZuulProxy。配置全局配置文件。
server:
port: 8835
spring:
application:
name: gateway-zuul
eureka:
client:
service-url:
defaultZone: http://localhost:7000/eureka/
zuul:
routes:
eureka-consumer:
path: /eureka-consumer/**
(5)启动项目访问http://localhost:8835/eureka-consumer/hi?id=12
Zuul路由的映射规则配置
使用路由配置无须通过serviceId指定具体服务实例地址,只需要通过zuul.routes.<路由名>.serviceId的方法成对配置即可。示例代码:
zuul:
routes:
eureka-consumer:
path: /eureka-consumer/**
serviceId: eureka-consumer
对于上述面向服务的路由配置,除了使用path和serviceId映射的配置方式外,还可以简介的配置方式,
zuul:
routes:
eureka-consumer: /eureka-consumer/**
服务路由的默认规则:默认情况下Zuul会自动为Eureka服务注册中心的所有服务创建映射关系,进行路由这会导致一些不希望对外开放,当使用服务名称作为前缀是,实际上会匹配类似如下代码对应的默认路由配置。
zuul:
routes:
eureka-consumer:
path: /eureka-consumer/**
serviceId: eureka-consumer
如果不想使用默认的路由规则,可以在配置找那个加入下列内容,即可关闭所有默认的路由配置规则,对应代码如下:
zuul:
ignored-services: '*'
路径匹配:
在使用服务路由的配置方式时,需要为没个路由规则提供定义路由表达式, 也就是path参数。路由表达式采用了Ant风格定义。
Ant风格的路由表达式共有3种通配符
通配符 | 说明 |
---|---|
? | 匹配任意单个字符 |
* | 匹配任意数量的字符 |
** | 匹配任意数量的字符,支持多级目录 |
Zuul与Hystrix结合实现熔断
Zuul与Hystrix结合使用实现熔断功能时,需要完成FallbackProvider接口,该接口提供了两个方法:
(1)gatRoute()方法:用于指定提供回退功能的服务。
(2)fallbackResponse():用于执行回退操作的具体逻辑
在gateway-zuul中创建网关处理类MyFallbackProvider类,用于处理回退逻辑
package com.itheima.gatewayzuul.config;
import com.netflix.ribbon.proxy.annotation.Http;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
@Component
public class MyFallbackProvider implements FallbackProvider{
@Override
public String getRoute(){
return "eureka-consumer";
}
@Override
public ClientHttpResponse fallbackResponse(String route, Throwable cause) {
return new ClientHttpResponse() {
@Override
public HttpStatus getStatusCode() throws IOException {
return HttpStatus.OK;
}
@Override
public int getRawStatusCode() throws IOException {
return this.getStatusCode().value();
}
@Override
public String getStatusText() throws IOException {
return this.getStatusCode().getReasonPhrase();
}
@Override
public void close() {
}
@Override
public InputStream getBody() throws IOException {
return new ByteArrayInputStream("连接异常".getBytes());
}
@Override
public HttpHeaders getHeaders() {
HttpHeaders headers=new HttpHeaders();
MediaType mt=new MediaType("application","json");
Charset.forName("UTF-8");
headers.setContentType(mt);
return headers;
}
};
}
}
启动gateway-zuul和eureka-server,访问http://localhost:8835/eureka-consumer/hi?id=12
Zuul的过滤器
Zuul作为网关组件,将客户端请求路由到业务处理中,其中大部分功能都是通过实现的。Zuul定义了4中标准的过滤器类型。
pre:该过滤器会在请求被路由之前调用因此可利用这种过滤器实现身份验证、在集群中选择请求的微服务架构、记录调试信息等功能。
route:负责把请求转发到服务,在此构建原始请求, 并发送原始请求。
post:在route和error过滤器之后调用,可以响应消息中添加的标准HTTP Header、手机统计信息和指标以及将响应发送给客户端。
error:处理请求发送错误时被调用。