測試麻煩,微小修改 全都得從新測html
單體架構也稱之爲單體系統或者是單體應用。就是一種把系統中全部的功能、模塊耦合在一個應用中的架構方式。其優勢爲:項目易於管理、部署簡單。缺點:測試成本高、可伸縮性差、可靠性差、迭代困難、跨語言程度差、團隊協做難java
聚合項目劃分linux
單項目容易 由於某個功能致使總體oomredis
拆分完 咋實現spring
面向服務的架構(SOA)是一個組件模型,它將應用程序拆分紅不一樣功能單元(稱爲服務)經過這些服務之間定義良好的接口和契約聯繫起來。接口是採用中立的方式進行定義的,它應該獨立於實現服務的硬件平臺、操做系統和編程語言。這使得構建在各類各樣的系統中的服務能夠以一種統一和通用的方式進行交互。數據庫
在沒有實施SOA的年代,從咱們研發的角度來看,只能在代碼級別複用,即Ctrl +V。SOA出現,咱們開始走向了模塊、業務線的複用。apache
SOA年代的典型實現: SOAP協議,CXF框架,XML傳輸編程
xsd,數據校驗json
SOA架構伴隨着軟件研發行業20年的發展,在最初的時候,大型it公司內部系統規模愈來愈大,IT系統愈來愈複雜,All in One單體架構的思想致使公司內項目業務和數據相互隔離,造成了孤島。api
最初,咱們使用數據庫做爲項目之間數據交互和中轉的平臺,如今咱們有了消息中間件。
最初,咱們使用XML完成系統之間解耦與相互關聯,如今咱們有了RPC,Restful
最初,咱們使用業務維度劃分總體項目結構,
最初,咱們多項目節點維護一個共享數據中心,如今咱們作冗餘存儲,閉環數據,保證高效運行及數據最終一致性
最初,SOA思想指導指導咱們把全部的IT系統彙總成一個大的總體,按照業務維度劃分服務,集中化管理 如今咱們拆分抽象服務使其能夠多系統複用相同的功能模塊。
RPC遠程過程調用 : Remote Procedure Call Protocol
遠程過程調用協議,它是一種經過網絡從遠程計算機程序上請求服務,而不須要了解底層網絡技術的協議。RPC協議假定某些傳輸協議的存在,如TCP或UDP,爲通訊程序之間攜帶信息數據。在OSI網絡通訊模型中,RPC跨越了傳輸層和應用層。RPC使得開發包括網絡分佈式多程序在內的應用程序更加容易。
原來的RPC也有其餘幾種好比DCOM,CORBA,RMI(Java)等
傳輸協議
傳輸效率
性能消耗
負載均衡
服務治理
RPC主要用於公司內部的服務調用,性能消耗低,傳輸效率高,服務治理方便。HTTP主要用於對外的異構環境,瀏覽器接口調用,APP接口調用,第三方接口調用等。
Apache Dubbo |ˈdʌbəʊ| 是一款高性能、輕量級的開源Java RPC框架,它提供了三大核心能力:面向接口的遠程方法調用,智能容錯和負載均衡,以及服務自動註冊和發現。
Dubbo是阿里巴巴公司開源的一個高性能優秀的服務框架,使得應用可經過高性能的 RPC 實現服務的輸出和輸入功能,能夠和Spring框架無縫集成。Dubbo框架,是基於容器運行的.。容器是Spring。
官方網站 : http://dubbo.apache.org/
阿里巴巴已經將dubbo框架捐獻給了Apache軟件基金會
註冊中心. 是用於發佈和訂閱服務的一個平臺.用於替代SOA結構體系框架中的ESB服務總線的。
開發服務端代碼完畢後, 將服務信息發佈出去. 實現一個服務的公開.
客戶端程序,從註冊中心下載服務內容 這個過程是訂閱.
訂閱服務的時候, 會將發佈的服務全部信息,一次性下載到客戶端.
客戶端也能夠自定義, 修改部分服務配置信息. 如: 超時的時長, 調用的重試次數等.
服務的消費者, 就是服務的客戶端.
消費者必須使用Dubbo技術開發部分代碼. 基本上都是配置文件定義.
服務的提供者, 就是服務端.
服務端必須使用Dubbo技術開發部分代碼. 以配置文件爲主.
容器. Dubbo技術的服務端(Provider), 在啓動執行的時候, 必須依賴容器才能正常啓動.
默認依賴的就是spring容器. 且Dubbo技術不能脫離spring框架.
在2.5.3版本的dubbo中, 默認依賴的是spring2.5版本技術. 能夠選用spring4.5如下版本.
在2.5.7版本的dubbo中, 默認依賴的是spring4.3.10版本技術. 能夠選擇任意的spring版本.
監控中心. 是Dubbo提供的一個jar工程.
主要功能是監控服務端(Provider)和消費端(Consumer)的使用數據的. 如: 服務端是什麼,有多少接口,多少方法, 調用次數, 壓力信息等. 客戶端有多少, 調用過哪些服務端, 調用了多少次等.
優勢:
採用NIO複用單一長鏈接,並使用線程池併發處理請求,減小握手和加大併發效率,性能較好(推薦使用)
缺點:
大文件上傳時,可能出現問題(不使用Dubbo文件上傳)
優勢:
JDK自帶的能力。可與原生RMI互操做,基於TCP協議
缺點:
偶爾鏈接失敗.
優勢:
可與原生Hessian互操做,基於HTTP協議
缺點:
需hessian.jar支持,http短鏈接的開銷大
優勢:
支持分佈式.不少周邊產品.
缺點:
受限於Zookeeper軟件的穩定性.Zookeeper專門分佈式輔助軟件,穩定較優
優勢:
去中心化,不須要單獨安裝軟件.
缺點:
2.2.1 Provider和Consumer和Registry不能跨機房(路由)
優勢:
支持集羣,性能高
缺點:
要求服務器時間同步.不然可能出現集羣失敗問題.
優勢:
標準RPC服務.沒有兼容問題
缺點:
不支持集羣.
http://dubbo.apache.org/zh-cn/docs/user/maturity.html
Feature | Maturity | Strength | Problem | Advise | User |
併發控制 | Tested | 併發控制 | 試用 | ||
鏈接控制 | Tested | 鏈接數控制 | 試用 | ||
直連提供者 | Tested | 點對點直連服務提供方,用於測試 | 測試環境使用 | Alibaba | |
分組聚合 | Tested | 分組聚合返回值,用於菜單聚合等服務 | 特殊場景使用 | 可用於生產環境 | |
參數驗證 | Tested | 參數驗證,JSR303驗證框架集成 | 對性能有影響 | 試用 | LaiWang |
結果緩存 | Tested | 結果緩存,用於加速請求 | 試用 | ||
泛化引用 | Stable | 泛化調用,無需業務接口類進行遠程調用,用於測試平臺,開放網關橋接等 | 可用於生產環境 | Alibaba | |
泛化實現 | Stable | 泛化實現,無需業務接口類實現任意接口,用於Mock平臺 | 可用於生產環境 | Alibaba | |
回聲測試 | Tested | 回聲測試 | 試用 | ||
隱式傳參 | Stable | 附加參數 | 可用於生產環境 | ||
異步調用 | Tested | 不可靠異步調用 | 試用 | ||
本地調用 | Tested | 本地調用 | 試用 | ||
參數回調 | Tested | 參數回調 | 特殊場景使用 | 試用 | Registry |
事件通知 | Tested | 事件通知,在遠程調用執行先後觸發 | 試用 | ||
本地存根 | Stable | 在客戶端執行部分邏輯 | 可用於生產環境 | Alibaba | |
本地假裝 | Stable | 僞造返回結果,可在失敗時執行,或直接執行,用於服務降級 | 需註冊中心支持 | 可用於生產環境 | Alibaba |
延遲暴露 | Stable | 延遲暴露服務,用於等待應用加載warmup數據,或等待spring加載完成 | 可用於生產環境 | Alibaba | |
延遲鏈接 | Tested | 延遲創建鏈接,調用時創建 | 試用 | Registry | |
粘滯鏈接 | Tested | 粘滯鏈接,老是向同一個提供方發起請求,除非此提供方掛掉,再切換到另外一臺 | 試用 | Registry | |
令牌驗證 | Tested | 令牌驗證,用於服務受權 | 需註冊中心支持 | 試用 | |
路由規則 | Tested | 動態決定調用關係 | 需註冊中心支持 | 試用 | |
配置規則 | Tested | 動態下發配置,實現功能的開關 | 需註冊中心支持 | 試用 | |
訪問日誌 | Tested | 訪問日誌,用於記錄調用信息 | 本地存儲,影響性能,受磁盤大小限制 | 試用 | |
分佈式事務 | Research | JTA/XA三階段提交事務 | 不穩定 | 不可用 |
Feature | Maturity | Strength | Problem | Advise | User |
---|---|---|---|---|---|
Zookeeper註冊中心 | Stable | 支持基於網絡的集羣方式,有普遍周邊開源產品,建議使用dubbo-2.3.3以上版本(推薦使用) | 依賴於Zookeeper的穩定性 | 可用於生產環境 | |
Redis註冊中心 | Stable | 支持基於客戶端雙寫的集羣方式,性能高 | 要求服務器時間同步,用於檢查心跳過時髒數據 | 可用於生產環境 | |
Multicast註冊中心 | Tested | 去中心化,不須要安裝註冊中心 | 依賴於網絡拓撲和路由,跨機房有風險 | 小規模應用或開發測試環境 | |
Simple註冊中心 | Tested | Dogfooding,註冊中心自己也是一個標準的RPC服務 | 沒有集羣支持,可能單點故障 | 試用 |
Feature | Maturity | Strength | Problem | Advise | User |
---|---|---|---|---|---|
Simple監控中心 | Stable | 支持JFreeChart統計報表 | 沒有集羣支持,可能單點故障,但故障後不影響RPC運行 | 可用於生產環境 |
Feature | Maturity | Strength | Problem | Advise | User |
---|---|---|---|---|---|
Dubbo協議 | Stable | 採用NIO複用單一長鏈接,並使用線程池併發處理請求,減小握手和加大併發效率,性能較好(推薦使用) | 在大文件傳輸時,單一鏈接會成爲瓶頸 | 可用於生產環境 | Alibaba |
Rmi協議 | Stable | 可與原生RMI互操做,基於TCP協議 | 偶爾會鏈接失敗,需重建Stub | 可用於生產環境 | Alibaba |
Hessian協議 | Stable | 可與原生Hessian互操做,基於HTTP協議 | 需hessian.jar支持,http短鏈接的開銷大 | 可用於生產環境 |
Feature | Maturity | Strength | Problem | Advise | User |
---|---|---|---|---|---|
Netty Transporter | Stable | JBoss的NIO框架,性能較好(推薦使用) | 一次請求派發兩種事件,需屏蔽無用事件 | 可用於生產環境 | Alibaba |
Mina Transporter | Stable | 老牌NIO框架,穩定 | 待發送消息隊列派發不及時,大壓力下,會出現FullGC | 可用於生產環境 | Alibaba |
Grizzly Transporter | Tested | Sun的NIO框架,應用於GlassFish服務器中 | 線程池不可擴展,Filter不能攔截下一Filter | 試用 |
Feature | Maturity | Strength | Problem | Advise | User |
---|---|---|---|---|---|
Hessian Serialization | Stable | 性能較好,多語言支持(推薦使用) | Hessian的各版本兼容性很差,可能和應用使用的Hessian衝突,Dubbo內嵌了hessian3.2.1的源碼 | 可用於生產環境 | Alibaba |
Dubbo Serialization | Tested | 經過不傳送POJO的類元信息,在大量POJO傳輸時,性能較好 | 當參數對象增長字段時,需外部文件聲明 | 試用 | |
Json Serialization | Tested | 純文本,可跨語言解析,缺省採用FastJson解析 | 性能較差 | 試用 | |
Java Serialization | Stable | Java原生支持 | 性能較差 | 可用於生產環境 |
Feature | Maturity | Strength | Problem | Advise | User |
---|---|---|---|---|---|
Javassist ProxyFactory | Stable | 經過字節碼生成代替反射,性能比較好(推薦使用) | 依賴於javassist.jar包,佔用JVM的Perm內存,Perm可能要設大一些:java -XX:PermSize=128m | 可用於生產環境 | Alibaba |
Jdk ProxyFactory | Stable | JDK原生支持 | 性能較差 | 可用於生產環境 |
Feature | Maturity | Strength | Problem | Advise | User |
---|---|---|---|---|---|
Failover Cluster | Stable | 失敗自動切換,當出現失敗,重試其它服務器,一般用於讀操做(推薦使用) | 重試會帶來更長延遲 | 可用於生產環境 | Alibaba |
Failfast Cluster | Stable | 快速失敗,只發起一次調用,失敗當即報錯,一般用於非冪等性的寫操做 | 若是有機器正在重啓,可能會出現調用失敗 | 可用於生產環境 | Alibaba |
Failsafe Cluster | Stable | 失敗安全,出現異常時,直接忽略,一般用於寫入審計日誌等操做 | 調用信息丟失 | 可用於生產環境 | Monitor |
Failback Cluster | Tested | 失敗自動恢復,後臺記錄失敗請求,定時重發,一般用於消息通知操做 | 不可靠,重啓丟失 | 可用於生產環境 | Registry |
Forking Cluster | Tested | 並行調用多個服務器,只要一個成功即返回,一般用於實時性要求較高的讀操做 | 須要浪費更多服務資源 | 可用於生產環境 | |
Broadcast Cluster | Tested | 廣播調用全部提供者,逐個調用,任意一臺報錯則報錯,一般用於更新提供方本地狀態 | 速度慢,任意一臺報錯則報錯 | 可用於生產環境 |
Feature | Maturity | Strength | Problem | Advise | User |
---|---|---|---|---|---|
Random LoadBalance | Stable | 隨機,按權重設置隨機機率(推薦使用) | 在一個截面上碰撞的機率高,重試時,可能出現瞬間壓力不均 | 可用於生產環境 | Alibaba |
RoundRobin LoadBalance | Stable | 輪詢,按公約後的權重設置輪詢比率 | 存在慢的機器累積請求問題,極端狀況可能產生雪崩 | 可用於生產環境 | |
LeastActive LoadBalance | Stable | 最少活躍調用數,相同活躍數的隨機,活躍數指調用先後計數差,使慢的機器收到更少請求 | 不支持權重,在容量規劃時,不能經過權重把壓力導向一臺機器壓測容量 | 可用於生產環境 | |
ConsistentHash LoadBalance | Stable | 一致性Hash,相同參數的請求老是發到同一提供者,當某一臺提供者掛時,本來發往該提供者的請求,基於虛擬節點,平攤到其它提供者,不會引發劇烈變更 | 壓力分攤不均 | 可用於生產環境 |
Feature | Maturity | Strength | Problem | Advise | User |
---|---|---|---|---|---|
條件路由規則 | Stable | 基於條件表達式的路由規則,功能簡單易用 | 有些複雜多分支條件狀況,規則很難描述 | 可用於生產環境 | Alibaba |
腳本路由規則 | Tested | 基於腳本引擎的路由規則,功能強大 | 沒有運行沙箱,腳本能力過於強大,可能成爲後門 | 試用 |
Feature | Maturity | Strength | Problem | Advise | User |
---|---|---|---|---|---|
Spring Container | Stable | 自動加載META-INF/spring目錄下的全部Spring配置 | 可用於生產環境 | Alibaba | |
Jetty Container | Stable | 啓動一個內嵌Jetty,用於彙報狀態 | 大量訪問頁面時,會影響服務器的線程和內存 | 可用於生產環境 | Alibaba |
Log4j Container | Stable | 自動配置log4j的配置,在多進程啓動時,自動給日誌文件按進程分目錄 | 用戶不能控制log4j的配置,不靈活 | 可用於生產環境 | Alibaba |
下載 http://zookeeper.apache.org/ 並上傳解壓縮
修改文件 vi /etc/profile 追加內容
在path後追加/usr/local/zookeeper/bin
注意中間間隔是: 冒號
export PATH=$PATH:/usr/local/hadoop/bin:/usr/local/hadoop/sbin:/usr/local/zo okeeper/bin
source /etc/profile 從新加載配置
重命名zoo_sample.cfg 爲zoo.cfg
默認加載配置文件會找zoo.cfg這個文件
修改配置文件
vi /usr/local/zookeeper/conf/zoo.cfg
建立數據存放目錄
Mkdir /data/zookeeper
建立Myid文件,並寫入服務器編號
注意:這裏寫入myid文件的編號和接下來要配置的服務器列表編號一一對應,每臺服務器配置的編號也應該不同。
Myid文件裏只有一個數字 1
建立好的這個目錄用於存儲zookeeper產生的數據
修改datadir爲剛纔咱們建立的目錄
dataDir=/data/zookeeper
在最後面加入集羣服務器列表
server.1=192.168.2.51:2888:3888 server.2=cm02:2888:3888 server.3=cm03:2888:3888
配置的服務器集羣個數建議是奇數的
半數以上節點存活,就能夠對外提供服務
其中 server.x 這裏的數字編號 就是咱們的myid裏寫入的數字
Cm01是主機名或ip地址
接下來是對外通信端口和內部選舉端口
zkServer.sh start 命令啓動一臺zookeeper服務器
沒報錯的話 使用jps看一下進程
QuorumPeerMain是zookeeper的主進程
經過status命令能夠查看服務器運行狀態
注意:當咱們使用集羣模式啓動zookeeper的時候,因爲咱們只啓動了一臺服務器,集羣總共3臺,沒有知足zookeeper半數以上節點運行原則,因此服務雖然起來了,可是沒有辦法對外提供服務。
這時咱們須要啓動第二臺服務器
SpringBoot + dubbo
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.1.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.littlepage</groupId> <artifactId>dubbo01</artifactId> <version>0.0.1</version> <name>dubbo01</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> <spring-boot.version>2.1.1.RELEASE</spring-boot.version> <dubbo.version>2.7.1</dubbo.version> </properties> <dependencyManagement> <dependencies> <!-- Spring Boot --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring-boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> <!-- Apache Dubbo --> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-dependencies-bom</artifactId> <version>${dubbo.version}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo</artifactId> <version>${dubbo.version}</version> <exclusions> <exclusion> <groupId>org.springframework</groupId> <artifactId>spring</artifactId> </exclusion> <exclusion> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> </exclusion> <exclusion> <groupId>log4j</groupId> <artifactId>log4j</artifactId> </exclusion> </exclusions> </dependency> </dependencies> </dependencyManagement> <dependencies> <!-- Dubbo Spring Boot Starter --> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>2.7.1</version> </dependency> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.curator/curator-framework --> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-framework</artifactId> <version>4.2.0</version> </dependency> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-recipes</artifactId> <version>4.2.0</version> <exclusions> <exclusion> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.4.14</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
server.port=8081 spring.application.name=DemoProvider dubbo.scan.base-packages=com.msb.db1.service dubbo.protocol.name=dubbo dubbo.protocol.port=666 dubbo.protocol.host=192.168.101.106 dubbo.registry.address=zookeeper://192.168.150.13:2181
public interface DemoService { String sayHello(String name); }
import org.apache.dubbo.config.annotation.Service; import org.springframework.stereotype.Component; @Service(version = "1.0.0" ,timeout = 10000, interfaceClass = DemoService.class) @Component public class DemoServiceImpl implements DemoService { @Override public String sayHello(String name) { // TODO Auto-generated method stub System.out.println("來啦~~~!"); return "hello:" + name; } }
spring.application.name=DemoCustomer dubbo.scan.base-packages=com.msb.db1.service dubbo.registry.address=zookeeper://192.168.150.13:2181
@Reference(version = "1.0.0") DemoService serv;
public interface DemoService { String sayHello(String name); }
本地存根(Stub)
服務端的骨架對象(Skeleton)