JAVA分布式篇3——Dubbo
JAVA分布式篇3——Dubbo
1、架構演變
1.1、單應用架構
- 當網站流量很小時,只需要一個應用,將所有的功能部署到一起(所有業務都放在一個tomcat 里),從而減少部署節點和成本
- 用于簡化 增刪改查 工作量的數據訪問框架 (ORM)是關鍵
- 例如:某個超市的收銀系統,某個公司的員工管理系統
優點
- 小項目開發快
- 成本低
- 架構簡單
- 易于測試
- 易于部署
缺點
- 大項目模塊耦合嚴重
- 不易開發,維護
- 溝通成本高
- 新增業務困難
- 核心業務與邊緣業務混合在一塊,出現問題互相影響
1.2、垂直應用架構
- 當訪問量逐漸增大,單一應用增加機器帶來的加速度越來越小,將應用拆成幾個互不相干的幾個應 用,以提高效率
- 大模塊按照mvc分層模式,進行拆分成多個互不相關的小模塊,并且每個小模塊都有獨立的服務器
- 用于加速前端頁面開發的web框架(MVC)是關鍵;因為每個小應用都有獨立的頁面
缺點
- 模塊之間不可能完全沒有交集,公用模塊無法重復利用,開發性的浪費
1.3、分布式服務架構
- 當垂直應用越來越多,應用之間交互不可避免,將核心業務抽取出來,作為獨立的業務,逐漸形成 穩健的服務中心,使前端應用能更快速的響應多變的市場需求
- 此時,用戶提高業務復用及整合的分布式服務框架(RPC)遠程調用是關鍵
1.4、流動計算架構
- 當服務越來越多,容量的評估,小服務資源的浪費等問題逐漸呈現,此時需增加一個調度中心基于 訪問壓力實時管理集群容量,提高集群利用率
- 此時,用于提高機器利用率的資源調度和治理中心(SOA)是關鍵
2、Dubbo
- Dubbo是分布式服務框架,是阿里巴巴的開源項目,現交給apache進行維護
- Dubbo致力于提高性能和透明化的RPC遠程服務調用方案,以及SOA服務治理方案
3、RPC
RPC【Remote Procedure Call】是指遠程過程調用,是一種進程間通信方式
3.1、RPC通信原理
- 在客戶端將對象進行序列化
- 底層通信框架使用netty(基于tcp協議的socket),將序列化的對象發給服務方提供方
- 服務提供方通過socket得到數據文件之后,進行反序列化,獲得要操作的對象
- 對象數據操作完畢,將新的對象序列化,再通過服務提供方的socket返回給客戶端
- 客戶端獲得序列化數據,再反序列化,得到最新的數據對象,至此,完成一次請求
RPC的核心:通信、序列化
4、Dubbo角色介紹
| Provider | 服務的提供方 |
| Consumer | 服務的消費方 |
| Registry | 服務注冊與發現的注冊中心 |
| Monitor | 監控服務的統計中心 |
| Container | 服務運行容器 |
4.1、啟動流程
- 服務容器負責啟動,加載,運行服務提供者
- 服務提供者在啟動時,向注冊中心注冊自己提供的服務
- 服務消費者在啟動時,向注冊中心訂閱自己所需的服務
- 在注冊中心返回服務提供者地址列表給消費者,如果有變更,注冊中心將基于長連接推送變更數據給 消費者
- 服務消費者,從提供者地址列表中,基于軟負載均衡算法,選一臺提供者進行調用,如果調用失敗,再選另一臺調用
- 服務消費者和提供者,在內存中累計調用次數和調用時間,定時每分鐘發送一次統計數據到監控中心
5、Dubbo快速入門
5.1、dubbo監控
在正式開始dubbo前,我們先來處理dubbo監控問題
github https://github.com/apache/dubbo-admin
官網打不開可嘗試下面地址
gitee https://codechina.csdn.net/mirrors/apache/dubbo-admin
百度云:https://pan.baidu.com/s/1_b6X3SkgTskLdal3HTtHmw提取碼:exa0
進入dubbo-admin-master
如zookeeper與dubbo不在一臺機器,需修改配置文件(dubbo-admin-master\dubbo-admin\src\main\resources\application.properties)
打開cmd,執行mvn package -Dmaven.skip.test=true,時間會有點久,出現下圖表成功
進入dubbo-admin-master\dubbo-admin\target,拷貝jar包到服務器,后臺啟動jar包
[root@VM-8-13-centos bin]# cd /root [root@VM-8-13-centos ~]# ls dubbo-admin-0.0.1-SNAPSHOT.jar [root@VM-8-13-centos ~]# nohup java -jar dubbo-admin-0.0.1-SNAPSHOT.jar > dubbo-admin.log 2>&1 & [1] 32315 [root@VM-8-13-centos ~]# netstat -tunlp|grep 7001 tcp6 0 0 :::7001 :::* LISTEN 32315/java訪問監控頁面
http://81.70.1.65:7001/默認賬號密碼都為root
到此監控頁面配置完成
下面介紹linux結束進程
首先查看端口pid
[root@VM-8-13-centos ~]# netstat -tunlp|grep 7001 tcp6 0 0 :::7001 :::* LISTEN 32315/java殺死進程
[root@VM-8-13-centos ~]# kill -9 323155.2、創建maven項目導入依賴
5.2.1、服務方
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns="http://xmlns.jcp.org/xml/ns/javaee"xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"id="WebApp_ID" version="3.1"><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener><context-param><param-name>contextConfigLocation</param-name><param-value>classpath:applicationContent.xml</param-value></context-param> </web-app>log4j.properties
log4j.rootLogger=INFO, stdout log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n log4j.appender.logfile=org.apache.log4j.FileAppender log4j.appender.logfile.File=target/zk.log log4j.appender.logfile.layout=org.apache.log4j.PatternLayout log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%napplicationContext.xml
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"xmlns="http://www.springframework.org/schema/beans"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd"><!--應用別名--><dubbo:application name="winkto-dubbo-provider"/><!--注冊中心地址--><dubbo:registry address="zookeeper://81.70.1.65:2181" timeout="30000"/><!--服務--><dubbo:annotation package="cn.winkto.service" /> </beans>服務
public interface RuoyeService {public String sayBye(String name); } @DubboService public class RuoyeServiceImpl implements RuoyeService {public String sayBye(String name) {System.out.println(name);return name+" bye";} }5.2.2、消費方
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"version="4.0"><!--注冊DispatcherServlet--><servlet><servlet-name>springmvc</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:springmvc-config.xml</param-value></init-param><load-on-startup>1</load-on-startup></servlet><!--/ 匹配所有的請求;(不包括.jsp)--><!--/* 匹配所有的請求;(包括.jsp)--><servlet-mapping><servlet-name>springmvc</servlet-name><url-pattern>/</url-pattern></servlet-mapping> </web-app>log4j.properties
log4j.rootLogger=INFO, stdout log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n log4j.appender.logfile=org.apache.log4j.FileAppender log4j.appender.logfile.File=target/zk.log log4j.appender.logfile.layout=org.apache.log4j.PatternLayout log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%nspringmvc-config.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:mvc="http://www.springframework.org/schema/mvc"xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttps://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/mvchttps://www.springframework.org/schema/mvc/spring-mvc.xsdhttp://dubbo.apache.org/schema/dubbohttp://dubbo.apache.org/schema/dubbo/dubbo.xsd"><!--Dubbo的應用名稱,通常使用項目名 --><dubbo:application name="dubbo-consumer" /><!--配置Dubbo的注冊中心地址 --><dubbo:registry address="zookeeper://81.70.1.65:2181" timeout="30000" /><dubbo:annotation package="cn.winkto.controller" /><!-- 自動掃描包,讓指定包下的注解生效,由IOC容器統一管理 --><context:component-scan base-package="cn.winkto.controller"/><!-- 讓Spring MVC不處理靜態資源 --><mvc:default-servlet-handler /><!--處理器映射器和處理器適配器,以及功能增強--><mvc:annotation-driven /></beans>偽服務接口
public interface RuoyeService {public String sayBye(String name); }controller
@RestController public class YoyaController {@DubboReferenceprivate RuoyeService ruoyeService;@RequestMapping("/bye/{name}")public String bye(@PathVariable String name){System.out.println(name);return ruoyeService.sayBye(name);} }測試
http://localhost:8082/dubbo_consumer_war_exploded/bye/yoya6、配置詳解
6.1、啟動檢查
啟動時會在注冊中心檢查依賴的服務是否可用,不可用時會拋出異常
<!--默認是true:拋異常;false:不拋異常--> <dubbo:consumer check="false" />6.2、超時時間
由于網絡或服務端不可靠,會導致調用過程中出現不確定的阻塞狀態(超時) 為了避免超時導致客戶端資源(線程)掛起耗盡,必須設置超時時間
<!--設置超時時間為2秒,默認為1秒--> <dubbo:provider timeout="2000"/>dubbo推薦在Provider上盡量多配置Consumer端屬性
- 作服務的提供者,比服務使用方更清楚服務性能參數,如調用的超時時間,合理的重試 次數,等等
- 在Provider配置后,Consumer不配置則會使用Provider的配置值,即Provider配置可 以作消費者的缺省值
6.3、重試次數
當出現失敗,自動切換并重試其它服務器,dubbo重試的缺省值是2次,我們可以自行設置(在提供方設置)
<dubbo:provider timeout="2000" retries="3"/>并不是所有的方法都適合設置重試次數
- 冪等方法:適合(當參數一樣,無論執行多少次,結果是一樣的,例如:查詢,修改)
- 非冪等方法:不適合(當參數一樣,執行結果不一樣,例如:刪除,添加)
配置重試次數
<dubbo:reference id="ruoyeService" interface="cn.winkto.service.RuoyeService"><dubbo:method name="bye" retries="1"/> </dubbo:reference>6.4、多版本配置
提供者
@DubboService public class RuoyeServiceImpl1 implements RuoyeService {public String sayBye(String name) {System.out.println(name);return name+" bye";} } @DubboService public class RuoyeServiceImpl2 implements RuoyeService {public String sayBye(String name) {System.out.println(name);return name+" byebye~";} } <dubbo:service interface="cn.winkto.service.RuoyeService" class="cn.winkto.service.RuoyeServiceImpl1" version="1.0.0"/> <dubbo:service interface="cn.winkto.service.RuoyeService" class="cn.winkto.service.RuoyeServiceImpl2" version="2.0.0"/>消費者
<dubbo:reference id="ruoyeService" interface="cn.winkto.service.RuoyeService" version="2.0.0"><dubbo:method name="bye" retries="1"/> </dubbo:reference> @RestController public class YoyaController {@DubboReference(version = "2.0.0")private RuoyeService ruoyeService;@RequestMapping("/bye/{name}")public String bye(@PathVariable String name){System.out.println(name);return ruoyeService.sayBye(name);} }消費者的控制層要改為自動注入
當消費者的版本修改為 version="*",那么就會隨機調用服務提供者的版本
6.5、本地存根
先在消費者處理一些業務邏輯,再調用提供者的過程,就是“本地存根”
在消費者,創建一個接口實現類,注意:必須使用構造方法的方式注入
@Service public class RuoyeServiceImpl implements RuoyeService {private RuoyeService ruoyeService;public RuoyeServiceImpl(RuoyeService ruoyeService) {this.ruoyeService = ruoyeService;}public String sayBye(String name) {if (!name.equals("zhangsan"))return ruoyeService.sayBye(name);return "名稱不正確哦";} } @RestController public class YoyaController {@DubboReference(version = "2.0.0",stub = "cn.winkto.service.RuoyeServiceImpl")private RuoyeService ruoyeService;@RequestMapping("/bye/{name}")public String bye(@PathVariable String name){System.out.println(name);return ruoyeService.sayBye(name);} }6.6、負載均衡策略
- 負載均衡(Load Balance), 其實就是將請求分攤到多個操作單元上進行執行,從而共同完成工作 任務
- dubbo一共提供4種策略,缺省為 random 隨機分配調用
6.7、高可用
zookeeper注冊中心宕機,還可以消費dubbo暴露的服務
- 監控中心宕掉不影響使用,只是丟失部分采樣數據
- 數據庫宕掉后,注冊中心仍能通過緩存提供服務列表查詢,但不能注冊新服務
- 注冊中心對等集群,任意一臺宕掉后,將自動切換到另一臺
- 注冊中心全部宕掉后,服務提供者和服務消費者仍能通過本地緩存通訊 服務提供者無狀態,任意一臺宕掉后,不影響使用
- 服務提供者全部宕掉后,服務消費者應用將無法使用,并無限次重連等待服務提供者恢復
6.8、 服務降級
服務降級,就是根據實際的情況和流量,對一些服務有策略的停止或換種簡單的方式處理,從而釋 放服務器的資源來保證核心業務的正常運行
- 在 管理控制臺配置服務降級:屏蔽和容錯
- 屏蔽:mock=force:return+null 表示消費方對該服務的方法調用都 直接返回 null 值,不發起遠程 調用。用來屏蔽不重要服務不可用時對調用方的影響
- 容錯:mock=fail:return+null 表示消費方對該服務的方法調用在 失敗后,再返回 null 值,不拋異 常。用來容忍不重要服務不穩定時對調用方的影響
總結
以上是生活随笔為你收集整理的JAVA分布式篇3——Dubbo的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 长春市计算机学校老照片,松江这所学校一百
- 下一篇: 浙江省团校计算机考试试题及答案,2001