Spring Cloud OpenFeign夺命连环9问,这谁受得了?

1、前言

前面介绍了Spring Cloud 中的灵魂摆渡者Nacos,和它的前辈们相比不仅仅功能强大,而且部署非常简单。

今天介绍一款服务调用的组件:OpenFeign,同样是一款超越先辈(RibbonFeign)的狠角色。

文章目录如下:

8e17e2744c12e9570d87fbfa11f0de08.png

2、Feign是什么?

Feign也是一个狠角色,Feign旨在使得Java Http客户端变得更容易。

Feign集成了Ribbon、RestTemplate实现了负载均衡的执行Http调用,只不过对原有的方式(Ribbon+RestTemplate)进行了封装,开发者不必手动使用RestTemplate调服务,而是定义一个接口,在这个接口中标注一个注解即可完成服务调用,这样更加符合面向接口编程的宗旨,简化了开发。

a51708bda235fe8932c3c79f5171a68d.png

但遗憾的是Feign现在停止迭代了,当然现在也是有不少企业在用。

有想要学习Feign的读者可以上spring Cloud官网学习,陈某这里也不再详细介绍了,不是今天的重点。

3、openFeign是什么?

前面介绍过停止迭代的Feign,简单点来说:OpenFeign是springcloud在Feign的基础上支持了SpringMVC的注解,如@RequestMapping等等。OpenFeign的@FeignClient可以解析SpringMVC的@RequestMapping注解下的接口,并通过动态代理的方式产生实现类,实现类中做负载均衡并调用其他服务。

官网地址:https://docs.spring.io/spring-cloud-openfeign/docs/2.2.10.BUILD-SNAPSHOT/reference/html

4、Feign和openFeign有什么区别?

FeignopenFiegn
Feign是SpringCloud组件中一个轻量级RESTful的HTTP服务客户端,Feign内置了Ribbon,用来做客户端负载均衡,去调用服务注册中心的服务。Feign的使用方式是:使用Feign的注解定义接口,调用这个接口,就可以调用服务注册中心的服务OpenFeign 是SpringCloud在Feign的基础上支持了SpringMVC的注解,如@RequestMapping等。OpenFeign 的@FeignClient可以解析SpringMVC的@RequestMapping注解下的接口,并通过动态代理的方式产生实现类,实现类中做负载均衡并调用其他服务。

5、环境准备

本篇文章Spring Cloud版本、JDK环境、项目环境均和上一篇Nacos的环境相同:五十五张图告诉你微服务的灵魂摆渡者Nacos究竟有多强?。

注册中心就不再使用Eureka了,直接使用Nacos作为注册和配置中心,有不会的可以查看Nacos文章。

本篇文章搭建的项目结构如下图:

1baa0242cb7a539ff91ecf3fee986122.png

注册中心使用Nacos,创建个微服务,分别为服务提供者Produce,服务消费者Consumer

6、创建服务提供者

既然是微服务之间的相互调用,那么一定会有服务提供者了,创建openFeign-provider9005,注册进入Nacos中,配置如下:

server:port: 9005
spring:application:## 指定服务名称,在nacos中的名字name: openFeign-providercloud:nacos:discovery:# nacos的服务地址,nacos-server中IP地址:端口号server-addr: 127.0.0.1:8848
management:endpoints:web:exposure:## yml文件中存在特殊字符,必须用单引号包含,否则启动报错include: '*'

注意:此处的spring.application.name指定的名称将会在openFeign接口调用中使用。

项目源码都会上传,关于如何注册进入Nacos,添加什么依赖源码都会有,结合陈某上篇Nacos文章,这都不是难事!

7、创建服务消费者

新建一个模块openFeign-consumer9006作为消费者服务,步骤如下。

1、添加依赖

除了Nacos的注册中心的依赖,还要添加openFeign的依赖,如下:

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

2、添加注解@EnableFeignClients开启openFeign功能

