国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

張開濤:降級特技之配置中心

開發 開發工具
降級開關我們需要通過配置方式來動態開啟/關閉,在應用時,首先要封裝一套應用層API方便業務邏輯使用,對于開關數據的存儲如果涉及的服務器/系統較少,則初期可以考慮使用配置文件配置。

降級開關我們需要通過配置方式來動態開啟/關閉,在應用時,首先要封裝一套應用層API方便業務邏輯使用,對于開關數據的存儲如果涉及的服務器/系統較少,則初期可以考慮使用配置文件配置。如果涉及的服務器/系統較多,則應該使用配置中心進行配置。實現時要做到不需要修改代碼,不需要重啟應用可動態配置開關。

[[188822]]

1. 應用層API封裝

如下是我們抽象并封裝的開關API。

  1. USER( 
  2.     "用戶信息", 
  3.    "user.not.call.backend", "是否不調用后端服務", 
  4.    "user. call.backend.rate.limit", "調用后端服務的限流", 
  5.    "user.redis.expire.seconds", "redis緩存過期時間"), 

里邊涉及到一兩個配置。

  • user.not.call.backend:是否回源調用后端用戶服務。如果不開啟,那么只會訪問緩存,不會將流量打到后端。
  • user.call.backend.ratio:調用后端服務的限流,比如配置100,即一秒只有100個請求會打到后端服務,剩余請求如果緩存沒用命中時,則直接返回空數據或錯誤。
  • user.redis.expire.seconds:后端返回的用戶數據在緩存中緩存多久。

