Feign中本身已经集成了Ribbon依赖和自动配置,因此我们不需要额外引入依赖,也不需要再注册RestTemplate 对象。
另外,我们可以像上节课中讲的那样去配置Ribbon,可以通过 ribbon.xx 来进行全局配置。
也可以通过 服务名.ribbon.xx 来对指定服务配置:
(1)修改OrderService的启动类设置OrderApplication
package cn.itbluebox.order;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EntityScan(“cn.itbluebox.order.entity”)
@EnableFeignClients
public class OrderApplication {
/*
使用Spring提供的 RestTemplate 发送http请求到商品服务
1、创建RestTemplate对象交给容器管理
2、在使用的时候,调用其方法完成操作(getXX,postXX)
@LoadBalanced : 是Ribbon提供的负载均衡的注解
*/
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class,args);
}
}
(2)启动第二个product_service
修改product_service的pom.xml
设置端口号为9011
启动测试
启动成功
查看Eurekahttp://localhost:9000/
重新启动order_service
(3)访问测试http://localhost:9002/order/buy/1
刷新页面再次访问
========================================================================
从Spring Cloud Edgware开始,Feign支持使用属性自定义Feign。对于一个指定名称的FeignClient(例如该Feign Client的名称为 feignName ),Feign支持如下配置项:
feign:
client:
config:
feignName: ##定义FeginClient的名称
connectTimeout: 5000 # 相当于Request.Options
readTimeout: 5000 # 相当于Request.Options
配置Feign的日志级别,相当于代码配置方式中的Logger
loggerLevel: full
Feign的错误解码器,相当于代码配置方式中的ErrorDecoder
errorDecoder: com.example.SimpleErrorDecoder
配置重试,相当于代码配置方式中的Retryer
retryer: com.example.SimpleRetryer
配置拦截器,相当于代码配置方式中的RequestInterceptor
requestInterceptors:
-
com.example.FooRequestInterceptor
-
com.example.BarRequestInterceptor
decode404: fals
-
feignName:FeginClient的名称
-
connectTimeout : 建立链接的超时时长
-
readTimeout : 读取超时时长
-
loggerLevel: Fegin的日志级别
-
errorDecoder :Feign的错误解码器
-
retryer : 配置重试
-
requestInterceptors : 添加请求拦截器
-
decode404 : 配置熔断不处理404异常
Spring Cloud Feign 支持对请求和响应进行GZIP压缩,以减少通信过程中的性能损耗。通过下面的参数即可开启请求与响应的压缩功能:
feign:
compression:
request:
enabled: true # 开启请求压缩
response:
enabled: true # 开启响应压缩
同时,我们也可以对请求的数据类型,以及触发压缩的大小下限进行设置:
feign:
compression:
request:
enabled: true # 开启请求压缩
mime-types: text/html,application/xml,application/json # 设置压缩的数据类型
min-request-size: 2048 # 设置触发压缩的大小下限
注:上面的数据类型、压缩大小下限均为默认值。
在开发或者运行阶段往往希望看到Feign请求过程的日志记录,默认情况下Feign的日志是没有开启的。要想用属性配置方式来达到日志效果,只需在 application.yml 中添加如下内容即可:
修改order_service当中的application.yml
feign:
client:
config:
service-product:
loggerLevel: FULL
logging:
level:
cn.itbluebox.order.feign.ProductFeignClient : debug
-
logging.level.xx
: debug : Feign日志只会对日志级别为debug的做出响应 -
feign.client.config.shop-service-product.loggerLevel
: 配置Feign的日志Feign有四种日志级别: -
NONE
【性能最佳,适用于生产】:不记录任何日志(默认值) -
BASIC
【适用于生产环境追踪问题】:仅记录请求方法、URL、响应状态代码以及执行时间 -
HEADERS
:记录BASIC级别的基础上,记录请求和响应的header。 -
FULL
【比较适用于开发及测试环境定位问题】:记录请求和响应的header、body和元数据。
重新启动运行测试
刷新页面访问测试http://localhost:9002/order/buy/1
==================================================================
在这里的工程在之前都已经重复多次创建,我们在这里省略创建的过程直接导入对应的代码即可
工程下载地址:https://download.youkuaiyun.com/download/qq_44757034/46931029
(1)设置tomcat最大线程数
设置order_service当中的application.yml
server:
port: 9002 #端口
tomcat:
max-threads: 10
(2)设置product_service延时返回数据
在ProductController当中修改
@RequestMapping(value = “/{id}”,method = RequestMethod.GET)
public Product findById(@PathVariable Long id) {
try {
Thread.sleep(2000l);
} catch (InterruptedException e) {
e.printStackTrace();
}
Product product = productService.findById(id);
product.setProductName(“访问的服务地址:”+ip + “:” + port);
return product;
}
(3)运行启动所有的工程测试
访问:http://localhost:9002/order/buy/1
我们可以看到访问时间是2秒多
访问http://localhost:9002/order/1
我们可以看到访问时间是3毫秒
(1)性能工具Jmetter
Apache JMeter是Apache组织开发的基于Java的压力测试工具。用于对软件做压力测试,它最初被设计用于Web应用测试,但后来扩展到其他测试领域。
它可以用于测试静态和动态资源,例如静态文件、Java 小服务程序、CGI 脚本、Java 对象、数据库、FTP 服务器, 等等。JMeter 可以用于对服务器、网络或对象模拟巨大的负载,来自不同压力类别下测试它们的强度和分析整体性能。
另外JMeter能够对应用程序做功能/回归测试,通过创建带有断言的脚本来验证你的程序返回了你期望的结果。
为了最大限度的灵活性,JMeter允许使用正则表达式创建断言。
1)安装Jmetter
Jmetter安装十分简单,下载完整压缩包,解压找到安装目录下bin/jmeter.bat 已管理员身份启动即可
解压以后找到bin目录启动
2) 配置Jmetter
(1)创建新的测试计划
进入界面后已经自动创建了对应的测试计划
(2)测试计划下创建发起请求的线程组
可以配置请求的线程数
以及每个请求发送的请求次数
(3)创建http请求模板
(4)添加结果树
3)测试
(1)设置发送线程数量
运行成功
发送对应的请求
在上述没有运行完的情况下我们在浏览器上访问http://localhost:9002/order/1
我们发现访问时长为将近4秒比之前的访问时间长了不少
4) 上述问题分析
Tomcat会以线程池的形式对所有的请求进行统一的管理,对于某个方法可能存在的耗时的问题的时候,会随着外面挤压的请求越来越多,势必造成整个系统的奔溃。
(2 )系统负载过高存在的问题(解决上述问题)
1) 问题分析
在微服务架构中,我们将业务拆分成一个个的服务,服务与服务之间可以相互调用,由于网络原因或者自身的原因,服务并不能保证服务的100%可用,如果单个服务出现问题,调用这个服务就会出现网络延迟,此时若有大量的网络涌入,会形成任务累计,导致服务瘫痪。
在SpringBoot程序中,默认使用内置tomcat作为web服务器。
单tomcat支持最大的并发请求是有限的,如果某一接口阻塞,待执行的任务积压越来越多,那么势必会影响其他接口的调用。
2)线程池的形式实现服务隔离
为了不影响其他接口的正常访问:对多个服务之间进行隔离
(1) 配置坐标(在order_service
当中)引入hystrix
为了方便实现线以线程池的形式完成资源隔离,需要引入如下依赖
com.netflix.hystrix
hystrix-metrics-event-stream
1.5.12
com.netflix.hystrix
hystrix-javanica
1.5.12
(2) 配置线程池
配置HystrixCommand接口的实现类,再实现类中可以对线程池进行配置,创建OrderCommand类
package cn.itbluebox.order.command;
import cn.itbluebox.order.entity.Product;
import com.netflix.hystrix.*;
import org.springframework.web.client.RestTemplate;
public class OrderCommand extends HystrixCommand {
private RestTemplate restTemplate;
private Long id;
public OrderCommand(RestTemplate restTemplate, Long id) {
super(setter());
this.restTemplate = restTemplate;
this.id = id;
}
private static Setter setter() {
// 服务分组
HystrixCommandGroupKey groupKey = HystrixCommandGroupKey.Factory.asKey(“order_product”);
// 服务标识
HystrixCommandKey commandKey = HystrixCommandKey.Factory.asKey(“product”);
// 线程池名称
HystrixThreadPoolKey threadPoolKey = HystrixThreadPoolKey.Factory.asKey(“order_product_pool”);
/**
-
线程池配置
-
withCoreSize : 线程池大小为10
-
withKeepAliveTimeMinutes: 线程存活时间15秒
-
withQueueSizeRejectionThreshold :队列等待的阈值为100,超过100执行拒绝策略
*/
HystrixThreadPoolProperties.Setter threadPoolProperties = HystrixThreadPoolProperties.Setter().withCoreSize(50)
.withKeepAliveTimeMinutes(15).withQueueSizeRejectionThreshold(100);
// 命令属性配置Hystrix 开启超时
HystrixCommandProperties.Setter commandProperties = HystrixCommandProperties.Setter()
// 采用线程池方式实现服务隔离
.withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.THREAD)
// 禁止
.withExecutionTimeoutEnabled(false);
return Setter.withGroupKey(groupKey).andCommandKey(commandKey).andThreadPoolKey(threadPoolKey)
.andThreadPoolPropertiesDefaults(threadPoolProperties).andCommandPropertiesDefaults(commandProperties);
}
@Override
protected Product run() throws Exception {
System.out.println(Thread.currentThread().getName());
return restTemplate.getForObject(“http://127.0.0.1:9001/product/” + id, Product.class);
}
/**
- 降级方法
*/
@Override
protected Product getFallback() {
Product product = new Product();
product.setProductName(“不好意思,出错了”);
return product;
}
}
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Java)
最后
看完上述知识点如果你深感Java基础不够扎实,或者刷题刷的不够、知识不全面
小编专门为你量身定制了一套<Java一线大厂高岗面试题解析合集:JAVA基础-中级-高级面试+SSM框架+分布式+性能调优+微服务+并发编程+网络+设计模式+数据结构与算法>
针对知识面不够,也莫慌!还有一整套的<Java核心进阶手册>,可以瞬间查漏补缺
全都是一丢一丢的收集整理纯手打出来的
更有纯手绘的各大知识体系大纲,可供梳理:Java筑基、MySQL、Redis、并发编程、Spring、分布式高性能架构知识、微服务架构知识、开源框架知识点等等的xmind手绘图~
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
5%以上Java开发知识点,真正体系化!**
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Java)
[外链图片转存中…(img-EiIHbr8S-1712790897337)]
最后
看完上述知识点如果你深感Java基础不够扎实,或者刷题刷的不够、知识不全面
小编专门为你量身定制了一套<Java一线大厂高岗面试题解析合集:JAVA基础-中级-高级面试+SSM框架+分布式+性能调优+微服务+并发编程+网络+设计模式+数据结构与算法>
[外链图片转存中…(img-fAma2yrX-1712790897337)]
针对知识面不够,也莫慌!还有一整套的<Java核心进阶手册>,可以瞬间查漏补缺
[外链图片转存中…(img-x4CoUgNt-1712790897337)]
全都是一丢一丢的收集整理纯手打出来的
更有纯手绘的各大知识体系大纲,可供梳理:Java筑基、MySQL、Redis、并发编程、Spring、分布式高性能架构知识、微服务架构知识、开源框架知识点等等的xmind手绘图~
[外链图片转存中…(img-cod5nUyH-1712790897337)]
[外链图片转存中…(img-80jM4DFC-1712790897337)]
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
[外链图片转存中…(img-qFOFImYq-1712790897338)]