老套路了,在Spring boot 主启动类上添加一个注解@EnableFeignClients,开启openFeign功能,如下:

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class OpenFeignConsumer9006Application
{public static void main(String[] args) {SpringApplication.run(OpenFeignConsumer9006Application.class, args);}
}

3、新建openFeign接口

新建一个openFeign接口,使用@FeignClient注解标注,如下:

@FeignClient(value = "openFeign-provider")
public interface OpenFeignService {
}

注意:该注解@FeignClient中的value属性指定了服务提供者在nacos注册中心的服务名

4、新建一个Controller调试

新建一个controller用来调试接口,直接调用openFeign的接口,如下:

@RestController
@RequestMapping("/openfeign")
public class OpenFeignController {}

好了,至此一个openFeign的微服务就搭建好了,并未实现具体的功能,下面一点点实现。

8、openFeign如何传参?

开发中接口传参的方式有很多,但是在openFeign中的传参是有一定规则的,下面详细介绍。

1、传递JSON数据

这个也是接口开发中常用的传参规则,在Spring Boot 中通过@RequestBody标识入参。

provider接口中JSON传参方法如下:

@RestController
@RequestMapping("/openfeign/provider")
public class OpenFeignProviderController {@PostMapping("/order2")public Order createOrder2(@RequestBody Order order){return order;}
}

consumer中openFeign接口中传参代码如下:

@FeignClient(value = "openFeign-provider")
public interface OpenFeignService {/*** 参数默认是@RequestBody标注的,这里的@RequestBody可以不填* 方法名称任意*/@PostMapping("/openfeign/provider/order2")Order createOrder2(@RequestBody Order order);
}

注意:openFeign默认的传参方式就是JSON传参(@RequestBody),因此定义接口的时候可以不用@RequestBody注解标注,不过为了规范,一般都填上。

2、POJO表单传参

这种传参方式也是比较常用,参数使用POJO对象接收。

provider服务提供者代码如下:

@RestController
@RequestMapping("/openfeign/provider")
public class OpenFeignProviderController {@PostMapping("/order1")public Order createOrder1(Order order){return order;}
}

consumer消费者openFeign代码如下:

@FeignClient(value = "openFeign-provider")
public interface OpenFeignService {/*** 参数默认是@RequestBody标注的,如果通过POJO表单传参的,使用@SpringQueryMap标注*/@PostMapping("/openfeign/provider/order1")Order createOrder1(@SpringQueryMap Order order);
}

网上很多人疑惑POJO表单方式如何传参,官方文档明确给出了解决方案,如下:

d67d7c64bea592204b9f7ea45d389b22.png

openFeign提供了一个注解@SpringQueryMap完美解决POJO表单传参。

3、URL中携带参数

此种方式针对restful方式中的GET请求,也是比较常用请求方式。

provider服务提供者代码如下:

