秒秒pk10官方网站 _Hystrix针对不可用服务的保护机制以及引入缓存

  • 时间:
  • 浏览:3
  • 来源:大鸭梨的博客 - 专注共享TV资源网分享

   完后 我写过一篇博文,通过案例了解Hystrix的各种基本使用土办法,在这篇文章里,我们 我们 我们 我们 是通过Hystrix调用正常工作的服务,也假使 说,Hytrix的保护机制并没办法 起作用,这里我们 我们 我们 我们 将在HystrixProtectDemo.java里演示调用不可用的服务时,hystrix启动保护机制的流程。你你這個 类是基于NormalHystrixDemo.java改写的,假使 在其中增加了getFallback土办法,代码如下。     

1	//省略必要的package和import代码
2	public class HystrixProtectDemo extends HystrixCommand<String> {
3		RestClient client = null;
4		HttpRequest request = null;
5	    //构造函数很這個
6		public HystrixDemoProtectDemo() {
7		super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"));
8		}
9	   //initRestClient土办法没变
10		private void initRestClient(){
11	        //和NormalHystrixDemo.java一样,具体请参考代码
12		}
13		//run土办法也没变
14		protected String run() {
15			//和NormalHystrixDemo.java一样,具体请参考代码
16		}
17	    //这次多个了getFallback土办法,一旦出错,会调用其中的代码
18		protected String getFallback() {
19			//省略跳转到错误提示页面的动作
20			return "Call Unavailable Service.";
21		}
22		//main函数
23		public static void main(String[] args) {
24			HystrixDemoProtectDemo normalDemo = new HystrixDemoProtectDemo();
25			normalDemo.initRestClient();
26			try {
27				Thread.sleep(30);
28			} catch (InterruptedException e) {
29				e.printStackTrace();
30			}           
31			String result = normalDemo.execute();
32			System.out.println("Call available function, result is:" + result);
33		}
34	}

    你你這個 类里的构造函数和NormalHystrixDemo.java很這個,而initRestClient和run土办法根本没变,只是 就不再全版给出了。

    在第18行里,我们 我们 我们 我们 重写了HystrixCommand类的getFallback土办法,在其中定义了一旦访问出错的动作,这里仅仅是输出一段话,在实际的项目里,还还都可以跳转到相应的错误提示页面。

    而main函数里的代码和NormalHystrixDemo.java里的全版一样,假使 ,在运行这段代码前不用运行HystrixServerDemo项目的启动类,另完后 服务一定是调用还还都可以 的。运行本段代码后,我们 我们 我们 我们 能看后如下的结果。  

             In run

             Call available function, result is:Call Unavailable Service.

    从第2行的输出上,我们 我们 我们 我们 能确认,一旦调用服务出错,Hystrix出理 类能自动地调用getFallback土办法。

    原因这里没办法 定义getFallback土办法,没办法 一旦服务不可用,没办法 用户原因在连接超时完后 ,在浏览器里看后一串毫无意义的内容,另完后 用户体验就很差,原因整个系统的其它容错土办法也没到位,甚至都有原因原因当前和下游模块瘫痪。

    相反,在这里原因我们 我们 我们 我们 在hystirx提供的getFallback土办法里做了充分的准备,没办法 一旦老出错误,这段错误出理 的代码能被立即触发,其效果就至少熔断后继的出理 流程。

    由getFallback出面,友好地告知用户老出象了,以及后继该如何出理 ,另完后 一方面能及时熔断请求从而保护整个系统,个人面不用造成因体验过差而用户大规模流失的情况表。

    原因每次请求都有走后台应用多多守护进程 乃至再到数据库检索一下数据,这对服务器的压力太少,有完后 你你這個 因素甚至会成为影响网站服务性能的瓶颈。只是 ,大多数网站会把有些不用实时更新的数据放入缓存,前端请求是到缓存里拿数据。    

    Hystrix在提供保护性便利的一起去,还都可以支持缓存的功能,在下面的HystrixCacheDemo.java里,我们 我们 我们 我们 将演示Hystrix从缓存中读取数据的步骤,代码如下。     

