Feign讲解与应用(文末送书)

本文涉及的产品
传统型负载均衡 CLB,每月750个小时 15LCU
网络型负载均衡 NLB,每月750个小时 15LCU
应用型负载均衡 ALB,每月750个小时 15LCU
简介: Feign讲解与应用(文末送书)

Feign[feɪn]

什么是Feign?

Feign 的英文表意为“假装,伪装,变形”, 是一个http请求调用的轻量级框架,可以以Java接口注解的方式调用Http请求,而不用像Java中通过封装HTTP请求报文的方式直接调用。Feign通过处理注解,将请求模板化,当实际调用的时候,传入参数,根据参数再应用到请求上,进而转化成真正的请求,这种请求相对而言比较直观。Feign被广泛应用在Spring Cloud 的解决方案中,是学习基于Spring Cloud 微服务架构不可或缺的重要组件。它让微服务之间调用变得更简单了, 类似controller调用service. SpringCloud集成了Ribbon Eureka, 可以在使用Feign时提供 负载均衡 的客户端

只需要一个接口, 然后添加注解即可

feign主要是社区, 大家都习惯面向接口编程. 这是很多开发人员的规范. 调用微服务有两种方法

  • 微服务名字(ribbon)
  • 接口和注解(feign)

Feign能干什么

  • Feign旨在编写Java Http客户端变得更容易
  • 前面使用Ribbon + RestTemplate时, 利用RestTemplate对Http请求的封装处理, 形成了一套模块化用法. 但是实际开发中, 由于服务的依赖的调用可能不止一处, 往往一个接口会被多处调用, 所以都会针对每一个服务自行封装一些客户端类来包装这些依赖服务的调用. 所以Feign在此基础上做了进一步封装, 由他来帮助我们定义和实现依赖服务接口的定义,  **在Feign的实现下, 我们只需要创建一个接口并使用注解的方式来配置它(类似于以前Dao接口上标注@Mapper注解, 现在是一个微服务接口上面标注一个Feign注解即可.) 即可完成对服务同提供方的接口绑定, 简化了使用SpringCloud Ribbon时, 自动封装服务调用客户端的开发量

使用feign 就是代替 RestTemplate

具体实现

实体类项目 加入 接口(和注解)

项目结构

cb1980779bc415afbdbee9816d1c688f.png

pom

<?xml version="1.0" encoding="UTF-8"?>
<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.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>springcloud</artifactId>
        <groupId>cn.com.codingce</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>springcloud-api</artifactId>
    <dependencies>
        <!--当前module自己需要的依赖, 如果父依赖中已经配置了版本-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <!--junit-->
<!--        <dependency>-->
<!--            <groupId>junit</groupId>-->
<!--            <artifactId>junit</artifactId>-->
<!--        </dependency>-->
        <!--feign-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-feign</artifactId>
            <version>1.4.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
        </dependency>
    </dependencies>
</project>

DeptClientService

package cn.com.codingce.service;
import cn.com.codingce.pojo.Dept;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import java.util.List;
/**
 * @author xzMa
 *
 * feign(面向接口编程)    练习  在实体类项目 创建service包  并创建 DeptClientService接口
 *
 *
 * 调用微服务两种方式 1 微服务名字 ribbon   2 接口和注解 feign
 *
 *
 * 只需要 接口和注解
 *
 * 注解
 */
@Component
@FeignClient(value = "SPRINGCLOUD-PROVIDER-DEPT")
public interface DeptClientService {
    //接口
    @GetMapping("/dept/get/{id}")
    public Dept queryById(@PathVariable("id") Long id);
    @GetMapping("/dept/list")
    public List<Dept> queryAll();
    @PostMapping("/dept/add")
    public boolean addDept(Dept dept);
}

新建客户端项目(springcloud-cusumer-dept-feign)

项目结构

65d1ce71b5c92ae096c9fa13d75531c8.png

pom

<?xml version="1.0" encoding="UTF-8"?>
<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.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>springcloud</artifactId>
        <groupId>cn.com.codingce</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <description>也是用来做客户端的</description>
    <artifactId>springcloud-cusumer-dept-feign</artifactId>
    <dependencies>
        <!--feign-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-feign</artifactId>
            <version>1.4.6.RELEASE</version>
        </dependency>
        <!--我们需要拿到实体类, 所以要配置api -module-->
        <dependency>
            <groupId>cn.com.codingce</groupId>
            <artifactId>springcloud-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <!--热部署工具-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--Ribbon-->
        <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-ribbon -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-ribbon</artifactId>
            <version>1.4.6.RELEASE</version>
        </dependency>
        <!--Eureka  客户端-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
            <version>1.4.6.RELEASE</version>
        </dependency>
    </dependencies>
</project>

DeptConsumerController

