1. 程式人生 > >基於dubbo的專案開發

基於dubbo的專案開發

dubbo是什麼:
dubbo是一個阿里巴巴開發的開源分散式服務框架,致力於提供高效能和透明化的RPC遠端服務呼叫方案,是阿里巴巴集團的各成員站點的核心框架,每天為2,000+個服務提供3,000,000,000+次訪問量支援。dubbo是對一個系統中應用層上的優化,後面我會在對系統中資料庫層面的優化進行分享,這裡我們只針對dubbo進行學習

dubbo能解決什麼問題:
當網站變大後,不可避免的需要拆分應用進行服務化,以提高系統性能,開發效率等。並且要求拆分出去的每個服務可以根據需要靈活的配置它的叢集數量和控制服務的粒度(服務的粒度就是說我執行的服務系統中對外發布的服務數量)

dubbo的優點:
1、使用簡單
2、部署輕盈
3、方便二次開發
噹噹網:dubboX
京東:jd-hydra
這些都是基於dubbo二次開發的框架

######在學習dubbo之前我們先來了解一下分散式應用

分散式應用.png

分散式應用:應用程式分佈在不同計算機上,通過網路來共同完成一項任務。通常為服務端/客戶端模式。
伺服器/客戶端又分為二端(server/client)、三端(server/middleware/client)、N端(multiple server/multiple minddle/multiple client)。也就是說分散式應用需要把服務(service)拆分出來,單獨部署在一個web伺服器中,controller呼叫service就通過網路來呼叫,這就形成了客戶端和服務端的模式,客戶端只負責執行controller程式碼,處理資料請求和響應;服務端只負責業務處理,資料運算等。又因為原本一個系統既需要處理使用者的請求和響應,又需要處理業務流程,執行壓力會比較大,從而影響整個系統的效能。現在把系統一分為二了,這就大大的提高整個系統的效能了

三端分散式應用.png

N端分散式應用.png

上面說到了分散式的應用分成客戶端和服務端,它們各自執行在自己的伺服器中,客戶端的controller呼叫服務端的service就不是在一個應用內呼叫了,而是通過網路傳輸來呼叫。
這種通過網路來使controller呼叫遠端的service的技術叫做RPC技術

RPC原理.png

RPC技術是什麼:
RPC(Remote Procedure Call Protocol)——遠端過程呼叫協議,它是一種通過網路從遠端計算機程式上請求服務
RPC的原理:
就是物件的序列化、反序列化以及序列化後資料的傳輸,dubbo(使用二進位制檔案,TCP)
java領域常見的RPC框架:
Java領域裡的分散式技術或者說分散式框架叫做RPC框架有:Dubbo,ZeroICE

使用分散式的模式的優點?
1.在開發上,分成了多個系統,有利於開發任務的分配,各自負責各自的系統開發。
2.在執行上,把負載壓力分配到多臺伺服器上,提高整個系統的執行效能。
3.由於分散式開發模式是把業務或者功能以服務的形式對外發布,這樣的話可以提高服務重用率

用了dubbo的優點?
拆分應用進行服務化,提高系統性能,開發效率,並且可以靈活配置服務叢集數和控制服務

註冊中心的作用:
1、服務端服務的註冊和客戶端服務的呼叫
2、提高系統的可用性
3、提高系統的可伸縮性
4、集中管理服務

註冊中心有什麼:
zookeeper:
zooKeeper是一個分散式的,開放原始碼的分散式應用程式協調服務,是Hadoop和Hbase的重要元件。它是一個為分散式應用提供一致性服務的軟體,提供的功能包括:配置維護、域名服務、分散式同步、組服務等。

zookeeper的使用
雖然能提供給dubbo應用做註冊中心的技術有很多,但是我們用的是zookeeper,因為它是dubbo官方推薦的技術,在springboot-dubbo中,也是預設整合了zookeeper。而且zookeeper它是Hadoop和HBase的重要元件,如果後期專案需要發展大資料業務,那麼就可以無縫的接入大資料的技術。所以我們使用zookeeper作為基於dubbo框架的分散式系統的註冊中心。

1,下載zookeeper執行程式
進入zookeeper官網:https://zookeeper.apache.org/下載
2,修改配置檔案
zoo_sample.cfg修改成zoo.cfg(可以copy一份再修改)
# 記憶體資料的備份地址
dataDir=F://zookeeper-3.4.5//data

存放日誌地址

 dataLogDir=F://zookeeper-3.4.5//log

