java-微服務相關面試題

三.微服務部分

相關概念

什么是集群

集群使將應用復制成多個相同的應用,一起來工作,從而提高工作能力。即將多個應用程序分散在不同的服務器,每個服務器都獨立運行相同的代碼。可以分散服務器壓力解決高并發的問題,同時也能預防單節點故障,即一臺服務器故障不影響其他服務器正常運行,但沒有解決單體應用代碼臃腫,業務復雜,維護性差等等問題

什么是負載均衡

使用了集群后,解決高并發同時有一個新的問題,就是客戶端的請求如何分配到多臺服務。因此需要通過負載均衡器,比如Nginx,使用負載均衡算法比如輪詢、權重、隨機等等將請求路由到不同的服務器

什么是分布式

分布式是將應用按照業務類型拆分成多個子應用,每個子應用部署在不同的服務器上單獨運行,子應用之間通過API相互調用。

可以分散服務器壓力解決高并發問題,同時可以解決單體應用代碼臃腫、業務復雜、維護性差等等問題,但是不能防止單節點故障,比如一個子應用故障,整個應用就能不完整運行

集群和分布式的區別,分別解決什么問題

集群是將一個應用程序復制多份,部署在多臺服務器上,每個服務器中的程序都是完整的,可以獨立運行

分布式是將一個應用程序拆分成多個子程序,分別部署在多臺服務器上,每個服務器中的程序都是不完整的,所有服務器需要相互通信相互協調才能完成最終的業務

集群能解決高并發問題,同時能防止單節點故障,即一臺服務器宕機不影響其他服務器的正常運行

分布式也能解決高并發問題,但不能防止單節點故障,即一臺服務器宕機了,整體業務就無法完成

集群無法解決項目本身的代碼臃腫、業務復雜等等問題,分布式能降低模塊之間的耦合

實際應用中,我們可以將分布式和集群相結合,比如分布式某個子程序的負載很高,可以單獨對這個子程序做集群

說一下你理解的微服務

微服務也是一個分布式系統,它將單體應用進行細粒度拆分,形成多個微服務,每個服務獨立運行,每個服務也都可以有自己的數據庫,服務之間使用HTTP通信,互相協調完成整個系統的業務。

它的優點是服務之間解耦合,不同的服務可以有不同的編程語言,技術選型多元化,支持敏捷開發

他的缺點是分布式事務很復雜,部署麻煩,技術成本高,服務間通信對性能也有一定的損耗

什么是CAP理論 , 哪些技術用到AP,哪些用到CP

CAP理論指的是,在一個分布式系統中,一致性,可用性,分區容錯性,三個要素最多只能同時實現兩點。

分區容錯性是分布式系統的內在要求,因此我們通常會在一致性和可用性之間做取舍。

滿足CP,也就是滿足一致性和容錯性,舍棄可用性,如果系統允許有段時間失效就可以考慮。常見的如Redis,Nacos,ZooKeeper

滿足AP,也就是滿足可用性和容錯性,舍棄一致性,如果系統允許出現短暫時間的不一致可以考慮。常見的如MySQL,Eureka

什么是強一致性和最終一致性

強一致性是只數據在多個副本中總數實時同步的,如果能容忍數據在多個副本中在一定的延遲時間內同步,則是弱一致性

最終一致性則不要求數據什么時候同步,但是最終會同步即可。通常情況下我們在分布式領域選擇會犧牲了強一致性,會采用最終一致性

什么是Base理論

Base指的是基本可用,軟狀態,最終一致性。它是對CAP中的AP的擴展,意思是說當出現故障部分服務不可用時,要保證核心功能可用,允許在一段時間內數據不一致,但最終要保證一致性。滿足Base理論的事務也叫柔性事務

SpringCloud

講一下你們公司微服務解決方案

我司正在使用的是第一代微服務方案,Springcloud Netflix全家桶。

它是使用Eureka做服務注冊與發現,也就是解決服務之間通信問題,

使用Ribbon/OpenFeign做客戶端的負載均衡,也就是解決將請求路由到微服務集群的問題,

使用Hystrix斷路器的熔斷、降級來解決單節點故障,

使用Zuul做服務網關,將它作為整個微服務的大門,來實現登錄、權限檢查等業務,

使用Config分布式配置中心,來統一管理配置所有微服務的配置文件,