@RestController
@RequestMapping("/openfeign/provider")
public class OpenFeignProviderController {@GetMapping("/test/{id}")public String test(@PathVariable("id")Integer id){return "accept one msg id="+id;
}

consumer消费者openFeign接口如下:

@FeignClient(value = "openFeign-provider")
public interface OpenFeignService {@GetMapping("/openfeign/provider/test/{id}")String get(@PathVariable("id")Integer id);
}

使用注解@PathVariable接收url中的占位符,这种方式很好理解。

4、普通表单参数

此种方式传参不建议使用,但是也有很多开发在用。

provider服务提供者代码如下:

@RestController
@RequestMapping("/openfeign/provider")
public class OpenFeignProviderController {@PostMapping("/test2")public String test2(String id,String name){return MessageFormat.format("accept on msg id={0},name={1}",id,name);}
}

consumer消费者openFeign接口传参如下:

@FeignClient(value = "openFeign-provider")
public interface OpenFeignService {/*** 必须要@RequestParam注解标注,且value属性必须填上参数名* 方法参数名可以任意,但是@RequestParam注解中的value属性必须和provider中的参数名相同*/@PostMapping("/openfeign/provider/test2")String test(@RequestParam("id") String arg1,@RequestParam("name") String arg2);
}

5、总结

传参的方式有很多,比如文件传参.....陈某这里只是列举了四种常见得传参方式。

9、超时如何处理?

想要理解超时处理,先看一个例子:我将provider服务接口睡眠3秒钟,接口如下:

@PostMapping("/test2")
public String test2(String id,String name) throws InterruptedException {Thread.sleep(3000);return MessageFormat.format("accept on msg id={0},name={1}",id,name);
}

此时,我们调用consumer的openFeign接口返回结果如下图:

2b20abdc3a0daa6f44c458d71adddb73.png

很明显的看出程序异常了,返回了接口调用超时。what?why?...........

openFeign其实是有默认的超时时间的,默认分别是连接超时时间10秒、读超时时间60秒,源码在feign.Request.Options#Options()这个方法中,如下图:

4d392ffc1efc4f5b06a32687f0f92726.png

那么问题来了:为什么我只设置了睡眠3秒就报超时呢?

其实openFeign集成了Ribbon,Ribbon的默认超时连接时间、读超时时间都是是1秒,源码在org.springframework.cloud.openfeign.ribbon.FeignLoadBalancer#execute()方法中,如下图:

88e8b5bef053ad55ca38592f23d7ba43.png

源码大致意思:如果openFeign没有设置对应得超时时间,那么将会采用Ribbon的默认超时时间。

理解了超时设置的原理,由之产生两种方案也是很明了了,如下:

  • 设置openFeign的超时时间

  • 设置Ribbon的超时时间

1、设置Ribbon的超时时间(不推荐)

设置很简单,在配置文件中添加如下设置:

ribbon:# 值的是建立链接所用的时间,适用于网络状况正常的情况下, 两端链接所用的时间ReadTimeout: 5000# 指的是建立链接后从服务器读取可用资源所用的时间ConectTimeout: 5000

2、设置openFeign的超时时间(推荐)

openFeign设置超时时间非常简单,只需要在配置文件中配置,如下:

feign:client:config:## default 设置的全局超时时间,指定服务名称可以设置单个服务的超时时间default:connectTimeout: 5000readTimeout: 5000

default设置的是全局超时时间,对所有的openFeign接口服务都生效

但是正常的业务逻辑中可能涉及到多个openFeign接口的调用,如下图:

361ba3f4a4ff401c09e4aeb9d193ff4a.png

上图中的伪代码如下:

public T invoke(){//1. 调用serviceAserviceA();//2. 调用serviceAserviceB();//3. 调用serviceAserviceC();
}

那么上面配置的全局超时时间能不能通过呢?很显然是serviceAserviceB能够成功调用,但是serviceC并不能成功执行,肯定报超时。

此时我们可以给serviceC这个服务单独配置一个超时时间,配置如下:

feign:client:config:## default 设置的全局超时时间,指定服务名称可以设置单个服务的超时时间default:connectTimeout: 5000readTimeout: 5000## 为serviceC这个服务单独配置超时时间serviceC:connectTimeout: 30000readTimeout: 30000

注意:单个配置的超时时间将会覆盖全局配置。

10、如何开启日志增强?

openFeign虽然提供了日志增强功能,但是默认是不显示任何日志的,不过开发者在调试阶段可以自己配置日志的级别。

openFeign的日志级别如下:

  • NONE:默认的,不显示任何日志;

  • BASIC:仅记录请求方法、URL、响应状态码及执行时间;

  • HEADERS:除了BASIC中定义的信息之外,还有请求和响应的头信息;