3,雙擊bin目錄下的zkServer.cmd,執行zookeeper(如果是Mac路徑就不說了,啟動需要到bin目錄下在終端使用命令 sh zkServer.sh start)

####先使用xml方式來寫一個hello world程式

這裡我使用的工具是idea
先建立一個父專案(dubbo_parent),然後再建立三個模組

######1,建立三個專案
一個用於服務端,一個用於客戶端,一個用於介面
服務端:server
客戶端:client
介面:api
然後我們來修改pom.xml配置,這了api專案只是提供介面不需要繼承dubbo_parent的依賴所以在api的pom.xml裡取消繼承的配置.
同時我們在server和client需要api的介面,所以我們需要在server,client兩個專案中匯入api的依賴

<dependencies>
  <dependency>
     <groupId>com.jd.dubbo</groupId>
     <artifactId>api</artifactId>
  </dependency>
</dependencies>

專案關係.png

######2、新增springboot相關依賴和匯入dubbo相關依賴(在dubbo_parent父專案的pom.xml中新增)

springboot父專案:spring-boot-starter-parent
springbootweb相關專案spring-boot-starter-web

  <!--Spring Boot專案-->
 <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.1.RELEASE</version>
</parent>
<dependencies>
<!--spring-boot-web依賴-->
 <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
<!-- dubbo相關依賴 -->
 <dependency>
  <groupId>com.alibaba</groupId>
  <artifactId>dubbo</artifactId>
  <version>2.5.3</version>
<exclusions>
  <exclusion>
    <groupId>org.springframework</groupId>
    <artifactId>spring</artifactId>
  </exclusion>
</exclusions>
  </dependency>
 <!--zookeeper-->
 <dependency>
    <groupId>com.101tec</groupId>
    <artifactId>zkclient</artifactId>
    <version>0.2</version>
 </dependency>
 <dependency>
   <groupId>org.apache.zookeeper</groupId>
   <artifactId>zookeeper</artifactId>
   <version>3.4.5</version>
 </dependency>
 </dependencies>

######3、編寫介面程式


3.1 首先我們在domain包裡建立一個HelloWorld的實體類,定義一個屬性 name,提供setter,getter方法實現Serializable介面
3.2 其次我們在service包裡建立一個介面定義一個抽象方法


######4、編寫服務端程式(介面實現類)和建立啟動類

建立服務端的啟動類

@SpringBootApplication
@ImportResource("classpath:dubbo-server.xml")
public class StartApp {
    public static void main(String[] args) {
        SpringApplication.run(StartApp.class,args);
    }
}

5、編寫服務端xml配置(dubbo-service.xml)

  <!--把具體的服務實現類交給spring容器管理-->
    <bean id="helloWorld" class="com.jd.dubbo.service.impl.HelloWorldServiceImpl"/>
    <!--設定應用名-->
    <dubbo:application name="dubbo-server"/>
    <!--設定RPC協議-->
    <dubbo:protocol name="dubbo" port="20880"/>

    <!--設定註冊中心地址zookeeper,register屬性,預設是true,如果為true的化,就需要把釋出的服務的服務地址註冊到zookeeper
        如果為false,就不需要把服務的地址註冊到zookeeper中
    -->
    <!--<dubbo:registry address="zookeeper://127.0.0.1:2181" register="false"/>-->

    <dubbo:registry address="zookeeper://127.0.0.1:2181" register="true" file="${user.home}/dubbo.cache"/>
    <!--釋出服務-->
    <dubbo:service interface="com.jd.dubbo.service.IHelloWorldService" ref="helloWorld"/>

6、編寫客戶端xml配置

  <!--設定應用名-->
    <dubbo:application name="dubbo-client"/>
    <!--設定註冊中心地址zookeeper-->
    <dubbo:registry address="zookeeper://127.0.0.1:2181"/>
    <!--引用服務-->
    <dubbo:reference interface="com.jd.dubbo.service.IHelloWorldService" id="helloWorldService"/>

7、編寫客戶端程式(啟動類)

@SpringBootApplication
@ImportResource("classpath:dubbo-client.xml")
@Controller
public class StartApp {

    @Autowired
    private IHelloWorldService helloWorldService;
    public static  void main (String[] args){
        SpringApplication.run(StartApp.class,args);
    }

    @RequestMapping("/sayHello")
    @ResponseBody
    public String sayHello(){
        HelloWorld helloWorld =helloWorldService.sayHello(new HelloWorld());
            return  helloWorld.getName();
        }
    }