使用Bus消息總線給各個微服務廣播消息,可以實現各個微服務配置的自動刷新,

使用Sleuth鏈路追蹤,來實時監控各個微服務建的調用關系,快速定位故障節點

說一說Spring Cloud有哪些常用組件

Eureka:做服務注冊與發現,用來解決服務之間通信問題,

Ribbon/OpenFeign:用做客戶端的負載均衡,也就是解決將請求路由到微服務集群的問題,

Hystrix:斷路器,它的熔斷、降級策略用來解決單節點故障,

Zuul:做服務網關,它是整個微服務的大門,可以用來實現登錄、權限檢查等業務,

Config:分布式配置中心,用來統一管理配置所有微服務的配置文件,

Bus:消息總線,用來給各個微服務廣播消息,可以實現各個微服務配置的自動刷新,

Sleuth:鏈路追蹤,用來實時監控各個微服務建的調用關系,快速定位故障節點

Spring Cloud的優缺點?

微服務相對單體應用來說

優點

  • 服務之間無耦合,代碼簡單方便開發維護,服務之間升級維護互不影響
  • 輕量級HTTP通信機制,不同的服務可以采用不同的編程語言
  • 有極強的擴展能力,業務量大的服務可以再次拆分服務,或者也可以集群部署
  • 支持時下流行的敏捷開發并做了優化

缺點

  • 分布式事務繁瑣
  • 部署麻煩,開發人員的學習成本高
  • 技術成本高,開發人員需要花更多的時間學習相關技術
  • 微服務間的通信存在對性能的損耗問題

什么是服務注冊

Eureka是一個服務組測與發現的組件,翻譯成人話就是管理所有微服務的通訊錄的組件。它包含注冊中心,客戶端兩部分組成。客戶端在啟動的時候會向注冊中心發送一條自我介紹信息,比如端口,ip等等,在注冊中心就會保存一張所有微服務的通訊錄。這就叫服務注冊

什么是服務發現

微服務會定期的從客戶端拉取一份微服務通訊錄,到本地緩存起來,默認是30s一次。當一個微服務向另一個微服務發起調用,直接根據本地的通訊錄找到對方的服務名,發送HTTP請求。這個就叫服務發現

什么是服務續約

微服務會定時(默認30s)發送心跳請求,告訴注冊中心,自己還處于存活狀態,那么服務中心就不會將其從清單中刪除,否則,當微服務宕機或者網絡故障等因素,沒有在規定時間(默認90s)內提交心跳請求,注冊中心就會將它從通訊錄中刪除。

如果服務掛了,注冊中心要等到90s后剔除,那么在剔除前的這段時間內,掛掉的服務有可能還是會被調用,怎么處理?

第一,可以修改注冊中心剔除服務時間,同時加快服務續約心跳請求的頻率

第二,可以使用Hystrix的熔斷降級機制,當某個服務不可訪問,快速失敗,并返回托底數據

第三。重試,提供者集群

你知道EurekaClient服務發現和服務續約每隔30s做一次請求是用什么技術實現的嗎?

使用了ScheduledThreadPoolExecutor線程池定時任務來實現

服務發現是先判斷是否開啟了服務發現功能(默認是開啟的),獲取定時任務的間隔時間(默認是30s),然后初始化服務發現的定時任務,間隔時間可以在yml中修改

服務續約是先判斷是否開啟服務注冊功能(默認是開啟的),獲取定時任務間隔時間(默認是30s),然后初始化心跳請求的定時任務,間隔時間可以在yml中修改

Ribbon是什么,Ribbon的工作原理講一下

Ribbon是一個客戶端負債均衡器,它可以按照負債均衡算法,向多個服務發起調用。當一個微服務有多個集群時,就可以使用它做請求負載均衡,通常結合RestTemplate來使用

說一下 Ribbon的工作原理

消費者會30/次注冊中心拉取服務注冊清單緩存到本地,當消費者需要調用一組提供者集群服務時,Ribbon會根據提供者服務名,在本地緩存的服務地址清單里找到這一組服務的通訊地址,然后按照負債均衡算法(默認是輪詢),選擇其中的一個通訊地址,發起http調用服務。

