Dubbo直連方式

山丘i發表於2020-08-21

一、dubbo概述

Apache Dubbo 是一款高效能、輕量級的開源 Java RPC 框架,它提供了三大核心能力:

  • 面向介面的遠端方法呼叫,
  • 智慧容錯和負載均衡,
  • 服務自動註冊和發現。

Dubbo 是一個分散式服務框架,致力於提供高效能和透明化的 RPC 遠端服務呼叫方案、 服務治理方案。

官網:http://dubbo.apache.org/zh-cn/

特性:

面向介面代理:

呼叫介面的方法,在 A 伺服器呼叫 B 伺服器的方法,由 dubbo 實現對 B 的呼叫,無需關心實現的細節,就像 MyBatis 訪問 Dao 的介面,可以運算元據庫一樣。不用關心 Dao 介面方法的實現

1. 基本架構

服務提供者(Provider):暴露服務的服務提供方,服務提供者在啟動時,向註冊中心註冊自己提供的服務。
服務消費者(Consumer ): 呼叫遠端服務的服務消費方,服務消費者在啟動時,向註冊中心訂閱自己所需的服務,服務消費者,從提供者地址列表中,基於軟負載均衡演算法,選一臺提供者進行呼叫,如果呼叫失敗,再選另一臺呼叫。
註冊中心(Registry) :註冊中心返回服務提供者地址列表給消費者,如果有變更,註冊中心將基於長連線推送變更資料給消費者
監控中心(Monitor) :服務消費者和提供者,在記憶體中累計呼叫次數和呼叫時間,定時每分鐘傳送一次統計資料到監控中心

呼叫關係說明

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

2. dubbo 支援的協議

支援多種協議:dubbo , hessian , rmi , http, webservice , thrift , memcached , redis。dubbo 官方推薦使用 dubbo 協議。dubbo 協議預設埠 20880
使用 dubbo 協議,spring 配置檔案加入:
<dubbo:protocol name="dubbo" port="20880" />

二、直連方法

點對點的直連專案:消費者直接訪問服務提供者,沒有註冊中心。消費者必須指定服務提供者的訪問地址(url)

消費者直接通過 url 地址訪問固定的服務提供者。這個 url 地址是不變的。

三、建立服務提供者

1. 思路

  1. 建立一個maven web工程:服務的提供者
  2. 建立一個實體bean查詢的結果,實現Serializable介面
  3. 提供一個服務介面:xxxx
  4. 實現這個服務介面:xxxxImpl
  5. 配置dubbo服務提供者的核心配置檔案
    • 宣告dubbo服務提供者的名稱:保證唯一
    • 宣告dubbo使用的協議和埠號
    • 暴露服務,使用直連方式
  6. 新增監聽器

1. 建立maven web

並新增對應的目錄

2. pom.xml

新增了dubbo依賴

<?xml version="1.0" encoding="UTF-8"?>

<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.md</groupId>
  <artifactId>01-link-userservice-provider</artifactId>
  <version>1.0.0</version>
  <packaging>war</packaging>



  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>


    <!--spring依賴-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>4.3.16.RELEASE</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>4.3.16.RELEASE</version>
    </dependency>


    <!--dubbo依賴-->
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>dubbo</artifactId>
      <version>2.6.2</version>
    </dependency>

  </dependencies>

  <build>
    <resources>
      <resource>
        <directory>src/main/java</directory><!--所在的目錄-->
        <includes><!--包括目錄下的.properties,.xml 檔案都會掃描到-->
          <include>**/*.properties</include>
          <include>**/*.xml</include>
        </includes>
        <filtering>false</filtering>
      </resource>
    </resources>
  </build>
</project>

3. 建立實體

package com.md.dubbo.model;

import java.io.Serializable;

/**
 * @author MD
 * @create 2020-08-16 21:30
 */
// model實現序列化
public class User implements Serializable {

    private Integer id;

    private String username;

    private Integer age;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}

4. 建立服務介面並實現

package com.md.dubbo.service;

import com.md.dubbo.model.User;

/**
 * @author MD
 * @create 2020-08-16 21:35
 */
public interface UserService {

    /**
     * 根據使用者標識獲取使用者資訊
     * @param id
     * @return
     */
    User queryUserById(Integer id);
}
//---------------------------------------
package com.md.dubbo.service.impl;

import com.md.dubbo.model.User;
import com.md.dubbo.service.UserService;

/**
 * @author MD
 * @create 2020-08-16 21:38
 */

public class UserServiceImpl implements UserService {
    @Override
    public User queryUserById(Integer id) {

        // 模擬
        User user = new User();
        user.setId(id);
        user.setUsername("pony");
        user.setAge(20);
        return user;
    }
}

5. 配置服務提供者的核心配置檔案

在resources目錄下建立dubbo-userservice-provider.xml檔案

這裡注意:選擇apache的這個

