Dubbo 03: 直連式 + 介面工程

2022-10-19 12:00:26
  • 進一步改正dubbo框架中簡單的直連式的不足

  • 需要用到3個相互獨立的maven工程,專案1為maven的java工程作為介面工程,專案2,3為maven的web工程

    工程1:o3-link-interface	作為介面工程
    工程2:o4-link-userservice-provider	作為服務的提供者
    工程3:o5-link-consumer	作為使用服務的消費者
    

工程1

  • 結構:與簡單的直連式不同的是,引入了介面工程,將實體類和所提供的服務的介面放在介面工程裡

  • pom檔案

    <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.example.dubbo</groupId>
      <artifactId>o3-link-interface</artifactId>
      <version>1.0.0</version>
      <packaging>jar</packaging>
    
      <build>
        <plugins>
          <!--JDK1.8編譯外掛-->
          <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.1</version>
            <configuration>
              <source>1.8</source>
              <target>1.8</target>
            </configuration>
          </plugin>
        </plugins>
      </build>
    </project>
    
  • 實體類:注意要實現序列化介面,資料需要通過socket網路傳輸

    package com.example.dubbo.model;
    
    import java.io.Serializable;
    
    public class User implements Serializable {
        private String id;
        private String name;
        private String age;
    
        @Override
        public String toString() {
            return "User{" +
                    "id='" + id + '\'' +
                    ", name='" + name + '\'' +
                    ", age='" + age + '\'' +
                    '}';
        }
    
        public String getId() {
            return id;
        }
    
        public void setId(String id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getAge() {
            return age;
        }
    
        public void setAge(String age) {
            this.age = age;
        }
    
        public User(String id, String name, String age) {
            this.id = id;
            this.name = name;
            this.age = age;
        }
    
        public User() {
        }
    }
    
  • 服務介面:

    package com.example.dubbo.service;
    
    import com.example.dubbo.model.User;
    
    public interface UserService {
        /**
         * 根據使用者id,獲取用資訊
         */
        User queryUserById(String id);
    }
    

工程2

  • 結構

  • pom檔案:要引入介面工程的依賴,知道要對哪些待提供的服務進行實現

    <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/maven-v4_0_0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <groupId>com.example.dubbo</groupId>
      <artifactId>o4-link-userservice-provider</artifactId>
      <packaging>war</packaging>
      <version>1.0.0</version>
    
      <dependencies>
        <!-- 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.example.dubbo</groupId>
          <artifactId>o3-link-interface</artifactId>
          <version>1.0.0</version>
        </dependency>
    
      </dependencies>
    
    
      <build>
        <plugins>
          <!--JDK1.8編譯外掛-->
          <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.1</version>
            <configuration>
              <source>1.8</source>
              <target>1.8</target>
            </configuration>
          </plugin>
        </plugins>
      </build>
    </project>
    
  • dubbo的服務提供者的組態檔

    <?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="o4-link-userservice-provider"/>
        <!-- 使用的協定和埠 -->
        <dubbo:protocol name="dubbo" port="20880"/>
        <!-- 提供的服務 -->
        <dubbo:service interface="com.example.dubbo.service.UserService"  ref="userService" registry="N/A"/>
        <!-- 服務的實現類-->
        <bean id="userService" class="com.example.dubbo.service.impl.userServiceImpl"/>
    </beans>
    
  • 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-link-userservice-provider.xml</param-value>
        </context-param>
        <listener>
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>
    </web-app>
    
  • 提供的服務實現

    package com.example.dubbo.service.impl;
    
    import com.example.dubbo.model.User;
    import com.example.dubbo.service.UserService;
    
    public class userServiceImpl implements UserService {
        @Override
        public User queryUserById(String id) {
            User user = new User();
            user.setId(id);
            user.setName("橘子");
            user.setAge("18");
            return user;
        }
    
        @Override
        public int queryAllUserCount() {
            return 3;
        }
    }
    

工程3

  • 結構

  • pom檔案:要引入介面工程的依賴,知道可以申請哪些服務

    <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/maven-v4_0_0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <groupId>com.example.dubbo</groupId>
      <artifactId>o5-link-consumer</artifactId>
      <packaging>war</packaging>
      <version>1.0.0</version>
    
      <dependencies>
        <!--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.example.dubbo</groupId>
          <artifactId>o3-link-interface</artifactId>
          <version>1.0.0</version>
        </dependency>
      </dependencies>
    
      <build>
        <plugins>
          <!--JDK1.8編譯外掛-->
          <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.1</version>
            <configuration>
              <source>1.8</source>
              <target>1.8</target>
            </configuration>
          </plugin>
        </plugins>
      </build>
    </project>
    
  • dubbo裡消費者的組態檔

    <?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="o5-link-consumer"/>
        
        <!-- 參照的遠端服務 -->
        <dubbo:reference id="userService" interface="com.example.dubbo.service.UserService" url="dubbo://127.0.0.1:20880" registry="N/A"/>
    </beans>
    
  • 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.example.dubbo.web.controller"/>
    
        <!-- 註解驅動 -->
        <mvc:annotation-driven/>
    
        <!-- 檢視解析器 -->
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="prefix" value="/"/>
            <property name="suffix" value=".jsp"/>
        </bean>
    </beans>
    
  • Controller層

    package com.example.dubbo.web.controller;
    
    import com.example.dubbo.model.User;
    import com.example.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;
    
    @Controller
    public class UserController {
        @Autowired
        UserService userService;
        /**
         * 響應前端請求,返回用使用者詳細資訊以及總的使用者個數
         */
        @RequestMapping("/getUserDetail.do")
        public String getUserDetail(String id, Model model){
            //獲取資料
            User user = userService.queryUserById(id);
            int userCount = userService.queryAllUserCount();
            //存放資料
            model.addAttribute("user", user);
            model.addAttribute("userCount", userCount);
            //跳轉到使用者詳情頁面
            return "userDetail";
        }
    }
    
  • 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:application.xml classpath:dubbo-link-consumer.xml</param-value>
            </init-param>
        </servlet>
        <servlet-mapping>
            <servlet-name>dispatcherServlet</servlet-name>
            <url-pattern>*.do</url-pattern>
        </servlet-mapping>
    </web-app>
    
  • 返回給前端的響應頁面:userDetail.jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>使用者詳情頁</title>
    </head>
    <body>
    <div>使用者id:${user.id}</div>
    <div>使用者名稱:${user.name}</div>
    <div>使用者年齡:${user.age}</div>
    <div>使用者數量:${userCount}</div>
    </body>
    </html>
    

測試

  • 將服務提供者工程和消費者工程部署到tomcat上並執行

  • 執行結果

分析

  • 優點:

  • 在直連式的基礎上引入了介面工程,其中包含實體類和待提供的服務的介面,定義了可以提供哪些服務

  • 服務者工程只要在其pom檔案中引入對上述介面工程的依賴,對待提供的服務進行實現即可

  • 消費者工程只要在其pom檔案中引入對上述介面工程的依賴,對所提供的服務進行申請存取即可

  • 上述介面工程的使用很好的隔離了服務消費者和服務提供者之間的耦合,在二者之間搭建了一個溝通呼叫的橋樑

  • 缺點:

  • 當提供的服務較多時,對服務者提供的服務以及消費者可以申請的服務不太好管理,無法對現有服務種類進行很好的統計與管理