提示:要直接看搭建例子的能夠跳到 三java
一.項目架構的發展web
傳統的mvc架構項目將整個系統功能實現所有寫在一個項目中,部署在一個機器上,隨着用戶量的增漲,單個項目服務器沒法承受暴增的用戶請求時須要增長服務器數量,並經過負載均衡集羣將項目部署到多個服務器上,提升項目可處理的用戶請求總數。spring
當mvc架構項目中的某個或某幾個模塊的用戶請求量較大,其餘模塊用戶請求量較小,此時負載均衡集羣依然是每一個服務器部署一個完整的項目,實際須要進行負載均衡的僅是用戶請求量較大的幾個模塊,此處則可採用分佈式將系統功能模塊服務化。spring-mvc
在項目過於龐大,部署單項目沒法知足需求時,須要將項目的不一樣功能模塊拆分紅單獨的服務項目部署到不一樣的服務器上(也就是分佈式)。tomcat
在分佈式中,各個服務項目之間要進行相互調用,須要在知道地址的狀況下經過網絡進行訪問。此時須要一個能讓全部服務都能得知其餘服務地址的中間人,由此產生了服務註冊中心,服務項目須要告訴服務註冊中心它是幹嗎的,也就是進行服務註冊,服務器
當其餘項目要調用特定服務時能夠到服務註冊中心查找服務項目的地址,獲取到服務項目地址後便可經過網絡地址自行調用該服務項目,這整個過程涉及的結構也就是rpc架構的內容。網絡
rpc架構:架構
包含服務提供者、服務消費者、服務註冊中心;mvc
服務註冊中心:在服務提供者進行服務註冊時保存服務提供者信息,在服務消費者進行服務發現時返回服務提供者地址;app
服務提供者provider:在服務註冊中心進行服務註冊,等待服務消費者調用;
服務消費者consumer:在服務註冊中心進行服務發現,在獲得服務註冊中心返回的服務提供者地址後進行服務調用;
rpc架構缺點:當項目拆分服務過多時沒法得知服務是否正在被誰使用;
soa服務化架構:在rpc架構的基礎上加了服務治理系統;
二.Zookeeper與Dubbo分別是什麼?各自在項目中充當什麼角色?
Zookeeper是什麼:
Apache ZooKeeper是由集羣(節點組)使用的一種服務,用於在自身之間協調,並經過穩健的同步技術維護共享數據。ZooKeeper自己是一個分佈式應用程序,爲寫入分佈式應用程序提供服務。
zookeeper充當的角色:
在上述rpc架構中zookeeper就是一個服務註冊中心,全部的服務都在zookeeper中進行登記(服務註冊),當某個服務要調用其餘服務時,問zookeeper要該服務的網絡地址(服務發現)。
dubbo是什麼:
Dubbo是一款高性能、輕量級的開源Java RPC框架,它提供了三大核心能力:面向接口的遠程方法調用,智能容錯和負載均衡,以及服務自動註冊和發現。
dubbo充當的角色:
rpc架構的系統中全部服務項目都須要進行服務註冊(告訴服務註冊中心我是誰)與服務發現(告訴服務註冊中心我要找誰),服務提供者和服務消費者(也就是服務自己)可以使用dubbo來負責服務註冊與服務發現。
dubbo對rpc架構缺點的處理:
Dubbo提供了dubbo-admin服務治理系統,在搭建dubbo+zookeeper後可運行dubbo-admin系統進行服務管理,也就從rpc架構變成了soa服務化架構。
三.搭建dubbo+zookeeper小例子
在正式搭建前能夠先安裝並啓動zookeeper(略),隨後安裝dubbo-admin,下載dubbo-admin.war,更名ROOT.war,放到tomcat中,啓動後可修改其中的dubbo.properties,將地址和帳號密碼修改爲你安裝的zookeeper的,隨後重啓項目
dubbo.registry.address=zookeeper://127.0.0.1:2181 dubbo.admin.root.password=root dubbo.admin.guest.password=guest
而後能夠訪問localhost:8080(修改成ROOT.war就是爲了能localhost:8080直接訪問項目),登陸dubbo-admin後能夠進去逛逛
在搭建到步驟3或步驟4時能夠啓動項目,而後到dubbo-admin服務管理系統中查看消費者和提供者是否有對應的數據,能夠此爲依據,判斷服務是否註冊成功。
1.建立maven項目,並在項目中建立三個子項目,service項目用於編寫公共服務接口,dubboProvider去實現service中的接口,dubboConsumer用於調用公共服務接口在dubboProvider中的實現
2.在service項目中新增一個接口:
package com.lwl.service; public interface DemoService { String sayHello(String name); }
3.dubboProvider中的操做:
3-1)在dubboProvider項目的pom.xml中加入依賴
<!--公共服務接口依賴--> <dependency> <groupId>com.lwl</groupId> <artifactId>service</artifactId> <version>1.0</version> </dependency> <!--dubbo依賴 https://mvnrepository.com/artifact/com.alibaba/dubbo --> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.5.10</version> <!-- 排除dubbo依賴自帶的spring和netty依賴,防止自帶的依賴與項目內依賴版本衝突,若是自己項目沒有,無需排除 --> <exclusions> <exclusion> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> </exclusion> <exclusion> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> </exclusion> <exclusion> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> </exclusion> <exclusion> <groupId>org.jboss.netty</groupId> <artifactId>netty</artifactId> </exclusion> </exclusions> </dependency> <!--zkclient依賴 https://mvnrepository.com/artifact/com.101tec/zkclient --> <dependency> <groupId>com.101tec</groupId> <artifactId>zkclient</artifactId> <version>0.11</version> </dependency> <!--dubbo自身的spring相關依賴被排除,此處將dubbo所須要的對應依賴引入--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.1.8.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.1.8.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>5.1.8.RELEASE</version> </dependency>
3-2)建立DemoServiceImpl 類,實現公共服務接口
package com.lwl.service.impl; import com.lwl.service.DemoService; public class DemoServiceImpl implements DemoService { @Override public String sayHello(String name) { return "Hello " + name; } }
3-3)在web.xml中配置啓動spring
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <!-- 啓動spring容器 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> </web-app>
3-4)在applicationContext.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:dubbo="http://code.alibabatech.com/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> <!--啓動掃描--> <context:component-scan base-package="com.lwl.service"/> <!--聲明公共服務接口實現類的bean--> <bean id="demoService" class="com.lwl.service.impl.DemoServiceImpl"/>
<!--dubbo:application:提供方的應用名--> <dubbo:application name="dubbo-provider"/> <!--dubbo:registry:註冊中心的類型和地址--> <dubbo:registry address="zookeeper://127.0.0.1:2181" check="false" subscribe="false" register=""/> <!--dubbo:protocol:這個服務要暴露在哪一個端口上(使用方根據這個端口使用服務)--> <dubbo:protocol name="dubbo" port="20880"/> <!--dubbo:service:設置暴露的服務接口,ref 爲該接口的 bean,timeout 爲超時時間--> <dubbo:service interface="com.lwl.service.DemoService" ref="demoService" timeout="600000"/> </beans>
4.在dubboConsumer項目中的操做:
4-1)在dubboConsumer項目的pom.xml文件添加依賴:
<!--公共服務接口依賴--> <dependency> <groupId>com.lwl</groupId> <artifactId>service</artifactId> <version>1.0</version> </dependency> <!--dubbo依賴 https://mvnrepository.com/artifact/com.alibaba/dubbo --> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.5.10</version> <!-- 排除dubbo自帶的spring和netty,使用項目的包,若是自己項目沒有則無需排除 --> <exclusions> <exclusion> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> </exclusion> <exclusion> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> </exclusion> <exclusion> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> </exclusion> <exclusion> <groupId>org.jboss.netty</groupId> <artifactId>netty</artifactId> </exclusion> </exclusions> </dependency> <!--zkclient依賴 https://mvnrepository.com/artifact/com.101tec/zkclient --> <dependency> <groupId>com.101tec</groupId> <artifactId>zkclient</artifactId> <version>0.11</version> </dependency> <!-- SpringMVC: https://mvnrepository.com/artifact/org.springframework/spring-webmvc--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.1.8.RELEASE</version>
</dependency>
4-2)在web.xml中啓動springmvc
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <!-- SpringMVC核心控制器 --> <servlet> <servlet-name>spring-mvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring-mvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>spring-mvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
4-3)在spring-mvc.xml中
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd"> <!-- 註解探測器--> <context:component-scan base-package="com.lwl.controller"/> <context:annotation-config/> <!--dubbo:application: 使用方的應用名--> <dubbo:application name="dubbo-consumer"/> <!--dubbo:registry:註冊中心的類型和地址--> <dubbo:registry address="zookeeper://127.0.0.1:2181" check="false"/> <!--dubbo:reference:要使用的服務的接口,並將返回的注入 bean,名稱爲id設的值--> <dubbo:reference interface="com.lwl.service.DemoService" id="demoService"/> <!-- 註冊註解驅動 --> <mvc:annotation-driven/> </beans>
4-4)建立controller:
package com.lwl.controller; import com.lwl.service.DemoService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; @RestController public class DemoController { // @Autowired // 默認按byType自動注入,當找不到對應類型的bean時才按byName自動注入,都找不到時拋出異常 // 默認狀況下必需要求依賴對象必須存在,若是要容許null值可以使用@Autowired(required=false) // @Resource // 默認按byName自動注入,找不到時拋出異常 @Resource//或使用@Autowired(required = false) private DemoService demoService; @GetMapping("/{name}") public String get(@PathVariable String name) { return demoService.sayHello(name); } }
5.先啓動dubboProvider項目,隨後啓動dubboConsumer項目,啓動後訪問http://localhost:8080/dubboConsumer/** 返回 Hello ** 則配置成功