当大多数人在使用Tomcat时,多个HTTP服务会共享一个线程池,假设其中一个HTTP服务访问的数据库响应非常慢,这将造成服务响应时间延迟增加,大多数线程阻塞等待数据响应返回,导致整个Tomcat线程池都被该服务占用,甚至拖垮整个Tomcat。因此,如果我们能把不同HTTP服务隔离到不同的线程池,则某个HTTP服务的线程池满了也不会对其他服务造成灾难性故障。这就需要线程隔离或者信号量隔离来实现了。

使用线程隔离或信号隔离的目的是为不同的服务分配一定的资源,当自己的资源用完,直接返回失败而不是占用别人的资源。

Hystrix实现服务隔离两种方案

Hystrix的资源隔离策略有两种,分别为:线程池和信号量。

线程池方式

1、 使用线程池隔离可以完全隔离第三方应用,请求线程可以快速放回。 2、 请求线程可以继续接受新的请求,如果出现问题线程池隔离是独立的不会影响其他应用。 
3、 当失败的应用再次变得可用时,线程池将清理并可立即恢复,而不需要一个长时间的恢复。 
4、 独立的线程池提高了并发性

缺点: 
线程池隔离的主要缺点是它们增加计算开销(CPU)。每个命令的执行涉及到排队、调度和上 下文切换都是在一个单独的线程上运行的。

每个服务接口都有自己独立的线程池,管理运行当前自己的接口。但是cpu开销比较大

在同一个线程池中,素有请求全部到一个服务进行访问,这时候会导致其他服服务没有线程接收请求访问,所以就会产生服务雪崩效应

Member:

pom:

<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"><modelVersion>4.0.0</modelVersion><groupId>com.itmayeidu</groupId><artifactId>member</artifactId><version>0.0.1-SNAPSHOT</version><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.0.0.RELEASE</version></parent><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient --><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId></dependency><!-- https://mvnrepository.com/artifact/com.alibaba/fastjson --><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.47</version></dependency></dependencies>
</project>

  controller

package com.toov5.controller;import java.util.HashMap;
import java.util.Map;import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/member")
public class MemberController {@RequestMapping("/memberIndex")public Object memberIndex() throws InterruptedException {Map<String, Object> hashMap = new HashMap<String, Object>();hashMap.put("code", 200);hashMap.put("msg", "memberIndex");Thread.sleep(1500);return hashMap;}}

启动类

package com.toov5.controller;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class AppMember {public static void main(String[] args) {SpringApplication.run(AppMember.class, args);}}

yml:

server:port: 8081

  

Order

pom

<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"><modelVersion>4.0.0</modelVersion><groupId>com.itmayeidu</groupId><artifactId>order</artifactId><version>0.0.1-SNAPSHOT</version><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.0.0.RELEASE</version></parent><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient --><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId></dependency><!-- https://mvnrepository.com/artifact/com.alibaba/fastjson --><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.47</version></dependency><dependency><groupId>com.netflix.hystrix</groupId><artifactId>hystrix-metrics-event-stream</artifactId><version>1.5.12</version></dependency><dependency><groupId>com.netflix.hystrix</groupId><artifactId>hystrix-javanica</artifactId><version>1.5.12</version></dependency></dependencies></project>

 controller

 