1    //省略必要的package和import代码
2    public class HystrixCacheDemo extends HystrixCommand<String> {
3        //用户id
4        Integer id;
5         //用完后

HashMap来模拟数据库里的数据
6        private HashMap<Integer,String> userList = new HashMap<Integer,String>();
7        //构造函数
8        public HystrixCacheDemo(Integer id) {
9        super(HystrixCommandGroupKey.Factory.asKey("RequestCacheCommand"));        
10            this.id = id;
11            userList.put(1, "Tom");
12        }

    在第3行里,我们 我们 我们 我们 定义了完后 用户id,并在第6行定义了完后 存放用户信息的HashMap。

    在第8行的构造函数里,我们 我们 我们 我们 在第10行里用参数id来初始化了本对象的id属性,并在第11行里,通过put土办法模拟地构建了完后 用户,在项目里,用户的信息虽然 是处于数据库里的。    

13        protected String run() {
14            System.out.println("In run");
15            return userList.get(id);
16        }

    原因不走缓存一段话,第13行定义run函数原因被execute土办法触发,在其中的第15行里,我们 我们 我们 我们 通过get土办法从userList你你這個 HashMap里获得两根用户数据,这里我们 我们 我们 我们 用get土办法来模拟根据id从数据库里获取数据的诸多动作。    

17		protected String getCacheKey() {
18			return String.valueOf(id);
19		}

  第17行定义的getCacheKey土办法是Hystrix实现缓存的关键,在其中我们 我们 我们 我们 还还都可以定义“缓存对象的标准”,具体而言,我们 我们 我们 我们 在这里是返回String.valueOf(id),也假使 说,原因第三个HystrixCacheDemo对象和第完后 对象具有相同的String.valueOf(id)的值,没办法 第三个对象在调用execute土办法时,就还还都可以走缓存。

public static void main(String[] args) {        
21         //初始化上下文,如果无法用缓存机制
22            HystrixRequestContext context = HystrixRequestContext.initializeContext();
23            //定义完后

具有相同id的对象
24            HystrixCacheDemo cacheDemo1 = new HystrixCacheDemo(1);
25            HystrixCacheDemo cacheDemo2 = new HystrixCacheDemo(1);
26            //第完后

对象调用的是run土办法,没办法



走缓存    
27            System.out.println("the result for cacheDemo1 is:" + cacheDemo1.execute());
28            System.out.println("whether get from cache:" + cacheDemo1.isResponseFromCache);
29            //第三个对象,原因和第完后

对象具有相同的id,只是

走缓存    
30            System.out.println("the result for cacheDemo2 is:" + cacheDemo2.execute());
31            System.out.println("whether get from cache:" + cacheDemo2.isResponseFromCache);
32            //销魂上下文,以清空缓存
33            context.shutdown();
34            //再次初始化上下文,但原因缓存已清,只是

cacheDemo3没走缓存
35            context = HystrixRequestContext.initializeContext();
36            HystrixCacheDemo cacheDemo3 = new HystrixCacheDemo(1);
37            System.out.println("the result for 3 is:" + cacheDemo3.execute());
38            System.out.println("whether get from cache:" + cacheDemo3.isResponseFromCache);
39            context.shutdown();

    在第20行的main土办法里,我们 我们 我们 我们 定义了如下的主要逻辑。

    第一,在第22行,通过initializeContext土办法,初始化了上下文,另完后 还都可以启动缓存机制。,在第24和25行里,我们 我们 我们 我们 创建了完后 不同名的,但相同id的HystrixCacheDemo对象。

    第二,在第27行里,我们 我们 我们 我们 通过cacheDemo1对象的execute土办法,根据id查找用户,虽然 我们 我们 我们 我们 在这里是通过run土办法里第15行的get土办法从HashMap里取数据,但我们 我们 我们 我们 还还都可以把这想象成从数据表里取数据。

    第三,在第30行里,我们 我们 我们 我们 调用了cacheDemo2对象的execute土办法,原因它和cacheDemo1对象具有相同的id,只是 这里并没办法 走execute土办法,假使 直接从保存cacheDemo1.execute的缓存里拿数据,这就还还都可以出理 因多次访问数据库而造成了系统损耗。

    第四,我们 我们 我们 我们 在第33行销毁了上下文,并在第35行里重新初始化了上下文,完后 ,虽然 在第36行定义的cacheDemo3对象的id依然是1,但原因上下文对象被重置过,其中的缓存也被清空,只是 在第37里执行的execute土办法并没办法 走缓存。

    运行上述代码,我们 我们 我们 我们 能看后如下的输出,你你這個 打印结果能很好地验证上述对主要流程的说明。    

1    In run
2    the result for cacheDemo1 is:Tom
3    whether get from cache:false
4    the result for cacheDemo2 is:Tom
5    whether get from cache:true
6    In run
7    the result for 3 is:Tom

    这里请我们 我们 我们 我们 注意,在缓存相关的getCacheKey土办法里,我们 我们 我们 我们 都有定义“保存缓存值”的逻辑,假使 定义“缓存对象的标准”,初学者经常 会混淆这点。具体而言,在这里的getCacheKey土办法里,我们 我们 我们 我们 并没办法 保存id是1的User对象的值(这里是Tom),假使 定义了如下的标准:假使 完后 (或多个)HystrixCacheDemo对象具有相同的String.valueOf(id)的值,如果缓存中也原因存有id的1的结果值,没办法 后继对象则还还都可以直接从缓存里读数据。

    在上文里,我们 我们 我们 我们 演示了通过Hystrix调用可用以及不可用服务的运行结果,并在调用过程中引入了缓存机制,这里,我们 我们 我们 我们 将在上述案例的基础上归纳Hystrix的一般工作流程。

    第一,我们 我们 我们 我们 还还都可以通过extends HystrixCommand<T>的土办法,让完后 类具备Hystrix保护机制的行态,其中T是泛型,在上述案例中我们 我们 我们 我们 用到的是String。

    第二,一旦继承了HystrixCommand完后 ,我们 我们 我们 我们 就还还都可以通过重写run土办法和getFallback土办法来定义调用“可用”和“不可用”服务的业务功能代码,其中,这完后 土办法的返回值时需和第一步里定义的泛型T一致。而在项目里,我们 我们 我们 我们 一般在getFallback土办法里,定义“服务不可用”时的保护土办法(也假使 后文里将要提到的降级土办法)。

    第三,我们 我们 我们 我们 还还还都可以通过缓存机制来降低并发情况表下对服务器的压力,在Hystrix里,我们 我们 我们 我们 还还都可以在getCacheKey里定义“判断还还都可以走缓存对象的标准”。

    在使用缓存是,请注意两点,第一时需开启上下文,第二,Hystrix会根据定义在类里的属性判断多次调用的对象不是同完后 ,原因是,如果完后 被调用过,则还还都可以走缓存。

    本文谢绝转载。