Netflix SpringCloud-feign & zuul

本篇继续简述Netflix版SpringCloud之feign & zuul。

一些基本组件概念理解:

feign: feign默认集成了ribbon, 也可以实现负载均衡

zuul: 路由网关控制服务器

下面简单演示下以上组件的用法。

准备工作:启动eureka服务注册中心(参见 Netflix SpringCloud-Eureka

1. feign实现负载均衡

1.1 pom

<dependency>  <groupId>org.springframework.cloud</groupId>  <artifactId>spring-cloud-starter-eureka</artifactId></dependency><dependency>  <groupId>org.springframework.cloud</groupId>  <artifactId>spring-cloud-starter-openfeign</artifactId></dependency><!--Hystrix Dashboard (断路器仪表盘)--><!--访问http://localhost:9001/hystrix    在请求地址栏输入:http://localhost:9001/hystrix.stream,    点击Monitor Stream可以监控service层的方法--><dependency>  <groupId>org.springframework.boot</groupId>  <artifactId>spring-boot-starter-actuator</artifactId></dependency><dependency>  <groupId>org.springframework.cloud</groupId>  <artifactId>spring-cloud-starter-netflix-hystrix</artifactId></dependency><dependency>  <groupId>org.springframework.cloud</groupId>  <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId></dependency><dependency>  <groupId>org.springframework.cloud</groupId>  <artifactId>spring-cloud-starter-zipkin</artifactId></dependency>

1.2 yml

eureka:  client:    serviceUrl:      defaultZone: http://peer1:8888/eureka/,http://peer2:8889/eureka/server:  port: 9001spring:  application:    name: routing-feign  zipkin:    base-url: http://localhost:9100## Feign是自带断路器的,在D版本的Spring Cloud中,它没有默认打开。需要在配置文件中配置打开它feign:  hystrix:    enabled: true

1.3 application

import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;import org.springframework.cloud.client.discovery.EnableDiscoveryClient;import org.springframework.cloud.netflix.feign.EnableFeignClients;import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;@SpringBootApplication@EnableDiscoveryClient@EnableFeignClients@EnableHystrixDashboard // 断路仪表盘@EnableCircuitBreaker // 开启断路器public class RoutingFeignApplication {  public static void main(String[] args) {    SpringApplication.run(RoutingFeignApplication.class, args);  }}

1.4 controller & service

import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.bind.annotation.RestController;/** * 在controller层,对外暴露一个”/hello”的API接口, * 通过定义的Feign客户端HelloService来消费服务 */@RestControllerpublic class HelloController {    @Autowired    HelloService helloService;    @RequestMapping(value = "/hello", method = RequestMethod.GET)    public String sayHi(@RequestParam String name){        return helloService.sayHelloFromClientOne(name);    }}
import org.springframework.cloud.netflix.feign.FeignClient;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.RequestParam;/** * 定义一个feign接口,通过@ FeignClient(“服务名”),来指定调用哪个服务 * fallback 指定服务断路处理   */@FeignClient(value = "eureka-client", fallback = HelloServiceHystrixImpl.class)public interface HelloService {    @RequestMapping(value = "/hello", method = RequestMethod.GET)    String sayHelloFromClientOne(@RequestParam(value = "name") String name);}

feign hystrix 断路处理:

import org.springframework.stereotype.Component;@Componentpublic class HelloServiceHystrixImpl implements HelloService {    @Override    public String sayHelloFromClientOne(String name) {        return "sorry " + name;    }}

1.5 feign负载均衡演示

(1)服务注册中心eureka-server集群,端口为8888,8889

eureka-client工程启动两个实例,端口分别为8887,8886

启动server-zipkin,端口为9100,

启动routing-feign, 端口为9001

(2)访问routing-feign服务:

        http://localhost:9001/hello?name=bruce

       反复刷新访问以上地址,可以看到会交替请求eureka-client两个实例,

      即通过feign, 实现了服务的负载均衡。然后再看下zipkin服务链路:

      

   

feign hystrix 断路仪表盘监控:

调取服务后,监控断路仪表盘:

当把eureka-client所有节点的服务都停掉后,再次请求,发现已有断路处理响应:

2. zuul路由控制

2.1 pom

<dependency>  <groupId>org.springframework.cloud</groupId>  <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId></dependency><dependency>  <groupId>org.springframework.cloud</groupId>  <artifactId>spring-cloud-starter-netflix-zuul</artifactId></dependency>

2.2 yml

eureka:  client:    serviceUrl:      defaultZone: http://peer1:8888/eureka/,http://peer2:8889/eureka/server:  port: 9002spring:  application:    name: routing-zuulzuul:  routes:    api-a:      path: /api-ribbon/**      serviceId: routing-ribbon    api-b:      path: /api-feign/**      serviceId: routing-feign

2.3 application

import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.client.discovery.EnableDiscoveryClient;import org.springframework.cloud.netflix.zuul.EnableZuulProxy;/** * Zuul是路由控制服务器,feign(ribbon)可以实现负载均衡 * 访问 http://localhost:9002/api-feign/hello?name=bruce * 根据yml中配置的zuul路由规则, * 以 /api-ribbon/ 开头的请求都转发给routing-ribbon服务 * 以 /api-feign/ 开头的请求都转发给routing-feign服务 */@SpringBootApplication@EnableDiscoveryClient@EnableZuulProxypublic class RoutingZuulApplication {  public static void main(String[] args) {    SpringApplication.run(RoutingZuulApplication.class, args);  }}

2.4 zuul filter

import com.netflix.zuul.ZuulFilter;import com.netflix.zuul.context.RequestContext;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.stereotype.Component;import javax.servlet.http.HttpServletRequest;/** * http://localhost:9002/api-ribbon/hello?name=bruce * token is empty * * http://localhost:9002/api-ribbon/hello?name=bruce&token=11 * hello bruce,I am from port:8887*/@Componentpublic class MyFilter extends ZuulFilter {    private static Logger log = LoggerFactory.getLogger(MyFilter.class);    /**     * filterType:返回一个字符串代表过滤器的类型,在zuul中定义了四种不同生命周期的过滤器类型,具体如下:     * pre:路由之前     * routing:路由之时     * post:路由之后     * error:发送错误调用     * filterOrder:过滤的顺序     * shouldFilter:这里可以写逻辑判断,是否要过滤,本文true,永远过滤。     * run:过滤器的具体逻辑。可用很复杂,包括查sql,nosql去判断该请求到底有没有权限访问。     * @return     */    @Override    public String filterType() {        return "pre";    }    @Override    public int filterOrder() {        return 0;    }    @Override    public boolean shouldFilter() {        return true;    }    @Override    public Object run() {        RequestContext ctx = RequestContext.getCurrentContext();        HttpServletRequest request = ctx.getRequest();        log.info(String.format("%s >>> %s", request.getMethod(), request.getRequestURL().toString()));        Object accessToken = request.getParameter("token");        if(accessToken == null) {            log.warn("token is empty");            ctx.setSendZuulResponse(false);            ctx.setResponseStatusCode(401);            try {                ctx.getResponse().getWriter().write("token is empty");            }catch (Exception e){                log.error("response writer error");            }            return null;        }        log.info("ok");        return null;    }}

2.5 zuul 路由控制演示

(1)服务注册中心eureka-server集群,端口为8888,8889

eureka-client工程启动两个实例,端口分别为8887,8886

启动routing-ribbon, 端口为9000,

启动routing-feign, 端口为9001,

启动routing-zuul,端口为9002,

启动server-zipkin,端口为9100

(2)请求访问:http://localhost:9002/api-feign/hello?name=bruce

由于未提供token,会被zuul filter拦截

(3)加上请求令牌token后,多次刷新请求,负载均衡​:

(4)请求地址中,api-feign 换作 api-ribbon后,

请求访问:http://localhost:9002/api-feign/hello?name=bruce

多次刷新请求,负载均衡​:

由上测试,可见zuul实现了简单的路由控制​转发功能。

以上简单演示集成了ribbon的feign,实现负载均衡的效果,以及feign整合了hystrix的断路处理机制。此外还有zuul的路由网关控制功能。

netflix下的springcloud, 已不再维护,目前只抽取了一些比较典型的功能加以温习,其他的不再赘述。后面抽空会简述下SpringCloud Alibaba。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值