註冊中心宕機,還能夠消費dubbo暴露的服務html
繞開註冊中心直連服務提供者java
@Reference(url="127.0.0.1:20888") // dubbo的註解 UserService userService; public List<UserAddress> initOrder(String userId) { return userService.getUserAddressList("1"); }
同一種服務提供者存在多份時須要負載均衡策略, loadbalancenode
隨機負載均衡, 按照權重設置隨機機率,隨機調用量越大,分佈越均勻,有利於動態調整提供者的權重spring
例: UserService一共三臺,咱們根據實際的機器性能給這三個機器添加不一樣的權重數據庫
userService1 weight=100 userService2 weight=200 userService3 weight=300
這樣這三臺機器被隨機調用到的比例就是1:2:3緩存
這是Dubbo默認的負載均衡機制安全
@SPI("random") public interface LoadBalance { @Adaptive({"loadbalance"}) <T> Invoker<T> select(List<Invoker<T>> var1, URL var2, Invocation var3) throws RpcException; }
假如一樣存在三臺相同的服務提供者, 不設置權重的話,消費者的會被均勻的按瞬間分發到這個三臺機器上123123123...服務器
輪詢, 按照公約後的權重值,設置查詢比率 , 存在慢的提供者請求累積的問題, 這種方式的訪問順序也是提早就知道的,只不過添加上了權重的以後的順序, 原來的123123... 可能變成了 123333併發
最少活躍調用數, 活躍數指的是調用先後的計時差,使慢的提供者接受更少的請求app
當用戶的請求會先查詢服務提供者列表中,而後選擇活躍數最低的,也就是上次響應時間最短的機器
一致性Hash, 使相同參數的請求老是發到同一個提供者上,當某一臺提供者掛掉時,本來該發送到這個服務提供者的請求會平攤到其餘提供者身上,不會產生巨大的動盪
<dubbo:parameter key="hash.arguments" value="0,1" />
<dubbo:parameter key="hash.nodes" value="320" />
服務端服務級別 <dubbo:service interface="..." loadbalance="roundrobin" /> 客戶端服務級別 <dubbo:reference interface="..." loadbalance="roundrobin" /> 服務端方法級別 <dubbo:service interface="..."> <dubbo:method name="..." loadbalance="roundrobin"/> </dubbo:service> 客戶端方法級別 <dubbo:reference interface="..."> <dubbo:method name="..." loadbalance="roundrobin"/> </dubbo:reference>
@Reference(loadbalance = "random") @Reference(loadbalance = "roundrobin") @Reference(loadbalance = "leastactive") @Reference(loadbalance = "consistenthash")
在暴露服務是,在@Service註解上邊添加 weight屬性 @Service(weight="200")
在服務器壓力劇增的狀況下,根據實際的業務狀況及流量,對一些服務和頁面進行有策略的不處理或者換種簡單方式處理的方式, 從而達到釋放系統資源,維持系統核心功能的正常運做
實現: 向註冊中心寫入動態配置規則
RegistryFactory registryFactory = ExtensionLoader.getExtensionLoader(RegistryFactory.class).getAdaptiveExtension(); Registry registry = registryFactory.getRegistry(URL.valueOf("zookeeper://10.20.153.10:2181")); registry.register(URL.valueOf("override://0.0.0.0/com.foo.BarService?category=configurators&dynamic=false&application=foo&mock=force:return+null"));
上面配置的最後一條URL上,mock=force:return+null
,表示在服務消費者層面直接對用戶的調用返回空,不行轉發處理
最後的url位置還能夠寫成mock=fail:return+null
,表示消費者在對服務的調用方法失敗後才返回null,用來緩衝服務調用不穩定時,對服務調用方的影響 ``
如圖在控制檯進行可視化界面消費者模塊實現服務降級
服務在調用失敗時,Dubbo提供了不少種容錯方案
failover cluster 失敗自動切換,當出現失敗,重試其它服務器,但重試會帶來更長延遲。可經過 retries="2" 來設置重試次數(不含第一次)。
重試次數配置以下: <dubbo:service retries="2" /> 或 <dubbo:reference retries="2" /> 或 <dubbo:reference> <dubbo:method name="findFoo" retries="2" /> </dubbo:reference>
Failfast Cluster 快速失敗,只發起一次調用,失敗當即報錯。一般用於非冪等性的寫操做,好比新增記錄。
Failsafe Cluster 失敗安全,出現異常時,直接忽略。一般用於寫入審計日誌等操做。
Failback Cluster 失敗自動恢復,後臺記錄失敗請求,定時重發。一般用於消息通知操做。
Forking Cluster 並行調用多個服務器,只要一個成功即返回。一般用於實時性要求較高的讀操做,但須要浪費更多服務資源。可經過 forks="2" 來設置最大並行數。
Broadcast Cluster 廣播調用全部提供者,逐個調用,任意一臺報錯則報錯 [2]。一般用於通知全部提供者更新緩存或日誌等本地資源信息。
按照如下示例在服務提供方和消費方配置集羣模式 <dubbo:service cluster="failsafe" /> 或 <dubbo:reference cluster="failsafe" />
hystrix 旨在經過控制遠程系統,服務和第三方的節點,從而對延遲和故障提供更強大的容錯能力,Hystrix同時具有回退機制和斷路器能力功能的線程和信號隔離,請求緩存,請求打包已經監控和配置的功能
hytrix的隔離策略有兩種:
Hystrix默認的保護級別是THREAD,它出來超時保護還有額外的保護,通常當系統的負載特別大,每秒幾百併發時,才選擇信號量隔離,正常狀況下使用默認的隔離級別
可使用execution.isolation.strategy屬性指定隔離策略。
@HystrixCommand(fallbackMethod = "notfindback", commandProperties=@HystrixProperty(name="execution.isolation.strategy", value="SEMAPHORE") ) public User findById( Long id) public User notfindback(Long id) { User user = new User(); user.setId(0L); return user; }
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> <version>2.0.1.RELEASE</version> </dependency>
@EnableDubbo @EnableHystrix @SpringBootApplication public class ProviderApp { public static void main(String[] args) { SpringApplication.run(ProviderApp.class); } }
@Component @Service //使用dubbo的Service 對外保留服務 public class UserServiceImpl implements UserService { // 添加這個註解,將當期方法,交給Hystrix進行代理,當出現異常時,進行容錯處理 @HystrixCommand public List<UserAddress> getUserAddressList(String userId) { UserAddress a1= new UserAddress(1,"張三","北京市朝陽區"); UserAddress a2= new UserAddress(2,"李四","山東濟南"); if (Math.random()>0.5){ throw new RuntimeException(); } return Arrays.asList(a1,a2); } }
public class UserServiceImpl implements UserService{ // 注入這個被服務提供者支持的接口 @Reference private final UserService userService; // 提供構造函數 public UserServiceImpl(UserService userService) { this.userService = userService; } @Override @HystrixCommand(fallbackMethod = "correct") // 當出現錯誤時,回調correct方法 public List<UserAddress> getUserAddressList(String userId) { // 判空 if (!StringUtils.isEmpty(userId)){ System.err.println(); return userService.getUserAddressList(userId); } return null; } public List<UserAddress> correct(String userId) { return Collections.singletonList(new UserAddress(9, "correct", "correct")); } }
原文出處:https://www.cnblogs.com/ZhuChangwu/p/11569660.html