Ribobn內部通過LoadBalancerInterceptor攔截RestTemplate發起的請求,然后交給RibbonLoadBalancerClient負載均衡客戶端做負載均衡,RibbonLoadBalancerClient把選擇服務的工作交給ILoadBalancer負載均衡器 ,ILoadBalancer會調用 IRule負載均衡算法類來選擇服務。之后RibbonLoadBalancerClient把選擇好的服務交給LoadBalancerRequest去發請求。

Ribbon有哪些負載均衡算法,怎么配置

RoundRobinRule:簡單輪詢,ribbon默認規則

AvailabilityFilteringRule:忽略短路狀態和并發過高的服務器

WeightedResponseTimeRule:根據服務器響應時間作為權重,響應時間越長權重越小

ZoneAvoidanceRule:根據區域選擇

BestAvailableRule:忽略短路的服務器,選擇并發較低的服務器

RandomRule:隨機選擇一個可用服務器

Retry:重試機制的選擇邏輯

OpenFeign和Ribbon的區別

OpenFeign整合了Ribbon和Hystrix,屏蔽了Ribbon拼接URL,參數的細節,使用聲明式編程,讓服務調用變得更加簡單,OpenFiegn底層也是走的Ribbon的負載均衡策略。推薦使用OpenFeign

OpengFiegn的工作流程

首先,當程序啟動時,@EnableFeignClient會掃描@FeignClient注解的接口,并交給Spring容器管理。

當發起請求時,會使用jdk動態代理,并為每個方法都生成相應的RequestTemplate,同時封裝http信息,包括url和請求參數等,

最后把RestTemplate交個HttpClient發送請求,使用ribbon的負載均衡發起調用

為什么要使用Eureka 為什么要使用Ribbon 為什么要使用config配置中心

在微服務系統中,各個服務之間是需要進行網絡通信的,那么他們相互調用就得知道對方的通信地址。eureka就是專門來做做服務注冊與發現,解決服務之間通信問題的

當一個微服務做了集群,也就是同一個服務名會對應多個地址,那么我們在調用的時候,應該調用哪一個就成了問題,Ribbon是一個負債均衡器,它可以按照負債均衡算法,向多個服務發起調用。當一個微服務有多個集群時,就可以使用它做請求的分發

在微服務系統中,服務數量很多,而每個服務都有自己的配置文件,管理起來很麻煩。用了配置中心就可以幫我們集中管理配置文件,它支持本地配置文件,也支持將配置文件放到遠程倉庫如git集中管理

為什么Feign的客戶端接口沒有寫實現類也可以直接被依賴注入

自動注入的實例其實是一個jdk動態代理對象,Feign會為每個方法生成相應的requestTemplate,它根據服務名找到對應的服務,根據返回值類型、形參列表匹配相應的接口,然后封裝url、請求參數,最后生成request請求,使用Ribbon負載均衡發起調用

介紹一下Hystrix

Hystrix意為熔斷器,它可以將出現故障的服務,通過熔斷、降級等手段隔離開,這樣不影響整個系統的主業務。它可以防止由單節點異常導致整個微服務故障,如果遇到故障時,快速失敗,熔斷的同時可以返回兜底數據達到服務降級的目的

什么是熔斷,什么是降級

熔斷,是對服務鏈路的一種保護機制,當鏈路上的某個服務不可訪問時,服務就會觸發降級返回拖地數據,同時當失敗率到達一個閾值,就標記該服務為短路狀態,當請求訪問時直接熔斷。直到檢查到該服務能正常訪問時,就快速恢復

降級,是當某個服務不可訪問時,我們返回一些事先準備好的數據給客戶端,比如說,友情提示服務暫不可用,請騷后重試,這樣用戶體驗就上去了

什么是資源隔離?

指的是限制某一個分布式服務的資源使用,可以理解為限流,也就是限制某個服務的請求數量。它包括線程池隔離和信號量隔離

線程池隔離,是指用一個線程池來存儲當前請求,可以通過設置線程池最大線程數和最大排隊隊列數來限制請求數量

信號量隔離:是指用一個計數器來記錄當前有多少個線程在運行,請求進來計數器就增加1,超過最大信號量,就直接返回

資源隔離:信號量和線程池的區別

線程池方式是異步處理,它與調用線程不是同一個線程

信號量方式是同步處理,與調用線程是同一個線程

