1. 程式人生 > >學習筆記-dubbo介紹和使用

學習筆記-dubbo介紹和使用

  • Dubbo介紹

    1.什麼是Dubbo

    一個分散式服務治理框架

    2.為什麼用Dubbo

    • 官方介紹

    當垂直應用越來越多,應用之間互動不可避免,將核心業務抽取出來,作為獨立的服務,逐漸形成穩定的服務中心,使前端應用能更快速的響應多變的市場需求。 此時,用於提高業務複用及整合的分散式服務框架(RPC)是關鍵。

    • 自我心得

    小專案中dubbo作用不明顯,因為專案中的Api都是通過直接依賴呼叫,當專案龐大比並且服務需要多次重複性的呼叫時,就需要一個框架來治理,dubbo可以做到的效果就是通多xml檔案配置,達到一次提供,到處呼叫的效果,並且和可以對服務的提供者和消費者進行管理;就是將提供服務的Api打包到伺服器,同時註冊到註冊中心(zookeeper),需要呼叫此服務的只需依賴伺服器上的jar包,配置消費者服務即可呼叫Api。

    3.基本概念

    • 節點角色說明

    dubbo-node

    > 
    - provider 服務的提供方
    - consumer 服用的消費方
    - registry 註冊中心(可以對提供方和消費方統一管理)
    - monitor 統計中心
    - container 執行容器
    
    • 呼叫關係說明:

      • 服務容器負責啟動,載入,執行服務提供者。
      • 服務提供者在啟動時,向註冊中心註冊自己提供的服務。
      • 服務消費者在啟動時,向註冊中心訂閱自己所需的服務。
      • 註冊中心返回服務提供者地址列表給消費者,如果有變更,註冊中心將基於長連線推送變更資料給消費者。
      • 服務消費者,從提供者地址列表中,基於軟負載均衡演算法,選一臺提供者進行呼叫,如果呼叫失敗,再選另一臺呼叫。
      • 服務消費者和提供者,在記憶體中累計呼叫次數和呼叫時間,定時每分鐘傳送一次統計資料到監控中心。
  • dubbo-provider搭建(Simple)

    1.準備工作

    為了更加直觀的體現dubbo的作用,在此我會搭建一個簡單的maven專案,通過專案的搭建流程和dubbo的相關簡單配置,介紹dubbo的使用,所以,需要做好以下最基本的準備工作:

    • JDK(1.8)
    • 開發工具(IDEA)
    • maven(3.3.9)
    • zookepper(註冊中心)

    2.專案結構

    為了後續程式碼更好的演示,將兩個專案建立在一個工作空間下(IDEA),建立簡單的介面和實現類,簡單的測試方法,基本結構為:

    dubbo-project
    • 介面基本實現為:
      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 ...