  • FULL:除了HEADERS中定义的信息之外,还有请求和响应的正文及元数据。

配置起来也很简单,步骤如下:

1、配置类中配置日志级别

需要自定义一个配置类,在其中设置日志级别,如下:

6cdb98314ab1fe62018e53dc3a3fb0f7.png

注意:这里的logger是feign包里的。

2、yaml文件中设置接口日志级别

只需要在配置文件中调整指定包或者openFeign的接口日志级别,如下:

logging:level:cn.myjszl.service: debug

这里的cn.myjszl.service是openFeign接口所在的包名,当然你也可以配置一个特定的openFeign接口。

3、演示效果

上述步骤将日志设置成了FULL,此时发出请求,日志效果如下图:

2d2fbcd4ff88f1822f71a1147e9bb660.png

日志中详细的打印出了请求头、请求体的内容。

11、如何替换默认的httpclient?

Feign在默认情况下使用的是JDK原生的URLConnection发送HTTP请求,没有连接池,但是对每个地址会保持一个长连接,即利用HTTP的persistence connection。

在生产环境中,通常不使用默认的http client,通常有如下两种选择:

  • 使用ApacheHttpClient

  • 使用OkHttp

至于哪个更好,其实各有千秋,我比较倾向于ApacheHttpClient,毕竟老牌子了,稳定性不在话下。

那么如何替换掉呢?其实很简单,下面演示使用ApacheHttpClient替换。

1、添加ApacheHttpClient依赖

在openFeign接口服务的pom文件添加如下依赖:

<!--     使用Apache HttpClient替换Feign原生httpclient--><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId></dependency><dependency><groupId>io.github.openfeign</groupId><artifactId>feign-httpclient</artifactId></dependency>

为什么要添加上面的依赖呢?从源码中不难看出,请看org.springframework.cloud.openfeign.FeignAutoConfiguration.HttpClientFeignConfiguration这个类,代码如下:

a9e864d640ac461bcb5059ddbddbd314.png

上述红色框中的生成条件,其中的@ConditionalOnClass(ApacheHttpClient.class),必须要有ApacheHttpClient这个类才会生效,并且feign.httpclient.enabled这个配置要设置为true

2、配置文件中开启

在配置文件中要配置开启,代码如下:

feign:client:httpclient:# 开启 Http Clientenabled: true

3、如何验证已经替换成功?

其实很简单,在feign.SynchronousMethodHandler#executeAndDecode()这个方法中可以清楚的看出调用哪个client,如下图:

8f98763cb1a61abac80da40d1fef3fb2.png

上图中可以看到最终调用的是ApacheHttpClient

4、总结

上述步骤仅仅演示一种替换方案,剩下的一种不再演示了,原理相同。

12、如何通讯优化?

在讲如何优化之前先来看一下GZIP 压缩算法,概念如下:

gzip是一种数据格式,采用用deflate算法压缩数据;gzip是一种流行的数据压缩算法,应用十分广泛,尤其是在Linux平台。

当GZIP压缩到一个纯文本数据时,效果是非常明显的,大约可以减少70%以上的数据大小。

网络数据经过压缩后实际上降低了网络传输的字节数,最明显的好处就是可以加快网页加载的速度。网页加载速度加快的好处不言而喻,除了节省流量,改善用户的浏览体验外,另一个潜在的好处是GZIP与搜索引擎的抓取工具有着更好的关系。例如 Google就可以通过直接读取GZIP文件来比普通手工抓取更快地检索网页。

GZIP压缩传输的原理如下图:

49139195d90621bb2a3f169a19ade7dd.png

按照上图拆解出的步骤如下:

  • 客户端向服务器请求头中带有:Accept-Encoding:gzip,deflate 字段,向服务器表示,客户端支持的压缩格式(gzip或者deflate),如果不发送该消息头,服务器是不会压缩的。

  • 服务端在收到请求之后,如果发现请求头中含有Accept-Encoding字段,并且支持该类型的压缩,就对响应报文压缩之后返回给客户端,并且携带Content-Encoding:gzip消息头,表示响应报文是根据该格式压缩过的。