package com.toov5.controller;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import com.alibaba.fastjson.JSONObject;
import com.toov5.hystrix.OrderHystrixCommand;
import com.toov5.hystrix.OrderHystrixCommand2;
import com.toov5.service.MemberService;@RestController
@RequestMapping("/order")
public class OrderController {@Autowiredprivate MemberService memberService;@RequestMapping("/orderIndex")public Object orderIndex() throws InterruptedException {JSONObject member = memberService.getMember(); //返回值与OrderHystrixCommand中的泛型对应System.out.println("当前线程名称:" + Thread.currentThread().getName() + ",订单服务调用会员服务:member:" + member);return member;}// 已经理解@RequestMapping("/orderIndexHystrix")public Object orderIndexHystrix() throws InterruptedException {return new OrderHystrixCommand(memberService).execute();}@RequestMapping("/findOrderIndex")public Object findIndex() {System.out.println("当前线程:" + Thread.currentThread().getName() + ",findOrderIndex");return "findOrderIndex";}
}

service

package com.toov5.service;import org.springframework.stereotype.Service;import com.alibaba.fastjson.JSONObject;
import com.toov5.utils.HttpClientUtils;@Service
public class MemberService {public JSONObject getMember() {JSONObject result = HttpClientUtils.httpGet("http://127.0.0.1:8081/member/memberIndex");return result;}}

utils

package com.toov5.utils;import com.alibaba.fastjson.JSONObject;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.io.IOException;/*** HttpClient4.3工具类* * @author hang.luo*/
public class HttpClientUtils {private static Logger logger = LoggerFactory.getLogger(HttpClientUtils.class); // 日志记录private static RequestConfig requestConfig = null;static {// 设置请求和传输超时时间requestConfig = RequestConfig.custom().setSocketTimeout(2000).setConnectTimeout(2000).build();}/*** post请求传输json参数* * @param url*            url地址* @param json*            参数* @return*/public static JSONObject httpPost(String url, JSONObject jsonParam) {// post请求返回结果CloseableHttpClient httpClient = HttpClients.createDefault();JSONObject jsonResult = null;HttpPost httpPost = new HttpPost(url);// 设置请求和传输超时时间
        httpPost.setConfig(requestConfig);try {if (null != jsonParam) {// 解决中文乱码问题StringEntity entity = new StringEntity(jsonParam.toString(), "utf-8");entity.setContentEncoding("UTF-8");entity.setContentType("application/json");httpPost.setEntity(entity);}CloseableHttpResponse result = httpClient.execute(httpPost);// 请求发送成功,并得到响应if (result.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {String str = "";try {// 读取服务器返回过来的json字符串数据str = EntityUtils.toString(result.getEntity(), "utf-8");// 把json字符串转换成json对象jsonResult = JSONObject.parseObject(str);} catch (Exception e) {logger.error("post请求提交失败:" + url, e);}}} catch (IOException e) {logger.error("post请求提交失败:" + url, e);} finally {httpPost.releaseConnection();}return jsonResult;}/*** post请求传输String参数 例如:name=Jack&sex=1&type=2* Content-type:application/x-www-form-urlencoded* * @param url*            url地址* @param strParam*            参数* @return*/public static JSONObject httpPost(String url, String strParam) {// post请求返回结果CloseableHttpClient httpClient = HttpClients.createDefault();JSONObject jsonResult = null;HttpPost httpPost = new HttpPost(url);httpPost.setConfig(requestConfig);try {if (null != strParam) {// 解决中文乱码问题StringEntity entity = new StringEntity(strParam, "utf-8");entity.setContentEncoding("UTF-8");entity.setContentType("application/x-www-form-urlencoded");httpPost.setEntity(entity);}CloseableHttpResponse result = httpClient.execute(httpPost);// 请求发送成功,并得到响应if (result.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {String str = "";try {// 读取服务器返回过来的json字符串数据str = EntityUtils.toString(result.getEntity(), "utf-8");// 把json字符串转换成json对象jsonResult = JSONObject.parseObject(str);} catch (Exception e) {logger.error("post请求提交失败:" + url, e);}}} catch (IOException e) {logger.error("post请求提交失败:" + url, e);} finally {httpPost.releaseConnection();}return jsonResult;}/*** 发送get请求* * @param url*            路径* @return*/public static JSONObject httpGet(String url) {// get请求返回结果JSONObject jsonResult = null;CloseableHttpClient client = HttpClients.createDefault();// 发送get请求HttpGet request = new HttpGet(url);request.setConfig(requestConfig);try {CloseableHttpResponse response = client.execute(request);// 请求发送成功,并得到响应if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {// 读取服务器返回过来的json字符串数据HttpEntity entity = response.getEntity();String strResult = EntityUtils.toString(entity, "utf-8");// 把json字符串转换成json对象jsonResult = JSONObject.parseObject(strResult);} else {logger.error("get请求提交失败:" + url);}} catch (IOException e) {logger.error("get请求提交失败:" + url, e);} finally {request.releaseConnection();}return jsonResult;}}

Hystrix:

package com.toov5.hystrix;import org.springframework.beans.factory.annotation.Autowired;import com.alibaba.fastjson.JSONObject;
import com.netflix.hystrix.HystrixCommand;
import com.netflix.hystrix.HystrixCommandGroupKey;
import com.netflix.hystrix.HystrixCommandKey;
import com.netflix.hystrix.HystrixCommandProperties;
import com.netflix.hystrix.HystrixThreadPoolKey;
import com.netflix.hystrix.HystrixThreadPoolProperties;
import com.toov5.service.MemberService;@SuppressWarnings("rawtypes")
public class OrderHystrixCommand extends HystrixCommand<JSONObject> {@Autowiredprivate MemberService memberService;/*** @param group*/public OrderHystrixCommand(MemberService memberService) {super(setter());  //隔离this.memberService = memberService;}//表示服务执行的代码protected JSONObject run() throws Exception {JSONObject member = memberService.getMember();System.out.println("当前线程名称:" + Thread.currentThread().getName() + ",订单服务调用会员服务:member:" + member);return member;}private static Setter setter() {// 服务分组  相同的会员是一组HystrixCommandGroupKey groupKey = HystrixCommandGroupKey.Factory.asKey("members");// 服务标识HystrixCommandKey commandKey = HystrixCommandKey.Factory.asKey("member");// 线程池名称HystrixThreadPoolKey threadPoolKey = HystrixThreadPoolKey.Factory.asKey("member-pool");// 线程池配置 线程池大小为10,线程存活时间15秒 队列等待的阈值为100,超过100执行拒绝策略HystrixThreadPoolProperties.Setter threadPoolProperties = HystrixThreadPoolProperties.Setter().withCoreSize(10).withKeepAliveTimeMinutes(15).withQueueSizeRejectionThreshold(100);// 命令属性配置Hystrix 开启超时HystrixCommandProperties.Setter commandProperties = HystrixCommandProperties.Setter()// 采用线程池方式实现服务隔离
                .withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.THREAD)// 禁止.withExecutionTimeoutEnabled(true);return HystrixCommand.Setter.withGroupKey(groupKey).andCommandKey(commandKey).andThreadPoolKey(threadPoolKey).andThreadPoolPropertiesDefaults(threadPoolProperties).andCommandPropertiesDefaults(commandProperties);}@Override    //降级protected JSONObject getFallback() {// 如果Hystrix发生熔断,当前服务不可用,直接执行Fallback方法System.out.println("系统错误!");JSONObject jsonObject = new JSONObject();jsonObject.put("code", 500);jsonObject.put("msg", "系统错误!");return jsonObject;}
}

启动类:

package com.toov5;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class AppOrder {public static void main(String[] args) {SpringApplication.run(AppOrder.class, args);}}

yml:

server:port: 8080tomcat:max-threads: 20

  

效果:

可以看到(开启超时),不同的线程池,服务隔离,服务降级。

转载于:https://www.cnblogs.com/toov5/p/9986857.html

互联网高并发之Hystrix实现服务隔离和降级相关推荐

  1. Hystrix实现服务隔离和降级

    背景 在分布式环境下,服务之间有大量的依赖,单个依赖故障时的容灾是个很重要的话题. 伴随着业务复杂性的提高,系统的不断拆分,一个面向用户端的API,其内部的RPC调用层层嵌套,调用链条可能会非常长.这 ...

  2. 服务的隔离、降级和熔断

    [尚学堂]Java300集零基础适合初学者视频教程_Java300集零基础教程_Java初学入门视频基础巩固教程_Java语言入门到精通_哔哩哔哩_bilibili 1.服务隔离.降级和熔断的产生背景 ...

  3. 07蚂蚁-高并发解决方案——1.Hystrix服务降级,服务隔离,服务熔断,服务限流,CDN

    高并发服务降级特技 背景 在今天,基于SOA的架构已经大行其道.伴随着架构的SOA化,相关联的服务熔断.降级.限流等思想,也在各种技术讲座中频繁出现.本文将结合Netflix开源的Hystrix框架, ...

  4. 高并发之服务降级和服务熔断____服务降级、熔断、限流的区别

    高并发之服务降级和服务熔断 服务降级: 服务压力剧增的时候根据当前的业务情况及流量对一些服务和页面有策略的降级,以此环节服务器的压力,以保证核心任务的进行. 同时保证部分甚至大部分任务客户能得到正确的 ...

  5. 互联网高并发解决方案(2)--高并发服务限流特技

    RPC和本地JAVA调用的区别 RPC远程调用:一般是可以跨平台使用的,采用Socket技术,只要语言支持socket技术就可以进行互相通信.其实就是socket+反射实现的. 本地调用:只能支持Ja ...

  6. SpringCloud Hystrix微服务架构的高并发问题与解决策略

    一.微服务架构的高并发问题 背景:由于服务器的最大处理线程数都是有上线的,比如tomcat等.当系统某时刻出现高并发请求时,如秒杀活动等,在瞬间服务器可处理线程数瞬间使用完,线程资源耗尽.当后面的其他 ...

  7. dubbo+rabbitmq+hystrix实现服务的高可用

    实际业务中,我们总希望我们的系统能够尽可能做到高可用,容错性强,系统内部在服务的调用链路上,可控制性更好,这样一旦系统一旦出现问题,容易追踪问题的来源,尤其是在分布式开发,微服务化越来越流行的今天,如 ...

  8. 服务熔断、降级、限流、异步RPC -- HyStrix

    本人新书出版,对技术感兴趣的朋友请关注: https://mp.weixin.qq.com/s/uq2cw2Lgf-s4nPHJ4WH4aw 在今天,基于SOA的架构已经大行其道.伴随着架构的SOA化 ...

  9. 云漫圈 | 谈谈怎么做【服务隔离】

    戳蓝字"CSDN云计算"关注我们哦! 转自:  孤独烟 引言 OK,如下图所示 那显而易见,做服务隔离的目的就是避免服务之间相互影响.毕竟谁也不能说自己的微服务百分百可用,如果不做 ...

最新文章

  1. 如何克服实施OKR的阻力?
  2. Windows XP Embedded 上手指南
  3. java增加缓存,java – 如何增加Integer对象的缓存大小
  4. 阿里P8亲自讲解!java中级开发工程师需要掌握的技能
  5. android动态开发,android开发实现动态壁纸
  6. IPv6下网络编程实例
  7. java调用javascript函数_使用Java程序中的参数调用Javascript函数
  8. 禁止i5笔记本按Ctrl+Alt+向下键翻转屏幕
  9. centos 分区
  10. python-字典和json
  11. ArcGIS属性字段名设置不超过四个中文的解决方法
  12. 山石网科-Hillstone-L2TP-***之配置终结篇
  13. 浦发银行计算机基础知识题库,2018浦发银行面试经验(信息科技岗,总行信息技术岗等)...
  14. 前端培训,达内黑马、丁鹿学堂、北大青鸟?
  15. win8计算机里没有用户名和密码错误,win8电脑其他用户的用户名和密码肿么弄?
  16. 查询 JetsonNano I2C 的工作频率(波特率)
  17. python中apply函数
  18. 浏览器提示“此网站的安全证书有问题“,你还敢继续访问吗?
  19. 自动驾驶 Automotive SPICE(ISO/IEC 15504) 和CMMI有什么不同?
  20. 清华教授的操作系统-----课程笔记

热门文章

  1. 腾讯云mysql升级失败怎么办_本地连接腾讯云Mysql失败问题
  2. 怎么查看页面跳转过程_fastcapture注册码怎么获取?FastStone注册码分享
  3. oracle 改变受限模式,oracle之受限模式修改
  4. 辐射4核能选项用计算机失败,gg修改器出现保护进程加载失败怎么解决 | 手游网游页游攻略大全...
  5. ctfshow-萌新-web9( 利用命令执行漏洞读取网站敏感文件)
  6. SQLi LABS Less-13 报错注入+布尔盲注
  7. python 怎么样去txt中提取xml_Python根据XML批量创建TXT并提取信息,python,xml,txt
  8. sqlserver聚合索引(clustered index) / 非聚合索引(nonclustered index)的理解
  9. 使用entityframework操作sqlite数据库
  10. Elasticsearch 2.3.0 重建索引