从零开始学springboot整合feign跨服务调用的方法
作者:CTO技术 发布时间:2023-05-15 18:30:22
介绍
微服务横行的互联网世界, 跨服务调用显得很平凡, 我们除了采用传统的http方式接口调用, 有没有更为优雅方便的方法呢?
答案是肯定的,feign就提供了轻便的方式!
如果你的服务都注册了注册中心,比如nacos, 那么调用会显得很轻松, 只需一个注解, 带上需要调用的服务名即可,**feign + nacos
**会帮你做剩余的事.
如果没有注册中心, 也无需担心, feign一样可以以传统的
ip:port
方式进行调用~
下面,我们来实践下吧
springboot整合feign
引入依赖, 这里注意, spring-cloud.version记得要和spring-boot版本匹配, 我这里spring-boot版本是2.1.3, 所以spring-cloud选择Greenwich.SR2版本.
大致的版本对应关系如下
更详细的请去https://start.spring.io/actuator/info
查询!
<properties>
<spring-cloud.version>Greenwich.SR2</spring-cloud.version>
</properties>
<dependencyManagement>
<dependencies>
<!--SpringCloud依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!--openfeign跨服务调用-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!--openfeign底层使用ApacheHttpClient调用-->
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
</dependency>
</dependencies>
然后我们去项目的启动类上加上注解@EnableFeignClients
最后, 加上Feign的配置application.properties
server.port=9999
#******************openfeign配置,参数采用的是默认的配置,可根据实际情况调整***********************
#启用ApacheHttpClient。默认就是true,使用HttpClientConnectionManager管理连接复用
feign.httpclient.enabled=true
#连接池的最大连接数,默认200
feign.httpclient.max-connections=200
#每个路由(服务器)分配的组最大连接数,默认50
feign.httpclient.max-connections-per-route=50
#连接最大存活时间,默认900秒
feign.httpclient.time-to-live=900
#连接最大存活时间单位秒
feign.httpclient.time-to-live-unit=seconds
#FeignAcceptGzipEncodingInterceptor * 被激活,会在header中添加Accept-Encoding:gzip,deflate,表明服务端在返回值时可以使用如下两个方式压缩返回结果
feign.compression.response.enabled=true
#FeignContentGzipEncodingInterceptor * 被激活,会在header中添加Content-Encoding:gzip,deflate,表明body中的参数是使用这两个方式的压缩
feign.compression.request.enabled=true
#content-length大于2048就进行请求参数的gzip压缩
feign.compression.request.minRequestSize=2048
#开启断路器
feign.hystrix.enabled=true
#断路器的隔离策略,默认就是线程池,SEMAPHORE模式下,就是主线程调用的远程的服务,即同步的
hystrix.command.default.execution.isolation.strategy=THREAD
#断路器超时设置
hystrix.command.default.execution.timeout.enabled=true
#总体请求在45秒还是无法得到响应,建议触发熔断(ribbon每个请求读取15秒超时,两个实例重试就是30秒,openfeign外层默认会进行一次调用,4次重试)
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=45000
#断路器的线程池存在一个问题,在队列满了以后,不会再去创建新的线程直到maximumSize
#核心线程池大小
hystrix.threadpool.default.coreSize=10
#最大线程池大小
hystrix.threadpool.default.maximumSize=10
#超过这个空闲时间,多于coreSize数量的线程会被回收,1分钟
hystrix.threadpool.default.keepAliveTimeMinutes=1
#队列的大小,默认为-1,即没有队列
hystrix.threadpool.default.maxQueueSize=200
#队列任务达到此阈值后,就开始拒绝;实际使用此参数进行队列是否满的判断
hystrix.threadpool.default.queueSizeRejectionThreshold=180
#负载均衡配置
#读取超时15秒,与原RestTemplate保持一致
ribbon.ReadTimeout=15000
#连接超时15秒,与原RestTemplate保持一致
ribbon.ConnectTimeout=15000
##每台服务器最多重试次数,但是首次调用不包括在内
ribbon.MaxAutoRetries=0
##最多重试多少台服务器,与实际实例数保持一致(不包括首台)
ribbon.MaxAutoRetriesNextServer=1
#是否所有操作都重试,
# false:get请求中,连接超时,读取超时都会重试,其他请求(put,post)连接超时重试,读取超时不重试。
# true:get请求中,连接超时,读取超时都会重试,其他请求(put,post)连接超时重试,读取超时重试。
#对于请求(put,post)要做好接口的幂等性
ribbon.OkToRetryOnAllOperations=true
spring-boot整合feign完成, 接下来我们编写测试代码
测试代码
两个服务
sb-alibaba-nacos (被调用方服务, 127.0.0.1:8081), 提供 getInfoById接口
sb-feign (调用方服务, 127.0.0.1:9999), 提供 getInfoById 测试接口
sb-alibaba-nacos提供的测试接口
@GetMapping(value = "getInfoById")
public String getInfoById(@RequestParam(value = "id") Long Id) {
return "example-service return :" + Id;
}
sb-feign相关代码
我们新建个包 feign,用来放所有涉及跨服务调用的类
ExampleControllerFeignClient.java:
package com.mrcoder.sbfeign.feign;
import feign.hystrix.FallbackFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
@FeignClient(name = "sb-alibaba-nacos", url = "http://127.0.0.1:8081/", fallbackFactory = ExampleControllerFeignClient.ExampleControllerFeignClientFallbackFactory.class)
public interface ExampleControllerFeignClient {
@GetMapping(value = "getInfoById")
String getInfoById(@RequestParam(value = "id") Long Id);
/**
* 服务降级内部类
*/
@Component
class ExampleControllerFeignClientFallbackFactory implements FallbackFactory<ExampleControllerFeignClient> {
private Logger logger = LoggerFactory.getLogger(ExampleControllerFeignClientFallbackFactory.class);
@Override
public ExampleControllerFeignClient create(Throwable cause) {
return new ExampleControllerFeignClient() {
@Override
public String getInfoById(Long signingLogId) {
logger.error("跨服务调用失败, 原因是:" + cause.getMessage());
return "失败, 原因是:" + cause.getMessage();
}
};
}
}
}
关键代码就是
@FeignClient(name = "sb-alibaba-nacos", url = "http://127.0.0.1:8081/", fallbackFactory = ExampleControllerFeignClient.ExampleControllerFeignClientFallbackFactory.class)
name 就是被调用方的服务名称 (
这里如果你没有配置服务注册中心的化,其实可以随便写
)url 就是被调用方的地址(
如果配置了服务注册中心, 可以不写!, 不过两个服务必须都注册!,这样才能找到!
)fallbackFactory 就是调用失败时指定的处理类
最后, 我们写个测试方法
package com.mrcoder.sbfeign.controller;
import com.mrcoder.sbfeign.feign.ExampleControllerFeignClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@CrossOrigin
@RestController
public class TestController {
@Autowired
private ExampleControllerFeignClient exampleControllerFeignClient;
@RequestMapping(value = "getInfoById", method = RequestMethod.GET)
public String test(@RequestParam(value = "id") Long Id) {
return exampleControllerFeignClient.getInfoById(Id);
}
}
开启两个服务sb-alibaba-nacos, sb-feign
而后访问sb-feign的测试方法
http://localhost:9999/getInfoById?id=22
出现
sb-alibaba-nacos return :22
跨服务调用成功~
来源:https://blog.csdn.net/mrcoderstack/article/details/109443790


