1 分佈式
1.1 什麼是分佈式
- 分佈式系統一定是由多個節點組成的系統。其中,節點指的是計算機服務器,而且這些節點一般不是孤立的,而是互通的。
- 這些連通的節點上部署了我們的節點,並且相互的操作會有協同。分佈式系統對於用戶而言,他們面對的就是一個服務器,提供用戶需要的服務而已,而實際上這些服務是通過背後的衆多服務器組成的一個分佈式系統,因此分佈式系統看起來像是一個超級計算機一樣。
1.2 分佈式與集羣的區別
- 集羣是同一個系統部在不同的服務器上,例如一個登陸系統部在不同的服務器上.
- 分佈式是不同的系統部在不同的服務器上,服務器之間相互調用.
小飯店原來只有一個廚師,切菜洗菜備料炒菜全乾。後來客人多了,廚房一個廚師忙不過來,又請了個廚師,兩個廚師都能炒一樣的菜,這兩個廚師的關係是集羣。爲了讓廚師專心炒菜,把菜做到極致,又請了個配菜師負責切菜,備菜,備料,廚師和配菜師的關係是分佈式,一個配菜師也忙不過來了,又請了個配菜師,兩個配菜師關係是集羣.
2 搭建分佈式項目
準備工具:eclipse,裝有CentOS7系統的VMwarm,zookeeper.......最重要的,一臺三年高齡的老人機.
1 首先創建一個父類的maven項目,打包方式爲pom.
在eclipse中創建一個父類maven項目,打包方式爲pom.爲什麼要創建一個父類的maven項目呢?因爲要使用這個maven項目進行各個jar包版本的管理,子類想要jar包直接跟父類要就可以. xml
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
< 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 >
< groupId >com.itqf</ groupId >
< artifactId >sping-parent</ artifactId >
< version >0.0.1-SNAPSHOT</ version >
< packaging >pom</ packaging >
<!-- 定義所有jar包的版本 -->
< properties >
< junit.version >4.12</ junit.version >
< spring.version >4.2.4.RELEASE</ spring.version >
< mybatis.version >3.2.8</ mybatis.version >
< mybatis.spring.version >1.2.2</ mybatis.spring.version >
< mybatis.paginator.version >1.2.15</ mybatis.paginator.version >
< mysql.version >5.1.32</ mysql.version >
< slf4j.version >1.6.4</ slf4j.version >
< jackson.version >2.4.2</ jackson.version >
< druid.version >1.0.9</ druid.version >
< httpclient.version >4.3.5</ httpclient.version >
< jstl.version >1.2</ jstl.version >
< servlet-api.version >2.5</ servlet-api.version >
< jsp-api.version >2.0</ jsp-api.version >
< joda-time.version >2.5</ joda-time.version >
< commons-lang3.version >3.3.2</ commons-lang3.version >
< commons-io.version >1.3.2</ commons-io.version >
< commons-net.version >3.3</ commons-net.version >
< pagehelper.version >3.4.2-fix</ pagehelper.version >
< jsqlparser.version >0.9.1</ jsqlparser.version >
< commons-fileupload.version >1.3.1</ commons-fileupload.version >
< jedis.version >2.7.2</ jedis.version >
< solrj.version >4.10.3</ solrj.version >
< dubbo.version >2.5.3</ dubbo.version >
< zookeeper.version >3.4.7</ zookeeper.version >
< zkclient.version >0.1</ zkclient.version >
< activemq.version >5.11.2</ activemq.version >
< freemarker.version >2.3.23</ freemarker.version >
< quartz.version >2.2.2</ quartz.version >
</ properties >
<!-- 管理所有項目中用到的jar包,並不做真正的依賴 -->
< dependencyManagement >
< dependencies >
<!-- 時間操作組件 -->
< dependency >
< groupId >joda-time</ groupId >
|
2 創建一個maven的聚合工程.
2.1 創建maven聚合工程,繼承父工程.
聚合工程:可以將項目中的controller層,view層等都獨立成一個工程,最終運行的時候整合到一起運行.
pom.xml
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
< 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 >com.itqf</ groupId >
< artifactId >sping-parent</ artifactId >
< version >0.0.1-SNAPSHOT</ version >
</ parent >
< groupId >com.itqf</ groupId >
< artifactId >sping-manager</ artifactId >
< version >0.0.1-SNAPSHOT</ version >
< packaging >pom</ packaging >
< dependencies >
< dependency >
< groupId >com.itqf</ groupId >
< artifactId >sping-common</ artifactId >
< version >0.0.1-SNAPSHOT</ version >
</ dependency >
</ dependencies >
< build >
< plugins >
< plugin >
< groupId >org.apache.tomcat.maven</ groupId >
< artifactId >tomcat7-maven-plugin</ artifactId >
< configuration >
< port >8083</ port >
< path >/</ path >
</ configuration >
</ plugin >
</ plugins >
</ build >
< modules >
< module >sping-manager-pojo</ module >
< module >sping-manager-interface</ module >
< module >sping-manager-service</ module >
< module >sping-manager-mapper</ module >
</ modules >
</ project >
|
2.2 在聚合工程中創建maven Module,命名sping-manager-pojo(實體類層).
pojo是一個普通的jar格式,不需要依賴父工程.
pom.xml
?
2.3 在聚合工程中創建maven Module,命名sping-manager-mapper(dao層). 在pom.xml文件中依賴pojo.因爲mapper層的方法返回的是一個實體類對象的話,那麼需要用到pojo.
導入依賴jar包.
xml
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
< 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 >com.itqf</ groupId >
< artifactId >sping-manager</ artifactId >
< version >0.0.1-SNAPSHOT</ version >
</ parent >
< artifactId >sping-manager-mapper</ artifactId >
<!-- 依賴pojo -->
< dependencies >
< dependency >
< groupId >com.itqf</ groupId >
< artifactId >sping-manager-pojo</ artifactId >
< version >0.0.1-SNAPSHOT</ version >
</ dependency >
<!-- Mybatis -->
< dependency >
< groupId >org.mybatis</ groupId >
< artifactId >mybatis</ artifactId >
< version >${mybatis.version}</ version >
</ dependency >
< dependency >
< groupId >org.mybatis</ groupId >
< artifactId >mybatis-spring</ artifactId >
< version >${mybatis.spring.version}</ version >
</ dependency >
< dependency >
< groupId >com.github.miemiedev</ groupId >
< artifactId >mybatis-paginator</ artifactId >
< version >${mybatis.paginator.version}</ version >
</ dependency >
< dependency >
< groupId >com.github.pagehelper</ groupId >
< artifactId >pagehelper</ artifactId >
< version >${pagehelper.version}</ version >
</ dependency >
<!-- MySql -->
< dependency >
< groupId >mysql</ groupId >
< artifactId >mysql-connector-java</ artifactId >
< version >${mysql.version}</ version >
</ dependency >
<!-- 連接池 -->
< dependency >
< groupId >com.alibaba</ groupId >
< artifactId >druid</ artifactId >
< version >${druid.version}</ version >
</ dependency >
</ dependencies >
</ project >
|
2.4 在聚合工程中創建sping-manager-interface(接口),將所有的service接口都放到獨立的工程當中. 接口中方法返回值如果是實體類,需要用到pojo.所以在pom中依賴pojo xml
?
2.5 在聚合項目中創建sping-manager-service(interface的實現類).打包方式爲war
因爲將controller層與service層分開了,所以在運行啓動的時候要講controller和service單獨使用tomcat發佈,將聚合工程中所需要的配置文件都放入service中,這樣在Tomcat啓動的時候回將配置文件都進行加載整合.
- service需要用到接口,所以依賴接口sping-manager-interface.
- service需要用到pojo,也需要調用到mapper,所以直接依賴mapper就可以,以爲mapper已經依賴了pojo (依賴傳遞) .
- service需要被spring管理,讓spring給service創建對象
- service需要dubbo的包(後面對dubbo進行介紹)
- service需要使用到SOA,將service當成一個服務發佈出去.
配置文件
SqlMapConfig.xml
?
db.properties
?
applicationContext-tx.xml
?
applicationContext-dao.xml
?
applicationContext-service.xml
?
pom.xml
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
< 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 >com.qianfeng</ groupId >
< artifactId >sping-manager</ artifactId >
< version >0.0.1-SNAPSHOT</ version >
</ parent >
< artifactId >sping-manager-service</ artifactId >
< packaging >war</ packaging >
< dependencies >
< dependency >
< groupId >com.qianfeng</ groupId >
< artifactId >sping-manager-interface</ artifactId >
< version >0.0.1-SNAPSHOT</ version >
</ dependency >
< dependency >
< groupId >com.qianfeng</ groupId >
< artifactId >sping-manager-mapper</ artifactId >
< version >0.0.1-SNAPSHOT</ version >
</ dependency >
<!-- Spring -->
< dependency >
< groupId >org.springframework</ groupId >
< artifactId >spring-context</ artifactId >
< version >${spring.version}</ version >
</ dependency >
< dependency >
< groupId >org.springframework</ groupId >
< artifactId >spring-beans</ artifactId >
< version >${spring.version}</ version >
</ dependency >
< dependency >
< groupId >org.springframework</ groupId >
< artifactId >spring-webmvc</ artifactId >
< version >${spring.version}</ version >
</ dependency >
< dependency >
< groupId >org.springframework</ groupId >
< artifactId >spring-jdbc</ artifactId >
< version >${spring.version}</ version >
</ dependency >
< dependency >
< groupId >org.springframework</ groupId >
< artifactId >spring-aspects</ artifactId >
< version >${spring.version}</ version >
</ dependency >
< dependency >
< groupId >org.springframework</ groupId >
< artifactId >spring-jms</ artifactId >
< version >${spring.version}</ version >
</ dependency >
< dependency >
< groupId >org.springframework</ groupId >
< artifactId >spring-context-support</ artifactId >
< version >${spring.version}</ version >
</ dependency >
</ dependencies >
</ project >
|
最後工程結構
3 使用dubbo將service發佈服務
首先思考?
像淘寶京東這樣的商城類網站,不但可以從PC端登錄,還能從手機端登錄,那麼是怎麼實現的?寫兩個controller?那肯定不會,誰會閒着沒事去找事情做,那麼這就需要使用到SOA(面向服務的架構).那麼我們在寫一個項目使用分佈式的時候,會有很多系統來相互調用,如果來回調用會使代碼結構非常混亂.這裏我們使用dubbo來管理,解決發佈服務太多,搞不清楚的問題.
什麼是SOA
SOA是一種設計方法,其中包含多個服務,而服務之間通過配合最終會提供一系列功能。一個服務通常以獨立的形式存在於操作系統進程中。服務之間通過網絡調用,而非採用進程內調用的方式進行通信。
比如你現在有很多服務:新聞服務(提供新聞的發佈,查看,修改,刪除),訂單服務(訂單添加,訂單修改,訂單查看,訂單刪除等)財務服務(收入,支出,統計等等)員工服務(新增,修改,查看,統計)考勤服務(簽到,簽退,導出,統計等)銷售服務(賣出上報,銷售統計。)
dubbo
什麼是dubbo(是資源調度和治理中心的管理工具)
隨着互聯網的發展,網站應用的規模不斷擴大,常規的垂直應用架構已無法應對,分佈式服務架構以及流動計算架構勢在必行,亟需一個治理系統確保架構有條不紊的演進。
單一應用架構
- 當網站流量很小時,只需一個應用,將所有功能都部署在一起,以減少部署節點和成本。
- 此時,用於簡化增刪改查工作量的 數據訪問框架(ORM) 是關鍵。
垂直應用架構
- 當訪問量逐漸增大,單一應用增加機器帶來的加速度越來越小,將應用拆成互不相干的幾個應用,以提升效率。
- 此時,用於加速前端頁面開發的 Web框架(MVC) 是關鍵。
分佈式服務架構
- 當垂直應用越來越多,應用之間交互不可避免,將核心業務抽取出來,作爲獨立的服務,逐漸形成穩定的服務中心,使前端應用能更快速的響應多變的市場需求。
- 此時,用於提高業務複用及整合的 分佈式服務框架(RPC) 是關鍵。
流動計算架構
- 當服務越來越多,容量的評估,小服務資源的浪費等問題逐漸顯現,此時需增加一個調度中心基於訪問壓力實時管理集羣容量,提高集羣利用率。
- 此時,用於提高機器利用率的 資源調度和治理中心(SOA) 是關鍵。
Dubbo環境的搭建:
節點角色說明:
- Provider: 暴露服務的服務提供方。
- Consumer: 調用遠程服務的服務消費方。
- Registry: 服務註冊與發現的註冊中心。
- Monitor: 統計服務的調用次數和調用時間的監控中心。
- Container: 服務運行容器。
調用關係說明:
- 服務容器負責啓動,加載,運行服務提供者。
- 服務提供者在啓動時,向註冊中心註冊自己提供的服務。
- 服務消費者在啓動時,向註冊中心訂閱自己所需的服務。
- 註冊中心返回服務提供者地址列表給消費者,如果有變更,註冊中心將基於長連接推送變更數據給消費者。
- 服務消費者,從提供者地址列表中,基於軟負載均衡算法,選一臺提供者進行調用,如果調用失敗,再選另一臺調用。 服務消費者和提供者,在內存中累計調用次數和調用時間,定時每分鐘發送一次統計數據到監控中心。
這裏我們主要來部註冊中心(Registry),我們使用Zookeeper來充當註冊中心.
在linux環境下部署註冊中心,Zookeeper
第一步當然是開虛擬機啦,我還是在CentOS7中來搞.
上網上搞一個Zookeeper的壓縮包,我的是zookeeper-3.4.6.tar.gz
粘貼到/opt目錄下,解壓.(需要jdk環境,如果沒有jdk環境先安裝一個jdk)
進入zookeeper-3.4.6目錄,創建一個叫data的文件夾。
把./conf目錄下的zoo_sample.cfg改名爲zoo.cfg 修改zoo.cfg中的data屬性:dataDir=/opt/zookeeper-3.4.6/data
第七步:
- 啓動zookeeper.
- 啓動:./zkServer.sh start
- 關閉:./zkServer.sh stop
- 查看狀態:./zkServer.sh status
注意zookeeper啓動後一定要將防火牆關閉!!!這樣就搞定啦.
在service的applicationContext-service.xml中添加配置文件進行發佈服務
?
1
2
3
4
5
6
7
8
9
10
11
12
|
<!-- 使用dubbo發佈服務 -->
<!-- 指明服務所在的工程 -->
< dubbo:application name = "sping-manager" />
<!-- 指明註冊中心 adress地址是linux中的ip地址加上端口號,zookeeper的默認端口號是2181 -->
< dubbo:registry protocol = "zookeeper" address = "10.0.117.198:2181" ></ dubbo:registry >
<!-- 把服務暴露在某個端口 port是端口號,選擇一個沒有被佔用的端口 -->
< dubbo:protocol name = "dubbo" port = "20888" ></ dubbo:protocol >
<!-- 發佈服務,ref是Spring容器創建的Service對象的名稱 -->
< dubbo:service interface = "com.itqf.service.ItemService" ref = "itemServiceImpl" timeout = "6000000" ></ dubbo:service >
|
在service的pom.xml中導入包
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
<!-- dubbo相關 -->
< dependency >
< groupId >com.alibaba</ groupId >
< artifactId >dubbo</ artifactId >
<!-- 排除依賴 -->
< exclusions >
< exclusion >
< groupId >org.springframework</ groupId >
< artifactId >spring</ artifactId >
</ exclusion >
< exclusion >
< groupId >org.jboss.netty</ groupId >
< artifactId >netty</ artifactId >
</ exclusion >
</ exclusions >
</ dependency >
< dependency >
< groupId >org.apache.zookeeper</ groupId >
< artifactId >zookeeper</ artifactId >
</ dependency >
< dependency >
< groupId >com.github.sgroschupf</ groupId >
< artifactId >zkclient</ artifactId >
</ dependency >
|
4 創建一個sping-manager-controller,與聚合項目平級.導入依賴.
contoller需要使用dubbo來訪問service層發佈的服務.要使用Tomcat服務器進行發佈,當然還需要用到springmvc.
xml
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
< dependencies >
<!-- 只需依賴業務的接口 -->
< dependency >
< groupId >com.qianfeng</ groupId >
< artifactId >sping-manager-interface</ artifactId >
< version >0.0.1-SNAPSHOT</ version >
</ dependency >
<!-- Spring -->
< dependency >
< groupId >org.springframework</ groupId >
< artifactId >spring-context</ artifactId >
< version >${spring.version}</ version >
</ dependency >
< dependency >
< groupId >org.springframework</ groupId >
< artifactId >spring-beans</ artifactId >
< version >${spring.version}</ version >
</ dependency >
< dependency >
< groupId >org.springframework</ groupId >
< artifactId >spring-webmvc</ artifactId >
< version >${spring.version}</ version >
</ dependency >
< dependency >
< groupId >org.springframework</ groupId >
< artifactId >spring-jdbc</ artifactId >
< version >${spring.version}</ version >
</ dependency >
< dependency >
< groupId >org.springframework</ groupId >
< artifactId >spring-aspects</ artifactId >
< version >${spring.version}</ version >
</ dependency >
< dependency >
< groupId >org.springframework</ groupId >
< artifactId >spring-jms</ artifactId >
< version >${spring.version}</ version >
</ dependency >
< dependency >
< groupId >org.springframework</ groupId >
< artifactId >spring-context-support</ artifactId >
< version >${spring.version}</ version >
</ dependency >
<!-- JSP相關 -->
< dependency >
< groupId >jstl</ groupId >
< artifactId >jstl</ artifactId >
</ dependency >
< dependency >
< groupId >javax.servlet</ groupId >
< artifactId >servlet-api</ artifactId >
< scope >provided</ scope >
</ dependency >
< dependency >
< groupId >javax.servlet</ groupId >
< artifactId >jsp-api</ artifactId >
< scope >provided</ scope >
</ dependency >
<!-- dubbo相關 -->
< dependency >
< groupId >com.alibaba</ groupId >
< artifactId >dubbo</ artifactId >
<!-- 排除依賴 -->
< exclusions >
< exclusion >
< groupId >org.springframework</ groupId >
< artifactId >spring</ artifactId >
</ exclusion >
< exclusion >
< groupId >org.jboss.netty</ groupId >
< artifactId >netty</ artifactId >
</ exclusion >
</ exclusions >
</ dependency >
< dependency >
< groupId >org.apache.zookeeper</ groupId >
< artifactId >zookeeper</ artifactId >
</ dependency >
< dependency >
< groupId >com.github.sgroschupf</ groupId >
< artifactId >zkclient</ artifactId >
</ dependency >
</ dependencies >
< build >
< plugins >
< plugin >
< groupId >org.apache.tomcat.maven</ groupId >
< artifactId >tomcat7-maven-plugin</ artifactId >
< configuration >
< port >8081</ port >
< path >/</ path >
</ configuration >
</ plugin >
</ plugins >
</ build >
|
spingmvc.xml
?
結構圖:
5 創建sping-common
這個是我需要用到的一個專門放工具的地方,這裏用來放一些公共需要的東西; pom.xml
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
< 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 >com.itqf</ groupId >
< artifactId >sping-parent</ artifactId >
< version >0.0.1-SNAPSHOT</ version >
</ parent >
< groupId >com.itqf</ groupId >
< artifactId >sping-common</ artifactId >
< version >0.0.1-SNAPSHOT</ version >
< dependencies >
<!-- 時間操作組件 -->
< dependency >
< groupId >joda-time</ groupId >
< artifactId >joda-time</ artifactId >
< version >${joda-time.version}</ version >
</ dependency >
<!-- Apache工具組件 -->
< dependency >
< groupId >org.apache.commons</ groupId >
< artifactId >commons-lang3</ artifactId >
< version >${commons-lang3.version}</ version >
</ dependency >
< dependency >
< groupId >org.apache.commons</ groupId >
< artifactId >commons-io</ artifactId >
< version >${commons-io.version}</ version >
</ dependency >
< dependency >
< groupId >commons-net</ groupId >
< artifactId >commons-net</ artifactId >
< version >${commons-net.version}</ version >
</ dependency >
<!-- Jackson Json處理工具包 -->
< dependency >
< groupId >com.fasterxml.jackson.core</ groupId >
< artifactId >jackson-databind</ artifactId >
< version >${jackson.version}</ version >
</ dependency >
</ dependencies >
</ project >
|
6 測試
好啦,這樣一個僞分佈式項目就搭建好了,接下來非常重要的一點就是需要將父工程,sping-manager的聚合工程,sping-common都install一下放到本地倉庫中,否則的話在啓動項目的時候會報錯說找不到父工程或其他工程.
最終工程圖:
結束。
原文鏈接:https://juejin.im/post/5ad85368f265da50472fc95a