到這裡我們通過xml的配置方式已經完成了,我們先啟動服務端server再啟動客服端client

###搭建電商架構(基於springboot全註解的方式構建)
基於springboot全註解的方式構建的好處
1、Springboot給我們提供了一整套開發包,匯入一個依賴就能使用它給我們提供的對應的功能,提高我們的開發效率
2、減少了我們應用自己匯入依賴包的數量
3、省去了繁瑣的xml配置檔案
4、內嵌web伺服器:如tomcat,jetty,部署應用變得方便
5、用springboot整合dubbo可以很方便的開發分散式的微服務

#####開發步驟:
一、建立各個工程專案

shop_parent
shop_api_goods(商品系統的api)
shop_api_order(訂單系統的api)
shop_server_goods(商品系統)
shop_server_order(訂單系統)
shop_client_mgrsite(後臺管理系統)
shop_clinet_website(移動端介面)

先建立一個父專案然後再建立其他模組,在shop_parent的pom.xml新增以下依賴

<!--Spring Boot專案-->
<parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-parent</artifactId>
  <version>1.5.1.RELEASE</version>
</parent>
<dependencies>
<!--spring-boot-web依賴-->
  <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
<!-- Spring Boot Dubbo 依賴 -->
<dependency>
    <groupId>io.dubbo.springboot</groupId>
    <artifactId>spring-boot-starter-dubbo</artifactId>
    <version>1.0.0</version>
  <!--剔除Dubbo內的netty,因為zookeeper中有一個-->
  <exclusions>
    <exclusion>
      <artifactId>netty</artifactId>
      <groupId>org.jboss.netty</groupId>
      </exclusion>
      </exclusions>
      </dependency>
</dependencies>
<!--管理商品之間的依賴-->
<dependencyManagement>
    <dependencies>
       <dependency>
       <groupId>com.jd.shop</groupId>
        <artifactId>shop_api_goods</artifactId>
       <version>1.0</version>
      </dependency>
      <dependency>
     <groupId>com.jd.shop</groupId>
    <artifactId>shop_api_order</artifactId>
    <version>1.0</version>
   </dependency>
 <!--阿里巴巴的druid-->
 <dependency>
   <groupId>com.alibaba</groupId>
  <artifactId>druid</artifactId>
  <version>1.0.25</version>
  </dependency>
 <!--spring-boot的mybatis依賴-->
<dependency>
  <groupId>org.mybatis.spring.boot</groupId>
  <artifactId>mybatis-spring-boot-starter</artifactId>
  <version>1.2.0</version>
  </dependency>
 <dependency>
  <groupId>org.projectlombok</groupId>
  <artifactId>lombok</artifactId>
  <version>1.16.18</version>
  </dependency>
</dependencies>
</dependencyManagement>
<build>
 <plugins>
     <!--用於打包和啟動springBoot應用的外掛-->
     <plugin>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-maven-plugin</artifactId>
     </plugin>
</plugins>
</build>