package cn.com.codingce.springcloud.controller;
import cn.com.codingce.pojo.Dept;
import cn.com.codingce.service.DeptClientService;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
@RestController
public class DeptConsumerController {
    @Resource
    private DeptClientService deptClientService = null;
    @RequestMapping("/consumer/dept/add")
    public boolean add(Dept dept) {
        return this.deptClientService.addDept(dept);
    }
    @RequestMapping("/consumer/dept/get/{id}")
    public Dept get(@PathVariable("id") Long id) {
        return this.deptClientService.queryById(id);
    }
    @RequestMapping("/consumer/dept/list")
    public List<Dept> list() {
        return this.deptClientService.queryAll();
    }
}

ConfigBean(配置Ribbon)

package cn.com.codingce.springcloud.config;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
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 ConfigBean {   //configuration -- spring applicationContext.xml
    //配置负载均衡实现RestTemplate  @LoadBalanced
    //IRule
    //AvailabilityFilteringRule: 先会过滤掉, 跳闸, 访问故障服务器
    //RoundRobinRule    轮询
    //RandomRule    随机
    //RetryRule: 会按照轮询获取服务~ 如果服务获取失败, 则会在指定的时间内进行, 重试
    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate() {
        return new RestTemplate();
    }
    @Bean
    public IRule myRule() {
        return new RandomRule();
    }
}

启动类FeginDeptConsumer_80

package cn.com.codingce.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.ComponentScan;
/**
 * @author xzMa
 * 在微服务启动的时候就能加载我们自定义的Ribbon类
 */
@SpringBootApplication
@EnableEurekaClient //Eureka 客户端
@EnableFeignClients(basePackages = {"cn.com.codingce"})
@ComponentScan("cn.com.codingce")
public class FeginDeptConsumer_80 {
    public static void main(String[] args) {
        SpringApplication.run(FeginDeptConsumer_80.class, args);
    }
}

运行截图

9b35034a13455dc8639817f8ca10cea4.png

0ee7902f9eea2a144decd26ad0215cb6.png

本项目地址:https://github.com/xzMhehe/codingce-java 

开源项目地址:https://github.com/OpenFeign/feign

相关实践学习
SLB负载均衡实践
本场景通过使用阿里云负载均衡 SLB 以及对负载均衡 SLB 后端服务器 ECS 的权重进行修改,快速解决服务器响应速度慢的问题
负载均衡入门与产品使用指南
负载均衡(Server Load Balancer)是对多台云服务器进行流量分发的负载均衡服务,可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。 本课程主要介绍负载均衡的相关技术以及阿里云负载均衡产品的使用方法。
目录
相关文章
|
3月前
|
负载均衡 监控 Dubbo
day00—探花交友前置Dubbo
day00—探花交友前置Dubbo
48 0
|
3月前
|
负载均衡 算法
Dubbo-负载均衡原理解析(1),一个本科渣渣是怎么逆袭从咸鱼到Offer收割机的
Dubbo-负载均衡原理解析(1),一个本科渣渣是怎么逆袭从咸鱼到Offer收割机的
|
中间件 程序员 Cloud Native
瞧一瞧 gRPC的拦截器 | 周末学习
上一次说到gRPC的认证总共有4种,其中介绍了常用且重要的2种
|
JSON 负载均衡 Java
SpringCloud Feign 远程调用(史上最详细讲解)
SpringCloud Feign 远程调用(史上最详细讲解)
5646 0
SpringCloud Feign 远程调用(史上最详细讲解)
|
JSON 负载均衡 算法
OpenFeign夺命连环9问?
OpenFeign夺命连环9问?
|
JSON 编解码 安全
Feign实战技巧篇
Feign实战技巧篇
115 0
|
JSON 负载均衡 算法
openFeign夺命连环9问,这谁受得了?
openFeign夺命连环9问,这谁受得了?
|
负载均衡 监控 前端开发
SpringCloud Netflix学习从练气到化虚
这篇文章是总结SpringCloud NetFlix的,其中使用的Eureka、Hystrix、zuul、feign等技术已经停更,目前是不推荐使用的,但是为了弄清楚微服务的架构演进,以及不同组件之间的差异性,笔者感觉还是需要学习这些已经过时的技术的,循序渐进式的学习才是最好的学习方法。
203 0
SpringCloud Netflix学习从练气到化虚
|
设计模式 监控 Java
Hystrix技术分享
在微服务架构中,一个请求需要调用多个服务是非常常见的。如客户端访问A服务,而A服务需要调用B服务,B服务需要调用C服务,由于网络原因或者自身的原因,如果B服务或者C服务不能及时响应,A服务将处于阻塞状态,直到B服务C服务响应。此时若有大量的请求涌入,容器的线程资源会被消耗完毕,导致服务瘫痪。服务与服务之间的依赖性,故障会传播,造成连锁反应,会对整个微服务系统造成灾难性的严重后果,这就是服务故障的“雪崩”效应。
177 0
Hystrix技术分享
|
Java Apache Spring
想不到Feign的一个注解还挺多坑的
想不到Feign的一个注解还挺多坑的
253 0