猜你喜欢
- 这个问题是我自己开发中遇到的问题 数据库使用的是mysql5.6 字段名称为checkingTime 类
- 本文实例讲述了Android实现跑马灯效果的方法。分享给大家供大家参考。具体如下:运行效果截图如下:直接在布局里写代码就好了:<Tex
- 这其实是去年校招时我遇到的一道阿里巴巴的笔试题(承认有点久远了-。-),嗯,如果我没记错的话,当时是作为Java方向的一道选做大题。当然题意
- 先给大家展示下关于仿支付宝钱包首页中带有分割线的gridview,俗称九宫格 的效果图,怎么样是不是和你想象的一样啊。在你的预料之中就继续访
- TabControl控件中TabPage选项卡切换时的触发事件选项卡切换触发的是TabControl控件的SelectedIndexChan
- 实例如下:private void Form1_Load(object sender, EventArgs e)
- 之前的一篇博客中,讲的是用栈实现了中缀表达式的简易计算器,对于我们人来讲,中缀表达式是一种比较直观,而且非常好计算的一种形式,但对于计算器来
- 一、题目描述题目实现:使用网络编程时,需要通过Socket传递对象。二、解题思路创建一个类:Student,实现序列化Student类包含两
- 若使用 Spring IoC 容器(ApplicationContext或BeanFactory)作为你的业务对象(你也应该这么做!),你会
- Springboot 在普通类型注入Service或mapper最近遇到一个难题(大佬可能感觉这太简单了把),对于我这样的小白来说,确实有些
- 配置不生效的解决办法注意:如果配置不生效,则说明spring优先加载了其他配置:解决办法:添加启动参数 -Dlogging.config=c
- MyBatis 通过包含的jdbcType类型BIT FLOAT CHAR &nbs
- 前言通过上一章的学习, 我们了解了Server启动的大致流程, 有很多组件与模块并没有细讲, 从这个章开始, 我们开始详细剖析netty的各
- 记事本涉及到的仅仅是对string 的存储,而且在读取上并不存在什么难点,直接用textview显示便可以了。需要做的主要是使用SQLite
- 一、JSON格式介绍JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。相对于另一种数据交换格式
- 问题最近 Cordova 项目里有一个需求,这里需要从 assets 目录中读取文件,加载配置信息,并且代码中要用到。因为看到 gradle
- 控制器Controller控制器复杂提供访问应用程序的行为,通常通过接口定义或注解定义两种方法实现。控制器负责解析用户的请求并将其转换为一个
- 举例:存在一个类:Public Class Student{ public string name; public int age;}Stu
- springboot初始化器新建项目项目结构idea工具类中初始化本地git仓库选择当前项目目录即可工具类由VCS变成了Gitadd 到缓存
- XSS ,全名:cross-site scripting(跨站点脚本),是当前 web 应用中最危险和最普遍的漏洞之一。攻击者尝试注入恶意脚