  • 客户端接收到响应之后,先判断是否有Content-Encoding消息头,如果有,按该格式解压报文。否则按正常报文处理。

openFeign支持请求/响应开启GZIP压缩,整体的流程如下图:

44faabd708fbd7bb709fa7e831acf136.png

上图中涉及到GZIP传输的只有两块,分别是Application client -> Application ServiceApplication Service->Application client

注意:openFeign支持的GZIP仅仅是在openFeign接口的请求和响应,即是openFeign消费者调用服务提供者的接口。

openFeign开启GZIP步骤也是很简单,只需要在配置文件中开启如下配置:

feign:## 开启压缩compression:request:enabled: true## 开启压缩的阈值,单位字节,默认2048,即是2k,这里为了演示效果设置成10字节min-request-size: 10mime-types: text/xml,application/xml,application/jsonresponse:enabled: true

上述配置完成之后,发出请求,可以清楚看到请求头中已经携带了GZIP压缩,如下图:

4045a591e0eb8260d1ba961eace738ff.png

13、如何熔断降级?

常见的熔断降级框架有HystrixSentinel,openFeign默认支持的就是Hystrix,这个在官方文档上就有体现,毕竟是一奶同胞嘛,哈哈...........

但是阿里的Sentinel无论是功能特性、简单易上手等各方面都完全秒杀Hystrix,因此此章节就使用openFeign+Sentinel进行整合实现服务降级。

说明:此处并不着重介绍Sentinel,陈某打算放在下一篇文章详细介绍Sentinel的强大之处。

1、添加Sentinel依赖

openFeign-consumer9006消费者的pom文件添加sentinel依赖(由于使用了聚合模块,不指定版本号),如下:

<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>

2、配置文件中开启sentinel熔断降级

要想openFeign使用sentinel的降级功能,还需要在配置文件中开启,添加如下配置:

feign:sentinel:enabled: true

3、添加降级回调类

这个类一定要和openFeign接口实现同一个类,如下图:

2e331a3a49baf1bd3657574bb6a2e8df.png

OpenFeignFallbackService这个是降级回调的类,一旦OpenFeignService中对应得接口出现了异常则会调用这个类中对应得方法进行降级处理。

4、添加fallback属性

@FeignClient中添加fallback属性,属性值是降级回调的类,如下:

@FeignClient(value = "openFeign-provider",fallback = OpenFeignFallbackService.class)
public interface OpenFeignService {}

5、演示

经过如上4个步骤,openFeign的熔断降级已经设置完成了,此时演示下效果。

通过postman调用http://localhost:9006/openfeign/order3这个接口,正常逻辑返回如下图:

ccf6095555af169be4cd401392510c14.png

现在手动造个异常,在服务提供的接口中抛出异常,如下图:

3c8f5e650e01b744d72a28e0588619cd.png

此时重新调用http://localhost:9006/openfeign/order3,返回如下图:

78c027e8cef67925bed05af5b447556e.png

哦豁,可以很清楚的看到服务已经成功降级调用,哦了,功能完成。

注意:实际开发中返回结果应该根据架构统一定制,陈某这里只是为了演示方便,不要借鉴,哈哈。。。

14、总结

本篇文章主要面对初学者,深入的源码以及熔断降级放在后面详细介绍,文中若有表述不清,错误的地方欢迎指正!

d21494e8de1365567034b0f1e31d24b5.gif

往期推荐

芭比扣了!Nacos中服务删除不了,肿么办?

2022-02-17

4c7db34023d8c45b01f72a173533f8b1.png

Spring Cloud Alibaba Nacos 服务注册与发现功能实现!

2022-02-07

84b2e7af7804232d86d21276042cd02f.png

Spring Cloud Alibaba Nacos路由策略之保护阈值!

2022-02-14

a62859e5d642efc3dc100579168950e0.png

求点赞、在看、分享三连62be0e44dab7c19879784c2fb9dc53e7.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/544293.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

玩转Nacos参数配置!多图勿点

作者 | 磊哥来源 | Java中文社群&#xff08;ID&#xff1a;javacn666&#xff09;转载请联系授权&#xff08;微信ID&#xff1a;GG_Stone&#xff09;Nacos 中的参数有很多&#xff0c;如&#xff1a;命名空间、分组名、服务名、保护阈值、服务路由类型、临时实例等&#xff…

为什么wait/notify必须要和synchronized一起使用?

作者 | 磊哥来源 | Java面试真题解析&#xff08;ID&#xff1a;aimianshi666&#xff09;转载请联系授权&#xff08;微信ID&#xff1a;GG_Stone&#xff09;在多线程编程中&#xff0c;wait 方法是让当前线程进入休眠状态&#xff0c;直到另一个线程调用了 notify 或 notify…

Magento Add Fee or Discount to Order Totals

2019独角兽企业重金招聘Python工程师标准>>> In this tutorial, we will see how to add new line item to magento order totals. What this means is that, how to add an additional Fee or Discount, or any kind of charge to order total of the magento chec…

再见 Feign!推荐一款微服务间调用神器,跟 SpringCloud 绝配!

在微服务项目中&#xff0c;如果我们想实现服务间调用&#xff0c;一般会选择Feign。之前介绍过一款HTTP客户端工具Retrofit&#xff0c;配合SpringBoot非常好用&#xff01;其实Retrofit不仅支持普通的HTTP调用&#xff0c;还能支持微服务间的调用&#xff0c;负载均衡和熔断限…

Spring Cloud Alibaba Nacos 的 2 种健康检查机制!

作者 | 磊哥来源 | Java中文社群&#xff08;ID&#xff1a;javacn666&#xff09;转载请联系授权&#xff08;微信ID&#xff1a;GG_Stone&#xff09;Spring Cloud Alibaba Nacos 作为注册中心不止提供了服务注册和服务发现功能&#xff0c;它还提供了服务可用性监测的机制。…

Python之包管理工具

在Python环境中已经有很多成熟的包&#xff0c;可以通过安装这些包来扩展我们的程序。 例如&#xff0c;很多时候Python开发人员都会去PyPI网站去查找自己想要使用的包&#xff0c;然后进行安装。PyPI &#xff08; Python Package Index&#xff09;是获得第三方 Python 软件包…

为什么wait和notify必须放在synchronized中?

作者 | 磊哥来源 | Java面试真题解析&#xff08;ID&#xff1a;aimianshi666&#xff09;转载请联系授权&#xff08;微信ID&#xff1a;GG_Stone&#xff09;在多线程编程中&#xff0c;wait 方法是让当前线程进入休眠状态&#xff0c;直到另一个线程调用了 notify 或 notify…

聊聊并发编程的10个坑

前言对于从事后端开发的同学来说&#xff0c;并发编程肯定再熟悉不过了。说实话&#xff0c;在java中并发编程是一大难点&#xff0c;至少我是这么认为的。不光理解起来比较费劲&#xff0c;使用起来更容易踩坑。不信&#xff0c;让继续往下面看。今天重点跟大家一起聊聊并发编…

macbook终端使用记(二)终端快捷键

为什么80%的码农都做不了架构师&#xff1f;>>> Command K清屏 Command T新建标签 Command M最小化窗口 Command W 关闭当前标签页 Command S 保存终端输出 Command D 垂直分隔当前标签页 Command Shift D 水平分隔当前标签页 Command shift {或}向左/向…

颜值爆表!Redis 官方可视化工具来啦,功能真心强大!

最近逛了一下Redis官方网站&#xff0c;发现Redis不仅推出了很多新特性&#xff0c;而且还发布了一款可视化工具RedisInsight。试用了一下感觉非常不错&#xff0c;最关键的是能支持RedisJSON之类的新特性&#xff0c;这是第三方工具无法比拟的。今天带大家体验一下RedisInsigh…

20个响应式网页设计中的“神话”误区

关于响应式网页的重要性我们已经证实了很长时间了&#xff0c;现在是该把焦点放到如何做出好的响应式网页设计的时候了。一起来看看吧&#xff01; 虽然很多人都在谈论响应式网页&#xff0c;但并不是每个人都知道他们在说什么。很多时候你看到网上的一些信息也在挑战你对响应式…

MySQL 索引失效的 15 种场景!

背景 无论你是技术大佬&#xff0c;还是刚入行的小白&#xff0c;时不时都会踩到Mysql数据库不走索引的坑。常见的现象就是&#xff1a;明明在字段上添加了索引&#xff0c;但却并未生效。前些天就遇到一个稍微特殊的场景&#xff0c;同一条SQL语句&#xff0c;在某些参数下生效…

Java夺命21连问!(附答案)

大家好&#xff0c;我是磊哥。有位朋友工作三年&#xff0c;去面试&#xff0c;给大家整理一下面试题&#xff0c;并附上答案。Mysql索引在什么情况下会失效MySql的存储引擎InnoDB与MyISAM的区别Mysql在项目中的优化场景&#xff0c;慢查询解决等Mysql有什么索引&#xff0c;索…

SpringCloud Nacos + Ribbon 调用服务的 2 种方法!

作者 | 磊哥来源 | Java中文社群&#xff08;ID&#xff1a;javacn666&#xff09;转载请联系授权&#xff08;微信ID&#xff1a;GG_Stone&#xff09;在 Nacos 中&#xff0c;服务调用主要是通过 RestTemplate Ribbon 实现的&#xff0c;RestTemplate 是 Spring 提供的 Rest…

SpringCloud Ribbon中的7种负载均衡策略!

作者 | 磊哥来源 | Java中文社群&#xff08;ID&#xff1a;javacn666&#xff09;转载请联系授权&#xff08;微信ID&#xff1a;GG_Stone&#xff09;负载均衡通器常有两种实现手段&#xff0c;一种是服务端负载均衡器&#xff0c;另一种是客户端负载均衡器&#xff0c;而我们…

线程池是如何执行的?拒绝策略有哪些?

作者 | 磊哥来源 | Java面试真题解析&#xff08;ID&#xff1a;aimianshi666&#xff09;转载请联系授权&#xff08;微信ID&#xff1a;GG_Stone&#xff09;聊到线程池就一定会聊到线程池的执行流程&#xff0c;也就是当有一个任务进入线程池之后&#xff0c;线程池是如何执…

浮动元素的均匀分布和两端对齐

当我们使用float来使元素并排显示的时候&#xff0c;可以使用margin来控制元素之间的距离&#xff0c;而在很多版式里&#xff08;例如产品图片的列表&#xff09;&#xff0c;需要浮动的元素达到两端对齐的效果&#xff0c;如图1所示。 图1 两端对齐的版式 单纯使用float:left…

20 图|Nacos 手摸手教程

Nacos 作为服务注册中心、配置中心&#xff0c;已经非常成熟了&#xff0c;业界的标杆&#xff0c;在讲解 Nacos 的架构原理之前&#xff0c;我先给大家来一篇开胃菜&#xff1a;讲解 Nacos 如何使用。涉及到如下两个话题&#xff1a;用 Nacos 作为注册中心。用 Nacos 作为配置…

为什么Spring需要三级缓存解决循环依赖,而不是二级缓存?

来源&#xff1a;https://www.cnblogs.com/semi-sub/p/13548479.html在使用spring框架的日常开发中&#xff0c;bean之间的循环依赖太频繁了&#xff0c;spring已经帮我们去解决循环依赖问题&#xff0c;对我们开发者来说是无感知的&#xff0c;下面具体分析一下spring是如何解…

20款华丽的几何形状字体【免费下载】

这里手机的字体使用几何形状设计。流畅简洁的线条&#xff0c;完美的圆形的角度建立一个完整性的设计感。使用几何形状生成出每一个优雅而现代的字母。这些字体可以用于标题和正文。由于他们的设计适合任何干净简约设计&#xff0c;因此很受欢迎。向下滚动并下载这些免费几何字…