<?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:dubbo="http://dubbo.apache.org/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">

    <!--服務提供者宣告名稱:必須保證服務名稱唯一,他的名稱是dubbo內部使用的唯一標識,用專案名就行-->
    <dubbo:application name="01-link-userservice-provider"/>

    <!--訪問服務協議的名稱及埠號
        name:指定協議名稱
        port:指定協議埠號(預設20880)
    -->
    <dubbo:protocol name="dubbo" port="20880"/>

    <!--
        暴露服務介面
        interface:暴露服務介面的全限定類名
        ref:介面引用的實現類在spring容器中的標識
        registry:如果不使用註冊中心,則值為N/A,直連
    -->
    <dubbo:service interface="com.md.dubbo.service.UserService" ref="userService" registry="N/A"/>

    <!--將介面的實現類載入到Spring容器中-->
    <bean id="userService" class="com.md.dubbo.service.impl.UserServiceImpl"/>

</beans>

6. 新增監聽器

在web.xml中

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

<!--預設的版本低的話換成這個版本的,直接複製即可-->

  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:dubbo-userservice-provider.xml</param-value>
  </context-param>

  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

</web-app>

7. 配置Tomcat

埠號注意修改一下:

HTTP port :8081

JMX port:1098

8. 安裝本地jar到maven倉庫

服務介面中的方法要給消費者使用,消費者專案需要知道介面名稱和介面中的方法名稱、引數等。這些資訊服務提供者才知道。需要把介面的 class 檔案打包為 jar .
服務介面專案的類檔案打包為 jar, 安裝到 maven 倉庫,倉庫中的提供者 jar 可以被消費者使用。
使用 idea 的 maven 視窗執行 install

四、建立服務消費者

1. 思路

  1. 建立一個maven web工程:服務的消費者
  2. 配置pom檔案:新增需要的依賴(spring,dubbo)
  3. 設定dubbo的核心配置檔案
  4. 編寫controller
  5. 配置中央排程器(就是一個servlet:DispatcherServlet)

基本和服務提供者一樣,這裡就說一些主要的

1. pom.xml

還是maven web專案

注意:新增了服務提供者的依賴

<?xml version="1.0" encoding="UTF-8"?>

<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.md</groupId>
  <artifactId>02-link-consumer</artifactId>
  <version>1.0.0</version>
  <packaging>war</packaging>



  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>

    <!--spring依賴-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>4.3.16.RELEASE</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>4.3.16.RELEASE</version>
    </dependency>

    <!--dubbo依賴-->
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>dubbo</artifactId>
      <version>2.6.2</version>
    </dependency>

    <!--依賴服務提供者-->
    <dependency>
      <groupId>com.md</groupId>
      <artifactId>01-link-userservice-provider</artifactId>
      <version>1.0.0</version>
    </dependency>


  </dependencies>

  <build>
    <resources>
      <resource>
        <directory>src/main/java</directory><!--所在的目錄-->
        <includes><!--包括目錄下的.properties,.xml 檔案都會掃描到-->
          <include>**/*.properties</include>
          <include>**/*.xml</include>
        </includes>
        <filtering>false</filtering>
      </resource>
    </resources>
  </build>
</project>

2. 配置服務消費者的核心配置檔案

在resources目錄下建立dubbo-consumer.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:dubbo="http://dubbo.apache.org/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">

    <!--宣告服務消費者名稱:保證唯一性-->
    <dubbo:application name="02-link-consumer"/>


    <!--
        引用遠端服務介面:
        id:遠端服務介面物件名稱
        interface:呼叫遠端介面的全限定類名
        url:訪問服務介面的地址
        registry:不使用註冊中心,值為:N/A
    -->
    <dubbo:reference id="userService" interface="com.md.dubbo.service.UserService"
                     url="dubbo://localhost:20880" registry="N/A"/>


</beans>

3. controller

package com.md.dubbo.web;

import com.md.dubbo.model.User;
import com.md.dubbo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * @author MD
 * @create 2020-08-19 9:00
 */

@Controller
public class UserController {

    // 自動注入
    @Autowired
    private UserService userService;

    @RequestMapping(value = "/user")
    public String userDetail(Model model , Integer id){
        User user = userService.queryUserById(id);
        model.addAttribute("user",user);
        return "userDetail";

    }
}

4. applicationContext.xml

在resources目錄下建立spring配置檔案

<?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:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!--掃描元件-->
    <context:component-scan base-package="com.md.dubbo.web"/>

    <!--配置註解驅動-->
    <mvc:annotation-driven/>

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/"/>
        <property name="suffix" value=".jsp"/>

    </bean>

</beans>

5. 配置中央排程器

在web.xml中

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
  <!--中央排程器-->


  <servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:applicationContext.xml,classpath:dubbo-consumer.xml</param-value>
    </init-param>

  </servlet>


  <servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>


</web-app>

6. 配置Tomcat

和上面一樣,只不過不用修改埠號了

7. 配置測試頁面

在webapp下 建立userDetail.jsp

<%--
  Created by IntelliJ IDEA.
  User: MD
  Date: 2020/8/19
  Time: 9:06
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>使用者詳情</title>
</head>
<body>
<h1>使用者詳情</h1>
<div>使用者標識:${user.id}</div>
<div>使用者名稱稱:${user.username}</div>
<div>使用者年齡:${user.age}</div>
</body>
</html>

8. 測試

  1. 首先開服務提供者的Tomcat
  2. 然後開服務消費者的Tomcat
  3. 然後在位址列輸入,就可以看到了

相關文章