7、Spring Cloud Feign负载与容错

    《SpringBoot整合ribbon项目实战》一文中介绍了spring cloud的负载均衡和容错的入门配置,在实际开发中微服务的负载均衡和容错基本同时出现而且是每个服务不可缺少的一部分。在使用ribbon时,通常会使用resttemplate实现对http请求的封装,形成了模板化的调用方法。spring cloud feign在此基础上做了进一步的封装,Feign是一种声明式、模板化的HTTP客户端。在Spring Cloud中使用Feign, 我们可以做到使用HTTP请求远程服务时能与调用本地方法一样的编码体验,开发者完全感知不到这是远程方法,更感知不到这是个HTTP请求。Feign包含了Ribbon和Hystrix,它既能负载也能容错。


@Autowired
// 远程服务
private AdvertGropRemoteService service;
public AdvertGroupVO foo(Integer groupId) {
    // 通过HTTP调用远程服务
    return service.findByGroupId(groupId);
}

 接下来,我们在《SpringBoot整合ribbon项目实战》基础上搭建一个新的服务消费者customer_feign,其余服务配置不变,具体步骤如下:

(1)新建项目

在原有的项目不变,在spring-ribbon-eureka项目下创建子项目ribbon_customer_feign,项目类型为jar

(2)修改pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <!-- 项目信息 -->
  <modelVersion>4.0.0</modelVersion>
  <artifactId>ribbon_customer_feign</artifactId>
  <name>spring cloud feign</name>
  <description>spring cloud feign</description>
 
  <!-- 父项目 -->
  <parent>
    <groupId>com.easystudy</groupId>
    <artifactId>spring-ribbon-eureka</artifactId>
    <version>0.0.1-SNAPSHOT</version>
  </parent>
 
  <!-- 项目强制依赖 -->
  <dependencies>
     <!-- spring cloud 客户注册 -->
     <dependency>
           <groupId>org.springframework.cloud</groupId>
          <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
     </dependency>
     <!-- spring cloud feign -->
     <dependency>
         <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-feign</artifactId>
        <version>1.4.4.RELEASE</version>
     </dependency>
  </dependencies>
</project>

(3)添加application.yml配置文件(在src/main/resources下)

# 多环境通用部分[各个环境可以覆盖通用字段]
spring: 
  application:
    # 通用名字,其他环境可以覆盖:为你的应用起个名字,该名字将注册到eureka注册中心
    name: ribbon-consumer-feign
server: 
  # 服务提供监听端口[eureka客户端],注意改端口不能与本机服务器端口冲突
  port: 8765
eureka:
  client:
    # 是否将eureka自身作为应用注册到eureka注册中心,默认为true
    registerWithEureka: true
    service-url:
      # 这里可以填写所有的eureka服务器地址并以','分离,当前面不能注册时候,自动选择后面的进行注册,排除单点

注意:修改端口为8765,不要和本机的其他tomcat端口冲突

(4)添加对外的controller,暴露"/hi"接口

package com.easystudy.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.easystudy.service.HelloService;

@RestController
public class CustomerController {
    
    @Autowired
    HelloService service;
    
    /**
     * 这里可以像调用本地普通方法一样调用远程过程
     * Feign给你的就是不一般的体验
     * @return
     */
    @RequestMapping("/hi")
    public String customer(){
        return service.hello();
    }
}

(5)添加HelloService的实现

package com.easystudy.service;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.easystudy.service.impl.HelloServiceImpl;

/**
 * (1)
 * @FeignClient注解定义了该接口是一个Feign客户端,name指定了注册到Eureka上的服务名,fallback是服务降级后的接口实现类
 * 为了让Feign知道在调用方法时应该向哪个地址发请求以及请求需要带哪些参数,我们需要定义一个接口
 * 用于通知Feign组件对该接口进行代理(不需要编写接口实现),test-service为代理的具体服务
 * 这里的test-service表示service_a和service_b注册到eureka的服务名
 * (2)
 * Spring Cloud Feign 的容错,HystrixCommand定义被封装起来,没有办法通过
 * @HystrixCommand注解的fallback,指定服务降级(错误处理)方法,Spring Cloud Feign
 * 提供也更为简洁明了的方法实现服务降级处理,只需要编写一个feign接口的具体实现类即可并fallback
 * 指定对应降级处理类,Feign的模板化就体现在这里,通过Feign, 我们能把HTTP远程调用对开发者完全透明,
 * 得到与调用本地方法一致的编码体验
 * (3)
 * Spring Cloud应用在启动时,Feign会扫描标有@FeignClient注解的接口,生成代理,并注册到Spring容器中
 * 生成代理时Feign会为每个接口方法创建一个RequetTemplate对象,该对象封装了HTTP请求需要的全部信息,
 * 请求参数名、请求方法等信息,如果是在用Spring Cloud Netflix搭建微服务,那么Feign无疑是最佳选择
 */
@FeignClient(value="test-service", fallback=HelloServiceImpl.class)		
public interface HelloService {
	/**
	 * 对应具体服务中的接口地址,这里表是service-a和service-b
	 * 对外提供的具体的接口服务,如com.easystudy.controller.ServiceAController的testA暴露的对外接口"/hello"
	 * @return
	 */
	@RequestMapping(value = "/hello", method=RequestMethod.GET)
	public String hello();
	
	@RequestMapping(value="/hello2", method=RequestMethod.HEAD)
	String hello(@RequestHeader("name") String name,
			     @RequestHeader("password") String password);
}

(6)添加HelloService降级处理HelloServiceImpl

package com.easystudy.service.impl;
import com.easystudy.service.HelloService;
/**
 * Feign容错降级处理类,它并不是Spring的Service类,
 * Feign会扫描标有@FeignClient注解的接口,生成代理
 * HelloServiceImpl仅仅是被指定的降级处理类
 * @author Administrator
 *
 */
public class HelloServiceImpl implements HelloService{
     @Override
     public String hello() {         
           return "请求错误";
     }

    /**
	 * 发现这里的入参里我故意去掉了@RequestParam、@RequestBody、@RequestHeader注解,
	 * 因为这几个注解本质上的意义就在于Feign在做微服务调用的时候对http传递参数用的,
	 * 但服务降级根本不会做http请求了,所以此处可以省略
	 */
	@Override
	public String hello(String name, String password) {
		// TODO Auto-generated method stub
		return null;
	}
     
}

(7)添加启动入口RibbonCustomerFeignApp

package com.easystudy;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
@EnableDiscoveryClient  // 通过该注解,实现服务发现,注册-spring-cloud-commons,支持consul、zookeeper,eureka
//@EnableEurekaClient   // 支持eureka,EnableEurekaClient也使用EnableDiscoveryClient注解
@EnableFeignClients     // 开启spring cloud feign的支持,启动器一定要加@EnableFeignClients,代表进行Feig
public class RibbonCustomerFeignApp {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        SpringApplication.run(RibbonCustomerFeignApp.class, args);
    }

}

(8)测试

启动eureka_register_service注册服务,启动ribbon_service_a和ribbon_service_b都提供test-service的hello服务;启动客户端ribbon_customer_feign

访问:http://localhost:8765/hi

再次访问:

可以看到feign轮训负载到service_a和service_b提供hello服务;

猜你喜欢

转载自blog.csdn.net/lixiang987654321/article/details/81544226
今日推荐