通過封裝后,我們可以很簡單地使用這些API。

  1. if (Switches.USER.notCall()) { 
  2.     retur nnull; 

或者

  1. cacheService.set(CacheKeys.getUserKey(pin), info, Switches.USER.getExpiresInSeconds()); 

API實現是從配置文件獲取相關配置,如果沒有,則返回一個默認值。

  1. public boolean notCall() { 
  2.     return DynamicConfigurer.getBoolean(callKey, false); 

或者

  1. public int getExpiresInSeconds() { 
  2.     return DynamicConfigurer.getInt(expiresKey, DEFAULT_EXPIRES_IN_ SECONDS); 

2. 配置文件實現開關配置

使用properties文件作為配置文件,借助JDK 7 WatchService實現文件變更監聽,實現代碼如下所示。

  1. static { 
  2.     try { 
  3.         filename"application.properties"
  4.         resourcenew ClassPathResource(filename); 
  5.         //監聽filename所在目錄下的文件修改、刪除事件 
  6.        watchService = FileSystems.getDefault().newWatchService(); 
  7.        Paths.get(resource.getFile().getParent()).register(watchService,StandardWatchEventKinds.ENTRY_MODIFY, StandardWatchEventKinds.ENTRY_DELETE); 
  8.         propertiesPropertiesLoaderUtils.loadProperties(resource); 
  9.     } catch(IOException e) {e.printStackTrace();} 
  10.     //啟動一個線程監聽內容變化,并重新載入配置 
  11.     Thread watchThread = new Thread(() -> { 
  12.         while(true) { 
  13.             try{ 
  14.                WatchKey watchKey = watchService.take(); 
  15.                for (WatchEvent<?> event : watchKey.pollEvents()) { 
  16.                    if (Objects.equal(event.context().toString(), filename)){ 
  17.                         properties =PropertiesLoaderUtils.loadProperties (resource); 
  18.                         break; 
  19.                    } 
  20.                } 
  21.                watchKey.reset(); 
  22.             } catch (Exception e){e.printStackTrace();} 
  23.         } 
  24.     }); 
  25.    watchThread.setDaemon(true); 
  26.    watchThread.start(); 
  27.   
  28.     Runtime.getRuntime().addShutdownHook(newThread(() -> { 
  29.         try{ 
  30.             watchService.close(); 
  31.         } catch(IOException e) {e.printStackTrace();} 
  32.     })); 
  33.   
  • 使用WatchService監聽“application.properties”文件所在目錄內容變化,包括修改、刪除事件。
  • 通過后臺線程實現阻塞等待內容變化事件,一旦發現有內容變更,如果是“application.properties”文件發生變更,則重新裝載配置文件。
  • JVM停止時記得關閉WatchService。

整體實現比較簡單,然后就可以封裝Properties實現自己的開關API了。通過配置文件的方式缺點是每次配置文件內容變更需要將配置文件同步到服務器上,這點算是比較麻煩的,如果自動部署系統支持動態更改配置文件并同步用這種方式,那么也并不麻煩。只是如果要維護多個項目時,則需要切換多個界面來操作。

3. 配置中心實現開關配置

統一配置中心,或者叫分布式配置中心,目的是實現配置開關的集中管理,要有配置后臺方便開關的配置,對于一般公司來說配置中心的維護要簡單,不需要投入過多的人力來做這件事情,配置中心不管是采用拉取模式還是推送模式,要考慮到連接數和網絡帶寬可能帶來的風險和問題。目前有一些開源方案可以選擇,如Zookeeper、Diamond、Disconf、Etcd3、Consul。本文選擇了Consul,其支持多數據中心、服務發現、KV存儲等特性,而且使用簡單,提供了簡單的Web UI方便管理,更多介紹可以參考Nginx負載均衡部分。我們借助Consul的KV存儲特性來實現配置管理。

啟動Consul Server

  1. ./consul agent -server -bootstrap-expect 1-data-dir /tmp/consul  -bind 0.0.0.0-client 0.0.0.0  -ui-dir ./ui/ 

HTTP API CRUD

● 新增/修改

  1. curl -X PUT -d 'true'  http://localhost:8500/v1/kv/item_tomcat/user.not.call.backend 
  2. curl -X PUT -d '30'  http://localhost:8500/v1/kv/item_tomcat / user.redis.expire.seconds 

item_tomcat是我們系統名,后邊是我們的配置名,Consul可以通過目錄層次實現多級配置。

● 查詢某個開關

curl

http://localhost:8500/v1/kv/item_tomcat/user.not.call.backend

● 查詢某個系統的開關

curl  

http://localhost:8500/v1/kv/item_tomcat?recurse

通過添加recurse參數實現目錄樹遞歸查詢,可以得到如下結果。

  1. [{"LockIndex":0,"Key":"item_tomcat/user.not.call.backend","Flags":0,"Value":"ZmFsc2U=","CreateIndex":13009,"ModifyIndex":13192},{"LockIndex":0,"Key":"item_tomcat/user.redis.expire.seconds","Flags":0,"Value":"MzA=","CreateIndex":13015,"ModifyIndex":13144}] 

● 阻塞查詢某個系統的開關

  1. curl “http://192.168.61.129:8500/v1/kv/item_tomcat?t=10s&recursetrue&index=13192” 

此處的index取列表ModifyIndex最大值,當其中的修改值大于此index,則返回數據。也可以添加“wait=10s”設置超時時間,超時后阻塞返回。

● 刪除某個開關

curl -X DELETE

http://localhost:8500/v1/kv/item_tomcat/user.not. call. backend

● 刪除某個系統開關

curl -X DELETE

http://localhost:8500/v1/kv/item_tomcat?recurse

整體使用比較簡單,Consul Web UI提供了可視化配置,在啟動時,通過ui-dir指定下載的Web UI目錄即可,配置界面如下圖所示。

通過ui-dir指定下載的Web UI目錄即可

配置界面簡潔,目前存在的一個缺點是沒有配置項的描述功能,在定義配置時,要起一個好理解且清晰的名字。

4. 應用代碼

接下來就需要在應用代碼中引入配置中心了,代碼如下所示。

  1. private static transient Properties properties =null
  2. private static transient String system ="item_tomcat"
  3. static { 
  4.     Consul consul = Consul.builder() 
  5.            .withHostAndPort(HostAndPort.fromString("192.168.61.129:8500")) 
  6.            .withConnectTimeoutMillis(1000) 
  7.            .withReadTimeoutMillis(30 * 1000) 
  8.            .withWriteTimeoutMillis(5000).build(); 
  9.     final KeyValueClient keyValueClient = consul.keyValueClient(); 
  10.     final AtomicBoolean needBreak = new AtomicBoolean(true); 
  11.     Thread thread = new Thread(() -> { 
  12.        BigInteger index = BigInteger.ZERO; 
  13.         while(true){ 
  14.            Properties _properties = new Properties(); 
  15.             try{ 
  16.                //阻塞獲取item_tomcat下的數據(阻塞30秒),index是item_tomcat下的最后修改數據的修改index,為了實現阻塞 
  17.                //此處阻塞時間受readTimeoutMillis影響 
  18.                List<Value> values =keyValueClient.getValues(system, QueryOptions.blockSeconds(30,index).build()); 
  19.                for(Value value : values) { 
  20.                    _properties.put(value.getKey().substring(system.length()+ 1), value. getValueAsString().orNull()); 
  21.                    //獲取最大的一個最后修改index,實現KeyValueClient #getValues的阻塞訪問 
  22.                     indexindex = index.max(BigInteger.valueOf(value.getModifyIndex ())); 
  23.                } 
  24.                properties = _properties
  25.            } catch (ConsulException e) { 
  26.                e.printStackTrace(); 
  27.                if(e.getCode() == 404) { //如果key不存在,休眠下 
  28.                     try { Thread.sleep(5000L); } catch(Exception e1) {} 
  29.                } 
  30.            } 
  31.             if(needBreak.get()== true) {break;} 
  32.         } 
  33.     }); 
  34.    thread.run();//先運行一次 
  35.    needBreak.set(false); 
  36.    thread.setDaemon(true); 
  37.    thread.start(); 

● 在配置Consul時,目前我們使用的IP/PORT,實際應用時建議使用域名/VIP,記得配置相關的超時時間。

● KeyValueClient在獲取數據時使用拉取模式(長輪詢),可以設置合理的阻塞時間(次時間受限于Consul配置的超時時間),選擇最大的ModifyIndex進行阻塞等待。

● 當ConsulException的code=404表示system在配置中心沒有任何配置。

● 在加載該類時先運行一次拉取配置,然后啟動后臺線程阻塞拉取最新配置。

Consul的一個缺點是無法進行增量配置更新,如果訂閱配置的應用很多,那么每次配置更新下發的量就非常大,如果有增量配置更新的話,則只需要把變化的下發即可。

到此集成Consul配置中心就完成了,此處只列出了核心代碼,還有一些異常情況需要大家處理,使得配置中心在應用中做到高可用。

【本文是51CTO專欄作者張開濤的原創文章,作者微信公眾號:開濤的博客( kaitao-1234567)】

戳這里,看該作者更多好文

責任編輯:趙寧寧 來源: 51CTO專欄
相關推薦

2017-06-04 16:24:27

線程線程池中斷

2016-11-28 08:40:17

系統降級服務

2017-05-10 11:40:29

緩存Nginx HTTP

2017-05-01 17:03:01

Java緩存分布式

2017-05-18 16:07:23

回滾數據庫代碼

2017-05-05 10:13:03

應用級緩存緩存代碼

2017-07-02 16:50:21

2017-06-16 15:16:15

2017-04-21 08:51:42

API緩存分布式

2012-12-13 17:38:48

2012年度IT博客大IT博客大賽博客

2016-11-28 08:58:43

系統限流

2016-11-28 08:58:43

系統限流算法

2018-08-01 14:20:11

微服務架構人工智能

2025-03-03 10:27:33

配置中心微服務架構

2009-09-02 09:12:55

Google云計算

2023-06-20 08:10:00

2023-12-21 21:09:47

2017-05-11 13:42:49

JavaScriptJQuery DataDOM

2018-01-08 18:00:12

2022-06-13 09:58:06

NacosSpring
點贊
收藏

51CTO技術棧公眾號

久久综合久久综合久久| 在线电影院国产精品| 精品国产第一页| 国产精品自在线拍| 日韩在线观看免费全集电视剧网站| 免费av在线播放| 色先锋资源久久综合| 性生大片免费观看性| 久久久影视传媒| 欧美女人性生活视频| 成人免费视频免费观看| 色综合电影网| 欧美中文日韩| 日韩欧美精品一区二区三区经典| 亚洲免费婷婷| 欧美久久在线| 精品国产乱码久久久久久久软件| 欧洲毛片在线视频免费观看| 国产精品成人品| 成人一二三区| 成人网欧美在线视频| 日本欧美视频| 91精品在线观看视频| 欧美成人一区二免费视频软件| 国产日韩av高清| 婷婷色综合网| 国产精品9999久久久久仙踪林 | 久久精品国产精品| 久久国产精品高清| 国产二区三区四区| 国产精品福利av| 日本全棵写真视频在线观看| 悠悠色在线精品| 欧美美女搞黄| 日韩欧美一区二区视频| 欧美片第一页| 欧美黄色片视频| 欧美理论在线播放| 99re视频在线| 久久av在线| 黄色a级片免费看| 亚洲国产精品成人综合| 高清色视频在线观看| 欧美图片一区二区三区| 午夜成年人在线免费视频| 日韩精品在线视频| 成人香蕉社区| 草莓视频一区| 精品一区免费av| 黄色国产小视频| 亚洲国产精品一区二区久久恐怖片 | 久久国产综合精品| 人妻夜夜添夜夜无码av| 国产精品麻豆欧美日韩ww| 神马午夜dy888| 欧美日韩国产乱码电影| 国产精品原创| 欧美一级高清免费播放| 欧美日韩国产欧| 成人午夜免费剧场| 亚洲欧洲在线观看av| 好男人免费精品视频| 偷拍欧美精品| 亚洲 国产 日韩 综合一区| 99久久精品免费| 黄视频在线播放| 中文在线不卡视频| 加勒比久久综合| 中文字幕中文字幕在线中一区高清| 国产欧美日韩精品在线| 香蕉视频在线看| 韩日欧美一区二区| 欧美爱爱视频| 成人精品久久一区二区三区| 蜜臀av一区二区| 国产一级粉嫩xxxx| 亚洲国产精品人人爽夜夜爽| 亚洲精品国产九九九| 国产精品日韩二区| 91啦中文在线观看| 欧美精品hd| 久久久亚洲影院你懂的| 一本久道久久综合婷婷鲸鱼| 成人在线看视频| 欧美麻豆精品久久久久久| 国产精伦一区二区三区| 亚洲女人毛片| 色偷偷一区二区三区| 欧美.com| 国产九色精品成人porny | 日韩欧美亚洲另类制服综合在线| 日韩制服一区| yellow视频在线观看一区二区| 国内成人精品2018免费看| 超碰在线一区二区三区| 久久久成人精品| 奇米精品一区二区三区在线观看一| www.aqdy爱情电影网| 色噜噜亚洲精品中文字幕| 老牛嫩草一区二区三区日本| 人人超碰在线| 久久全球大尺度高清视频| 免费观看成人av| 亚洲麻豆精品| 91亚洲va在线va天堂va国 | 日韩精品久久| 日韩福利视频在线| 亚洲欧美激情精品一区二区| 亚洲美女一区| 色网站在线免费观看| 午夜精品理论片| 91影院在线观看| 91久久国产综合久久91猫猫| 蜜桃在线一区二区三区精品| 色综合咪咪久久| 久久99国产精品视频| 欧美黄色一级片视频| 中文欧美日本在线资源| 老司机精品视频导航| 97超碰资源站在线观看| 91传媒免费看| 91高清视频在线| 欧美日韩中文| 番号集在线观看| 成人欧美一区二区| 色吊一区二区三区| 亚洲网站视频| 麻豆传媒在线免费| 日韩wuma| 日韩激情av在线免费观看| 久久99久久精品欧美| 精品丝袜在线| 亚洲成人动漫在线| 中文字幕欧美专区| 成人午夜激情视频| 伊人久久大香| 美日韩精品免费视频| 丁香亚洲综合激情啪啪综合| 亚洲欧洲美洲av| 99中文字幕在线观看| 尤物精品国产第一福利三区| 成人深夜在线观看| 成人免费91| 成人漫画网站免费| 国产成人精品999| 日韩欧美亚洲国产一区| 99成人免费视频| 色在线中文字幕| 国产深夜男女无套内射| 九九九热精品免费视频观看网站| 国产精品久久久久久妇女6080 | 久久久影视精品| 亚洲老司机在线| 久久久久免费av| av在线app| 人妻少妇精品无码专区二区| 欧美大肥婆大肥bbbbb| 亚洲女与黑人做爰| 好看不卡的中文字幕| 国产乱码午夜在线视频 | 91精品国产高清自在线| 亚洲成av人片在线观看无码| 亚洲夜间福利| 偷拍精品精品一区二区三区| av网站在线不卡| 亚洲a级在线观看| 精品国产乱码久久久久久免费 | 欧洲精品中文字幕| 老司机一区二区| 日韩精品中文字幕吗一区二区| 99久热re在线精彩视频| 欧美精品一区二区三区久久| 中文字幕综合一区| 亚洲成人自拍一区| 另类调教123区| 欧美激情影院| 午夜在线小视频| 欧美一级在线看| 国产精品人成电影| 欧美婷婷精品激情| av午夜在线| 高清孕妇孕交╳╳交| 99热久久这里只有精品| 亚洲网友自拍偷拍| 免费亚洲网站| 日韩精品一区国产| 亚洲一区av在线| 538prom精品视频线放| 亚洲精品丝袜日韩| 久久精品男人天堂av| 日韩中文字幕在线免费观看| 国产亚洲精aa在线看| 国产伦子伦对白在线播放观看| 久久青草伊人| 国产欧美日韩视频在线| 麻豆专区一区二区三区四区五区| 成人免费视频在线观看| 日韩精品视频免费专区在线播放| 国产美女精品视频免费观看| 欧美视频在线播放一区|