線程池方式由于需要排隊,調度,線程切換,因此開銷較大,信號量方式無需切換線程,開銷較小

對于CAP理論,Eureka選擇的是AP還是CP?它保證了一致性還是可用性?

CAP理論指的是,一個分布式系統中,一致性,可用性,分區容錯性,三個要素只能同時實現兩點。Eureka選擇的是AP,它是弱一致性的,保證了可用性和分區容錯性,放棄了數據一致性。也就是說當多個Eureka之間不可通信時,需要保證服務可用,正常提供服務注冊發現功能,但是網絡恢復后最終還是會同步的。

說一下Eureka的自我保護

為了防止服務被誤刪除,Eureka不會立即刪除過時的服務數據。這種機制可能會導致客戶端從注冊中心獲取到已經下線的服務并發起調用而導致錯誤,因此在開發階段我們可以關閉自我保護機制。在生產環境中,我們需要打開自我保護,因為它可以防止因為網絡波動,服務沒有及時續約而造成的服務誤刪除問題。

你們項目是如何做服務降級的?

比如在秒殺業務中,需要實時從redis中查詢庫存,通過設置hystrix的最大信號量,以此來防止redis雪崩。當并發過高,請求數超過最大信號量,觸發降級,直接向客戶端返回兜底數據:”活動太火爆啦,請騷后重試“

Zuul有哪幾類Filter,他們的執行順序是怎么樣的?

zuul按照執行順序,分為pre前置過濾,route路由過濾,post后置過濾,error異常后過濾

正常流程是請求先經過前置過濾器,到達路由過濾器進行路由,路由到各種微服務執行請求,返回結果后經過后置過濾,返回用戶

異常流程,如果再整個過程中出現異常,都會進入error異常過濾器,處理完畢后經過post過濾器返回用戶,如果error自己出現異常,最終也會通過post過濾器返回用戶,如果post過濾器出現異常,也會跳轉到error過濾器,然后直接返回用戶

在Zuul中做登錄檢查如何實現?

可以通過繼承ZuulFilter抽象類,自定義pre類型的過濾器,shouldFilter方法中可以定義需要放行的資源,run方法中檢查請求頭中的token信息,如果沒有token,就響應到客戶端未登錄的信息,并組織filter繼續往后執行

在Zuul中如何做限流?

方式一:可以通過繼承ZuulFilter抽象類自定義pre過濾器,加上限流算法,來實現

方式二:可以通過hystrix的資源隔離模式,設置線程池最大連接數或者最大信號量來實現

方式三:常用,Ratelimit,使用令牌桶算法。。。

配置中心解決什么問題?

在分布式系統中,服務數量很多,而每個服務都有自己的配置文件,管理起來很麻煩。配置中心是個好東西,可以幫我們集中管理配置文件,它支持本地配置文件,也支持將配置文件放到遠程倉庫如git集中管理。

EureakServer的搭建流程

第一步,導入eureka-server依賴,以及springboot的web環境依賴。

第二布,主啟動類上打注解,@EnableEurekaServer,開啟eureka服務端功能

第三步,yml配置文件中,配置注冊中心的端口號,主機名,注冊中心地址

Ribbon的整合流程

第一步,導入ribbon依賴

第二部,給RestTemplate的Bean定義方法上,加上注解@LoadBalanced,讓這個restTemplate有負載均衡的功能

第三步,修改restTemplate調用服務的url,將目標主機名換成目標服務名

Feign的整合流程

第一步,導入openfeign依賴

第二部,主配置類加注解,@EnableFeignClients,開啟feign支持

第三步,定義feign客戶端接口,并加上注釋@FeignClient("目標服務名"),接口中定義方法,該方法與目標服務的對應方法的方法名,返回值類型,形參列表,url路徑要一致

Hystrix的整合流程

  • 第一步,導入hystrix依賴

  • 第二部,主啟動類加注解,@EnableCircuitBreaker,開啟熔斷功能

  • 第三步,在需要開啟熔斷功能的方法上,加注解@HystrixCommand(fallbackMethod="xxx"),xxx是降級方法

  • 第四步,定義降級方法,方法名需要和fallbackMethod的值一致,形參列表和返回值類型需要和目標方法一致