二、新增專案相關依賴
1、新增springboot專案
2、新增我們需要用到的服務系統api包
3、新增springboot-web依賴
4、新增連線資料庫的相關依賴
5、新增dubbo依賴
6、建立springboot應用的啟動類
######修改pom.xml
1.在shop_api_goods(商品系統的api)shop_server_goods(商品系統)這兩個模組中不需要繼承shop_parent所以在他們的pom.xml中需要修改一下.
2.分別在在shop_server_goods(商品系統和shop_server_order(訂單系統)中新增依賴,

 <!--shop_server_goods-->
<dependency>
   <groupId>com.jd.shop</groupId>
   <artifactId>shop_api_goods</artifactId>
 </dependency>
 <!--shop_server_order-->
<dependency>
   <groupId>com.jd.shop</groupId>
   <artifactId>shop_api_order</artifactId>
 </dependency>
<!--shop_server_order-->
 <!--shop_server_order-->
<dependencies>
  <!--mysql驅動-->
  <dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
 </dependency>
    <!--阿里巴巴的druid-->
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid</artifactId>
   </dependency>
 <!--spring-boot的mybatis依賴-->
  <dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
  </dependency>
   <dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
  </dependency>
</dependencies>
 <build>
   <plugins>
      <plugin>
        <groupId>org.mybatis.generator</groupId>
        <artifactId>mybatis-generator-maven-plugin</artifactId>
        <version>1.3.2</version>
        <configuration>
        <verbose>true</verbose>
        <overwrite>false</overwrite>
        </configuration>
 <dependencies>
   <dependency>
     <groupId>mysql</groupId>
     <artifactId>mysql-connector-java</artifactId>
     <version>5.1.21</version>
     </dependency>
  </dependencies>
  </plugin>
</plugins>
</build>

建立兩個服務端啟動類 StartApp
shop_server_goods和shop_server_order的啟動類

@SpringBootApplication
@EnableTransactionManagement
@MapperScan("com.jd.server.goods.mapper")
public class StartApp {
    public static void main(String[] args) {
        SpringApplication.run(StartApp.class,args);
    }
}

三、各個服務系統整合mybatis
1、在application.properties配置檔案中新增如下配置資訊:(兩個服務需要做部分修改,需要修改的地方下面在()裡標註了)

server.port=9090(server.port=9091)
#資料庫連線地址
spring.datasource.url=jdbc:mysql://localhost:3306/jd_shop
#MySQL驅動
spring.datasource.driverClassName=com.mysql.jdbc.Driver
#資料庫賬號
spring.datasource.username=root
#資料庫密碼
spring.datasource.password=123456
#阿里巴巴Druid連線池
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource 
#mybatis的mapper.xml配置檔案路徑
mybatis.mapperLocations=classpath:mapper/*.xml
#mybatis的mapper.xml配置檔案domain物件別名掃描路徑
mybatis.typeAliasesPackage=com.jd.api.goods.domain    
(mybatis.typeAliasesPackage=com.jd.api.order.domain   )

2、在啟動類新增如下註解:(上面的啟動類程式碼已經添加了)

//掃描mybatis介面的註解
@MapperScan("com.jd.server.goods.mapper")
//開啟事務管理
@EnableTransactionManagement

#####四、各個服務系統整合mybatis-generator外掛
1、在各個服務系統的pom檔案中新增mybatis-generator外掛(在pom.xml已經新增)
2、在resources目錄下新增generatorConfig.xml檔案(兩個服務系統需要適當的修改)

#####五、各個服務系統整合dubbo釋出服務程式
1、在application.properties配置檔案中新增如下配置資訊:

#整合dubbo
#設定應用的服務名
spring.dubbo.application.name=shop-server-goods
(spring.dubbo.application.name=shop-server-order)
#設定RPC協議
spring.dubbo.protocol.name=dubbo
#設定RPC埠號
spring.dubbo.protocol.port=20880
#設定註冊中心的地址
spring.dubbo.registry.address=zookeeper://127.0.0.1:2181
#設定釋出服務註解掃描的路徑
spring.dubbo.scan=com.jd.server.goods.service.impl
(spring.dubbo.scan=com.jd.server.order.service.impl)

#####六、釋出一個服務(以釋出商品服務為例)
1、使用mybatis-genenrator外掛生成domain類、mapper介面、mapper.xml檔案
2、每個domain類應該在對應的api專案中
3、在對應的api專案中建立一個服務介面

4、建立服務實現類
在該實現類上貼上@Service註解,貼上了該註解就代表了該類需要釋出服務

注意:
1、該註解是com.alibaba.dubbo.config.annotation包下的註解不是spring的註解
2、貼上該註解的服務實現類必須要在上面的配置項spring.dubbo.scan=xxx能夠掃描到的路徑下


5、啟動springboot應用

#####七、各個客戶端整合dubbo引用服務程式
1、在application.properties配置檔案中新增如下配置資訊:

 #dubbo應用名
spring.dubbo.application.name=shop-client-mgrsite
#連線的註冊中心地址                
spring.dubbo.registry.address=zookeeper://127.0.0.1:2181
#引用服務掃描的路徑                
spring.dubbo.scan=com.jd.client.mgrsite.controller

#####八、引用服務(以商品controller為例)
1、建立商品的controller呼叫商品的服務
在該controller需要注入服務的依賴上貼上@Refrence註解,貼上該註解就可以自動的把需要引用的服務注入進來
注意:貼上該註解的服務依賴必須要在上面的配置項spring.dubbo.scan=xxx能夠掃描到的路徑下

@Controller
public class ProductController {

    @Reference
    IProductService productService;
    @RequestMapping("/getAllProduct")
    @ResponseBody
    public List<Product> getAllProduct() {
        return productService.getAllProduct();
    }
}