借鉴地址:https://blog.csdn.net/loushuiyifan/article/details/82702522
1.资源隔离:
(信号量隔离)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | public class QueryByOrderIdCommandSemaphore extends HystrixCommand<Integer> { private final static Logger logger = LoggerFactory.getLogger(QueryByOrderIdCommandSemaphore. class ); private OrderServiceProvider orderServiceProvider; public QueryByOrderIdCommandSemaphore(OrderServiceProvider orderServiceProvider) { super (Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey( "orderService" )) .andCommandKey(HystrixCommandKey.Factory.asKey( "queryByOrderId" )) .andCommandPropertiesDefaults(HystrixCommandProperties.Setter() .withCircuitBreakerRequestVolumeThreshold( 10 )至少有 10 个请求,熔断器才进行错误率的计算 .withCircuitBreakerSleepWindowInMilliseconds( 5000 ) //熔断器中断请求5秒后会进入半打开状态,放部分流量过去重试 .withCircuitBreakerErrorThresholdPercentage( 50 ) //错误率达到50开启熔断保护 .withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.SEMAPHORE) .withExecutionIsolationSemaphoreMaxConcurrentRequests( 10 ))); //最大并发请求量 this .orderServiceProvider = orderServiceProvider; } @Override protected Integer run() { return orderServiceProvider.queryByOrderId(); } @Override protected Integer getFallback() { return - 1 ; } } |
第二步,调用HystrixCommand的执行方法发起实际请求。
1 2 3 4 5 | @Test public void testQueryByOrderIdCommand() { Integer r = new QueryOrderIdCommand(orderServiceProvider).execute(); logger.info( "result:{}" , r); } |
执行命令的几种方法
Hystrix提供了4种执行命令的方法,execute()和queue() 适用于HystrixCommand对象,而observe()和toObservable()适用于HystrixObservableCommand对象。
execute()
以同步堵塞方式执行run(),只支持接收一个值对象。hystrix会从线程池中取一个线程来执行run(),并等待返回值。
queue()
以异步非阻塞方式执行run(),只支持接收一个值对象。调用queue()就直接返回一个Future对象。可通过 Future.get()拿到run()的返回结果,但Future.get()是阻塞执行的。若执行成功,Future.get()返回单个返回值。当执行失败时,如果没有重写fallback,Future.get()抛出异常。
observe()
事件注册前执行run()/construct(),支持接收多个值对象,取决于发射源。调用observe()会返回一个hot Observable,也就是说,调用observe()自动触发执行run()/construct(),无论是否存在订阅者。
如果继承的是HystrixCommand,hystrix会从线程池中取一个线程以非阻塞方式执行run();如果继承的是HystrixObservableCommand,将以调用线程阻塞执行construct()。
observe()使用方法:
- 调用observe()会返回一个Observable对象
- 调用这个Observable对象的subscribe()方法完成事件注册,从而获取结果
toObservable()
事件注册后执行run()/construct(),支持接收多个值对象,取决于发射源。调用toObservable()会返回一个cold Observable,也就是说,调用toObservable()不会立即触发执行run()/construct(),必须有订阅者订阅Observable时才会执行。
如果继承的是HystrixCommand,hystrix会从线程池中取一个线程以非阻塞方式执行run(),调用线程不必等待run();如果继承的是HystrixObservableCommand,将以调用线程堵塞执行construct(),调用线程需等待construct()执行完才能继续往下走。
toObservable()使用方法:
- 调用observe()会返回一个Observable对象
- 调用这个Observable对象的subscribe()方法完成事件注册,从而获取结果
需注意的是,HystrixCommand也支持toObservable()和observe(),但是即使将HystrixCommand转换成Observable,它也只能发射一个值对象。只有HystrixObservableCommand才支持发射多个值对象。
几种方法的关系
- execute()实际是调用了queue().get()
- queue()实际调用了toObservable().toBlocking().toFuture()
- observe()实际调用toObservable()获得一个cold Observable,再创建一个ReplaySubject对象订阅Observable,将源Observable转化为hot Observable。因此调用observe()会自动触发执行run()/construct()。
Hystrix总是以Observable的形式作为响应返回,不同执行命令的方法只是进行了相应的转换。
线程池隔离
1 2 3 4 5 | final static ConcurrentHashMap<String, HystrixThreadPool> threadPools = new ConcurrentHashMap<String, HystrixThreadPool>(); ... if (!threadPools.containsKey(key)) { threadPools.put(key, new HystrixThreadPoolDefault(threadPoolKey, propertiesBuilder)); } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具