feign整合Hystrix:

  • 第一步,yml中配置,feign.hystrix.enable=true,開啟hystrix功能

  • 第二部,@FeignClient標簽中,定義fallback或者fallbackFactory,指定降級類

  • 第三步,

如果是fallback,就實現feign接口,并覆寫接口中的方法作為降級方法

如果是fallbackFactory,就實現FallbackFactory接口,同時指定泛型為feign接口,覆寫create方法,返回一個feign接口的匿名內部類,類中寫降級方法

Zuul的整合流程

第一步,導入zuul依賴

第二步,主啟動類上加注解@EnableZuulProxy,開啟zuul功能

第三步,yml中配置,統一訪問前綴prefix,禁用通過服務名方式訪問服務ignoredServices,配置路由routes指定某個服務使用某個路徑來訪問

ConfigServer的整合流程

配置中心服務端配置:

第一步,導入config-server依賴

第二步,主啟動類加注解,@EnableConfigServer,開啟配置中心

第三步,配置文件中,配置遠程倉庫地址,倉庫賬號密碼

客戶端配置:

第一步,導入config-client依賴

第二步,創建bootstrap.yml配置文件,配置中心地址config.uri,要拉取的配置文件名name,環境名profile

你們微服務項目的技術棧描述一下

前端門戶系統:HTML + JQuery + CSS

前端管理系統:VUE + ElementUI

后端系統:基于SpringCloud微服務框架(Eureka+OpenFeign+Hystrix+Zuul+Config)

+MyBatisPlus+SpringMVC+Redis+ElasticSearch+RabbitMQ+AlicloudOSS

瀏覽器發起一個請求,在你的微服務項目中的怎么去執行的?

瀏覽器發起的所有請求首先通過Nginx,通過負載均衡算法,路由給zuul集群,然后通過zuul前置過濾,作登錄校驗后,它會從配置中心拉取的通訊地址中,根據url匹配到對應的服務,然后使用ribbon發起restful調用。微服務間也可以通過feign相互調用,最終執行完任務,返回瀏覽器

說下Ribbon和Feign的區別呢

Ribbon和Feign都是SpringCloud Netflix中實現負載均衡的組件,不同點在于

Ribbon是需要我們手動構建http請求,根據目標服務名通過負載均衡算法直接調用目標服務,

Feign是采用接口的方式,將需要調用的目標服務方法定義成抽象方法,路徑,服務名,形參列表,返回值類型需要保持一致。我們只需要調用接口中的方法就可以了。它會自動幫我們生成jdk動態代理,為每個方法生成RequestTemplate并封裝url和請求參數,使用負載均衡算法發起調用

Ribbon的實現方式,一般配合RestTemplate發起http請求,我們需要在注冊RestTemplate的Bean的方法上加@LoadBalanced,使它具有負載均衡的能力

Feign的實現方式,是在主啟動類上加@EnableFeignClients,在客戶端接口上加注解@FeignClient

Spring,SpringBoot和SpringCloud的關系以及區別

Spring是一個開源的輕量級控制反轉和面向切面編程的容器框架。輕量級是說它開發使用簡單,功能強大。控制反轉是指將對象的創建,銷毀控制交給ioc容器,方便解耦合,降低維護難度,面向切面編程是指將相同的邏輯橫向抽取出來,可以對一些通用業務如事務,日志進行集中管理。

Springboot是一個基于spring的框架,對spring做了大量簡化,使開發流程更快,更高效。比如它大量簡化maven依賴,基于注解配置(JavaConfig)無需XML,內嵌Tomcat,部署流程簡單,打包和部署更加靈活,允許獨立運行

SpringCloud是基于SpringBoot實現的,用于微服務架構中管理和協調服務的,它是一系列框架的有序集合,它為開發者提供了一系列工具,例如服務發現與注冊,配置中心,網關,負載均衡,熔斷器,鏈路追蹤等等,讓微服務架構落地變得更簡單

分布式事務

什么是分布式事務,

分布式事務,指的是在分布式環境中,一個請求可能涉及到對多個數據庫的寫操作,要保證多數據庫的一致性就需要用到分布式事務

分布式事務你知道哪些解決方案? 這些方案如何選型

常見的分布式事務解決方案,2PC,TCC,可靠消息最終一致性,最大努力通知

