學習筆記-dubbo介紹和使用
Dubbo介紹
1.什麼是Dubbo
一個分散式服務治理框架
2.為什麼用Dubbo
- 官方介紹
當垂直應用越來越多,應用之間互動不可避免,將核心業務抽取出來,作為獨立的服務,逐漸形成穩定的服務中心,使前端應用能更快速的響應多變的市場需求。 此時,用於提高業務複用及整合的分散式服務框架(RPC)是關鍵。
- 自我心得
小專案中dubbo作用不明顯,因為專案中的Api都是通過直接依賴呼叫,當專案龐大比並且服務需要多次重複性的呼叫時,就需要一個框架來治理,dubbo可以做到的效果就是通多xml檔案配置,達到一次提供,到處呼叫的效果,並且和可以對服務的提供者和消費者進行管理;就是將提供服務的Api打包到伺服器,同時註冊到註冊中心(zookeeper),需要呼叫此服務的只需依賴伺服器上的jar包,配置消費者服務即可呼叫Api。
3.基本概念
- 節點角色說明
> - provider 服務的提供方 - consumer 服用的消費方 - registry 註冊中心(可以對提供方和消費方統一管理) - monitor 統計中心 - container 執行容器
呼叫關係說明:
- 服務容器負責啟動,載入,執行服務提供者。
- 服務提供者在啟動時,向註冊中心註冊自己提供的服務。
- 服務消費者在啟動時,向註冊中心訂閱自己所需的服務。
- 註冊中心返回服務提供者地址列表給消費者,如果有變更,註冊中心將基於長連線推送變更資料給消費者。
- 服務消費者,從提供者地址列表中,基於軟負載均衡演算法,選一臺提供者進行呼叫,如果呼叫失敗,再選另一臺呼叫。
- 服務消費者和提供者,在記憶體中累計呼叫次數和呼叫時間,定時每分鐘傳送一次統計資料到監控中心。
dubbo-provider搭建(Simple)
1.準備工作
為了更加直觀的體現dubbo的作用,在此我會搭建一個簡單的maven專案,通過專案的搭建流程和dubbo的相關簡單配置,介紹dubbo的使用,所以,需要做好以下最基本的準備工作:
- JDK(1.8)
- 開發工具(IDEA)
- maven(3.3.9)
- zookepper(註冊中心)
2.專案結構
為了後續程式碼更好的演示,將兩個專案建立在一個工作空間下(IDEA),建立簡單的介面和實現類,簡單的測試方法,基本結構為:
- 介面基本實現為:
public interface ISimpleService { public String sayHello(String name); } @Service public class SimpleServiceImpl implements ISimpleService { public String sayHello(String name) { return "Hello" + name; } }
3.spring boot配置
配置專案的pom檔案,搭建spring boot執行環境,這裡給出一個基本的模板,其中包含mysql的依賴,以及使用基本dubbo的依賴,還有註冊中心zookeeper的相關依賴,可以根據實際情況修改:
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.2.8.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <artifactId>logback-classic</artifactId> <groupId>ch.qos.logback</groupId> </exclusion> <exclusion> <artifactId>log4j-over-slf4j</artifactId> <groupId>org.slf4j</groupId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!--dubbo--> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.8.4</version> </dependency> <!--zookeeper 相關--> <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.4.8</version> </dependency> <dependency> <groupId>com.github.sgroschupf</groupId> <artifactId>zkclient</artifactId> <version>0.1</version> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <!-- Import dependency management from Spring Boot --> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>1.2.8.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <repositories> <repository> <id>public</id> <name>nexus-repository</name> <url>http://192.168.1.169:8080/nexus/content/groups/public</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>true</enabled> </snapshots> </repository> <repository> <id>release</id> <name>nexus-repository</name> <url>http://192.168.1.169:8080/nexus/content/repositories/releases</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>true</enabled> </snapshots> </repository> </repositories> <pluginRepositories> <pluginRepository> <id>nexus</id> <name>nexus-repository</name> <url>http://192.168.1.169:8080/nexus/content/groups/public/</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>false</enabled> </snapshots> </pluginRepository> </pluginRepositories> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> </plugins> </build>
配置完pom檔案後還需要配置application.xml(spring預設載入的配置檔案,根目錄下即可,也可以自己修改配置檔案制定),由於spring boot預設會配置jdbcTemplate,所以需要指定一個dataSourcec(也可通過配置修改,不多說):
# 制定spring boot執行的埠 server.port=8899 #db properties 需要指定一個datasource spring.datasource.url=xxx spring.datasource.username=xxx spring.datasource.password=xxx spring.datasource.driver-class-name=com.mysql.jdbc.Driver
4.dubbo配置
- 隨後配置simple-dubbo-provider.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.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> <!--提供的服務名稱 自己指定即可 代表你提供的這個服務--> <dubbo:application name="simpleprovider"></dubbo:application> <!--註冊中心 本地啟動zookeeper後預設的ip+port--> <dubbo:registry address="zookeeper://127.0.0.1:2181"></dubbo:registry> <!--協議 port自己指定--> <dubbo:protocol name="dubbo" port="8899"></dubbo:protocol> <!--提供的介面服務--> <dubbo:service ref="simpleServiceImpl" interface="cn.littledragon.dubbo.service.ISimpleService"></dubbo:service>
5.執行函式
- 最後可以配置日誌檔案進行,進行日誌記錄,隨後編寫main函式執行專案,運用spring boot中寫好的main方法,加以修改:
@SpringBootApplication @ComponentScan("cn.littledragon") // @MapperScan(basePackages = "com.tdh.swaptrailer.comm.dal.mapper") @ImportResource("simple-dubbo-spring.xml") public class Application { public static final String CONTAINER_KEY = "dubbo.container"; public static final String SHUTDOWN_HOOK_KEY = "dubbo.shutdown.hook"; private static final Logger LOGGER = LoggerFactory.getLogger(Application.class); private static final ExtensionLoader<Container> LOADER = ExtensionLoader.getExtensionLoader(Container.class); private static volatile boolean running = true; protected static void keepRunning(String[] args) { try { if (args == null || args.length == 0) { String config = ConfigUtils.getProperty(CONTAINER_KEY, LOADER.getDefaultExtensionName()); args = Constants.COMMA_SPLIT_PATTERN.split(config); } final List<Container> containers = new ArrayList<Container>(); for (int i = 0; i < args.length; i++) { containers.add(LOADER.getExtension(args[i])); } LOGGER.info("Use container type(" + Arrays.toString(args) + ") to run dubbo serivce."); if ("true".equals(System.getProperty(SHUTDOWN_HOOK_KEY))) { Runtime.getRuntime().addShutdownHook(new Thread() { public void run() { for (Container container : containers) { try { container.stop(); LOGGER.info("Dubbo " + container.getClass().getSimpleName() + " stopped!"); } catch (Exception t) { LOGGER.error(t.getMessage(), t); } synchronized (Application.class) { running = false; Application.class.notify(); } } } }); } for (Container container : containers) { container.start(); LOGGER.info("Dubbo " + container.getClass().getSimpleName() + " started!"); } LOGGER.info(new SimpleDateFormat("[yyyy-MM-dd HH:mm:ss]").format(new Date()) + " Dubbo service server started!"); } catch (RuntimeException e) { LOGGER.error(e.getMessage(), e); } synchronized (Application.class) { while (running) { try { Application.class.wait(); } catch (Exception e) { LOGGER.error(e.getMessage(), e); } } } } public static void main(String[] args) throws Exception { // SpringApplication.run(Application.class, args); SpringApplication app = new SpringApplication(Application.class); app.setWebEnvironment(false); app.run(args); keepRunning(args); } }
dubbo-consumer搭建
- ### 準備工作
在dubbo-provider相同目錄下建立dubbo-consumer專案,二者處於同一目錄下同一等級
- ### spring boot配置
步驟與dubbo-provider相同,此處多一個步驟就是需要將別人提供的服務(也就是需要使用、消費的服務)引入進來:
<dependency> <groupId>cn.littledragon</groupId> <artifactId>dubbo.provider</artifactId> <version>1.0-SNAPSHOT</version> </dependency>
- ### dubbo配置
隨後配置simple-dubbo-provider.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.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> <!-- 服務名稱 與提供服務名稱對應 --> <dubbo:application name="simpleprovider"></dubbo:application> <!--註冊中心--> <dubbo:registry address="zookeeper://127.0.0.1:2181"></dubbo:registry> <!--使用服務 引入依賴後,就可以直接使用此介面 --> <dubbo:reference interface="cn.littledragon.dubbo.service.ISimpleService" id="simpleService"/> </beans>
- ### 執行函式
Application.java也與dubbo-provider相同即可
- ### 測試函式
編寫測試類,測試服務使用情況
public class ConsumerTest { public static void main(String[] args){ ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"simple-dubbo-spring.xml"}); context.start(); ISimpleService simpleService = (ISimpleService)context.getBean("simpleService"); System.out.println(simpleService.sayHello(" littledragon ...")); } }
執行效果
- 首先本地執行zookepper
- 執行dubbo-provider專案的Application.main(),列印dubbo started即可
- 執行dubbo-consumer專案的Application.main(),列印dubbo started即可
- 執行測試函式.main(),可以看到輸出結果:
hello littledragon ...