2PC,它將整個事務流程分為兩個階段,P指的是準備階段,C指的是提交階段。它是一個阻塞協議,不適用于并發較高,事務生命周期長的分布式事務。

TCC,它是基于補償性事務的AP系統的一種實現,補償也就是說先按照預定方案執行,如果失敗了就走補償方案。它可以自己定義數據操作的粒度,但是對應用的侵入性強,可以用在登錄送積分,送優惠券等等場景

可靠消息最終一致性,指的是當事務發起方執行完本地事務后,就發出一條消息通知其他參與方,并且他們一定能接收到消息并處理事務。適合執行周期長,并且實時性要求不高的場景

最大努力通知,是在不影響主業務的情況下,盡可能的保證數據的一致性,它適用于一些最終一致性敏感度低的業務,比如支付結果通知

什么是2pc

2PC,是將整個事務流程分為兩個階段,P指的是準備階段,C指的是提交階段。它常見的標準有XA,JTA,Seata

由DTP模型定義事務管理器TM和資源管理器RM之間通訊的接口規范叫做XA,它規定的交互方式是醬紫的:應用程序AP通過TM提交和回滾事務,TM通過XA接口來通知RM數據庫事務的開始,結束,提交,回滾

2PC能保證分布式事務的原子性,但是也有很多缺陷

比如,在第一階段,如果參與者遲遲不回復協調者,就會造成事務的阻塞,性能不好

比如,在第二階段,如果事務協調者發出提交事務指令后宕機,一部分參與者收到消息提交了事務,另一部分沒有收到消息沒有提交事務,這就會導致數據不一致

再比如,在第二階段,如果事務協調者發出提交事務指令后宕機,收到指令的參與者也宕機了,我們就不能確定事務的執行結果,究竟有沒有提交

Seata相比傳統2PC有什么區別,以及優點?

Seata是由阿里中間件團隊發起的開源項目Fescar更名而來,是一個開源的分布式事務框架,它通過對本地關系數據庫的分支事務協調,來驅動完成全局事務

Seata的主要優點是性能好,不會長時間占用鏈接資源,對業務零入侵

與傳統的2PC的區別主要兩方面

在架構層次方面,傳統的2PC方案的RM本質就是數據庫自身,而Seata的RM是以jar包形式作為中間件層部署在應用程序上

在兩階段提交上方面,傳統2PC方案是在第二階段完成才釋放資源,而Seata是在第一階段就將本地事務提交,提高了效率

Seata的TC,TM,RM的含義,以及作用?

TC:事務協調器,它是獨立的中間件,需要獨立部署運行,它維護全局事務的運行狀態,接收TM指令發起全局事務的提交與回滾,負責與RM通信協調各各分支事務的提交或回滾

TM:事務管理器,TM需要嵌入應用程序中工作,它負責開啟一個全局事務,并最終向TC發起全局提交或全局回滾的指令

RM:控制分支事務,負責分支注冊、狀態匯報,并接收事務協調器TC的指令,驅動分支事務的提交和回滾

你知道TCC嗎,它有什么樣的優缺點?

TCC是基于補償型事務的AP系統的一種實現。補償指的先按照事先預定的方案去執行,如果失敗了就走補償方案

它的優點是異步執行效率高,它能對分布式事務中的各個資源分別鎖定,分別提交與釋放

它的缺點是對應用的侵入性強,改動成本高,實現難度大

解釋一下Seata的工作原理

Seata有三個角色:

  • TM任務管理器,負責開啟,提交,回滾事務的發起,
  • TC事務協調器 ,接收TM的指令通知RM提交或者回滾事務
  • RM資源管理器,控制著分支事務的提交和回滾

假設有服務A需要調用服務B,且兩個服務都需要修改各自的數據庫,A服務作為程序入口充當TM和RM,B服務控制著分支事務充當RM。

  • A服務的TM向TC申請開啟一個全局事務,全局事務創建成功并生成一個全局唯一的XID

  • A服務的RM向TC注冊分支事務,并將其納入XID對應全局事務的管轄

  • A服務執行分支事務,寫undolog日志,向TC上報事務狀態

  • 當調用B服務時,B服務的RM向TC注冊分支事務,該分支事務執行,然后寫undolog,向TC上報事務狀態

  • 服務執行完畢A服務的TM向TC發送commit或者rollback指令

  • TC接收到指令,向參與事務的RM發送指令

  • 事務參與者RM受到commit指令,刪除undolog日志。 如果是rollback指令就根據undolog回滾

你能簡單描述一下你在項目中是如何集成Seata的嗎

事務協調器:安裝并啟動Seata客戶端

主業務端:

  • 第一步,導入Seata依賴

  • 第二步,yml中配置事務組名,同時需要添加配置文件file.conf,registry.conf,需要注意yml中事務組名與file.comf中的事務組名一致

  • 第三步,配置DataSource,需要適用Seata對DataSource進行代理

  • 第四步,數據庫中添加undo log日志表

  • 第五步,業務方法上加注解@GlobalTransactional(rollbackFor = Exception.class)注解

事務參與者:

  • 前四步與主業務端相同,第五步不需要了

沒有Seata或者TCC這些事務框架,你可以怎么處理事務?

不用框架就要自己實現,如果業務要求強一致性這個不太好做,需要協調多個數據庫的同時提交和回滾.如果是業務不要求強一致性,我可以參照TCC思想 ,可以考慮自己實現異步寫數據庫方案,如果失敗可以做補償.當然這個要根據業務特性來,很多大公司都是自己封裝事務框架.

分布式鎖

你說一下什么是分布式鎖

分布式鎖是在分布式/集群環境中解決多線程并發造成的一系列數據安全問題.所用到的鎖就是分布式鎖,這種鎖需要被多個應用共享才可以,通常使用Redis和zookeeper來實現。

分布式鎖有哪些解決方案

常用的三種方案

基于數據庫實現:通?;谥麈I,或者唯一索引來實現分布式鎖,但是性能比較差,一般不建議使用

基于Redis :可以使用setnx來加鎖 ,但是需要設置鎖的自動刪除來防止死鎖,所以要結合expire使用.為了保證setnx和expire兩個命令的原子性,可以使用set命令組合。

另外釋放鎖在finallly中調用del刪除鎖,而刪除鎖前需要判斷該鎖是否是當前線程加的鎖以免誤刪除鎖,需要通過get獲取鎖然后進行判斷,但是需要保證get判斷或和del刪除鎖的原子性,可以使用LUA腳本實現。

總之自己封裝Redis的分布式鎖是很麻煩的,我們可以使用Redissoin來實現分布式鎖,Redissoin已經封裝好了。

基于zookeeper : 使用臨時順序節點實現,線程進來都去創建臨時順序節點,第一個節點的創建線程獲取到鎖,后面的節點監聽自己的上一個節點的刪除事件,如果第一個節點被刪除,釋放鎖第二個節點就成為第一個節點,獲取到鎖。

在項目中可以使用curator,這個是Apache封裝好的基于zookeeper的分布式鎖方案。

Redis如何實現分布式鎖,用什么命令

可以使用setnx來加鎖 ,但是需要設置鎖的自動刪除來防止死鎖,所以要結合expire使用.為了保證setnx和expire兩個命令的原子性,可以使用set命令組合。

Redis實現分布式鎖可能會出現什么問題,如何解決

添加鎖和設置過期時間可以使用set命令進行組合,達到原子性加鎖

需要用lua解決刪除和判斷鎖的原子性,否則可能會刪除掉別人的鎖。

Redis集群環境中,redis節點掛掉可能會導致加鎖失敗,可以使用Redisson的紅鎖來解決。

你項目中怎么使用分布式鎖的

自己封裝Redis的分布式鎖是很麻煩的,我們可以使用Redissoin來實現分布式鎖,Redissoin已經封裝好了

了解Redission的看門狗原理嗎?

Redisson對分布式鎖進行了封裝,對于鎖超時問題,它提供了看門狗進行鎖時間的續期,底層使用了定時任務每10s檢查一下,如果業務還未執行完成,未釋放鎖,就進行超時時間續期。

你在項目中如果使用ZK實現分布式鎖的?

基于zookeeper : 使用臨時順序節點實現,線程進來都去創建臨時順序節點,第一個節點的創建線程獲取到鎖,后面的節點監聽自己的上一個節點的刪除事件,如果第一個節點被刪除,釋放鎖第二個節點就成為第一個節點,獲取到鎖。

在項目中可以使用curator,這個是Apache封裝好的基于zookeeper的分布式鎖方案。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容