SpringBoot整合Dubbo


 

Dubbo是阿里開源的一個微服務框架,性能很高,現在由Apache維護。

  

此處寫一個demo,訂單服務獲取訂單所屬用戶的信息,order-service調用user-service。

 

 


 

 

 

1、新建子模塊api,groupId為com.chy.mall,artifactId為api

這個模塊用來存放微服務中所有的實體類,以及所有的服務提供者提供的服務接口。

只寫實體類和接口,使用普通的maven項目即可。

 

(1)pom.xml

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.12</version>
    </dependency>

 我要使用lombok,添加lombok的依賴

 

 

(2)新建包model,用於存放所有的model。包下新建實體類User:

//注意:實體類要可序列化
@Getter
@Setter
public class User implements Serializable {
    private Integer id;
    private String username;
    private String password;
    private String tel;
    private String address;
}

 

 

(3)新建包service,用於存放所有服務提供者提供的服務接口。包下新建UserService:

public interface UserService {
    User findUserById(Integer id);
}

 

 

建包的方式有很多,比如用戶服務要提供很多接口,可以在service下新建包user-service;

比如一個服務提供者一個包,user-service包下新建model包、service包,分別放本服務的model、提供的服務接口。

 

之所以把model寫在這個子模塊中,是因為服務接口的參數類型、返回值類型很多都要聲明為實體類。

 

 

(4)使用maven install打包為jar安裝到本地倉庫,實際開發是安裝到公司私服。

如果后續要更新、維護這個jar包,實際開發是以新版本號的方式來開發、安裝,要使用新的jar包需要改pom.xml中的版本號;

自己操作的話,可以直接在原來代碼的基礎上改(使用原版本號),然后安裝覆蓋掉倉庫中原來安裝的jar包。

 

 

 

 

2、新建子模塊user-service,springboot項目,作為服務提供者。groupId為com.chy.mall,artifactId為user-service

(1)pom.xml

   <!-- api接口的jar包 -->
    <dependency>
        <groupId>com.chy.mall</groupId>
        <artifactId>api</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>

    <!-- dubbo的依賴 -->
    <dependency>
        <groupId>org.apache.dubbo</groupId>
        <artifactId>dubbo-spring-boot-starter</artifactId>
        <version>2.7.6</version>
    </dependency>

    <!-- zk的依賴 -->
    <dependency>
        <groupId>org.apache.dubbo</groupId>
        <artifactId>dubbo-dependencies-zookeeper</artifactId>
        <version>2.7.6</version>
        <type>pom</type>
        <exclusions>
            <exclusion>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-log4j12</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

 

使用zk作為注冊中心、配置管理中心,這里添加的zk依賴是作為zkCli。

zk的依賴要用<exclusions>去掉slf4j部分,因為spring-boot-strat已經包含了slf4j,如果不去掉會報錯:slf4j綁定了多個jar包中的Logger......

像這種多處引入同一個依賴的,用maven看一下依賴關系圖,重復的保留一個即可。

 

 

dubbo可以使用多種注冊中心,比如zk、redis等,上面的zk依賴只包含以zk作為注冊中心的依賴,服務只能以zk作為注冊中心。

zk的依賴可以換為以下2種中的任一種,均包含了dubbo支持的所有的注冊中心的依賴:

<dependency>
    <groupId>org.apache.dubbo</groupId>
    <artifactId>dubbo</artifactId>
    <version>2.7.6</version>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>dubbo</artifactId>
    <version>2.6.8</version>
</dependency>

 

 

(2)新建包service,包下新建類UserServiceImpl實現服務接口UserService

//此處的@Service是dubbo下的注解,不是spring的注解
@Service
public class UserServiceImpl implements UserService {
    @Override
    public User findUserById(Integer id) {
        User user = new User();
        user.setId(id);
        user.setUsername("chy");
        return user;
    }
}

實現服務接口的類都放到一個包下。

 

 

(3)配置文件

spring.application.name=user-service
#如果指定了spring應用名稱,可以缺省dubbo的應用名稱,這2個至少要配置1個。缺省dubbo的應用名稱時默認值是spring的應用名稱
#dubbo.application.name=user-service

#注冊中心地址 dubbo.registry.address=zookeeper://192.168.1.9:2181 #端口號可以寫在address中,也可以單獨寫。實質是從address中獲取的port是null,后面設置的port覆蓋了null #dubbo.registry.port=2181
#指定dubbo使用的協議、端口 dubbo.protocol.name=dubbo dubbo.protocol.port=20880
#指定注冊到zk上超時時間,ms dubbo.registry.timeout=10000
#指定實現服務(提供服務)的包 dubbo.scan.base-packages=com.chy.user-service.service

 

連接到zkServer的時間開銷大,如果不將注冊的超時時間設置大一些,可能會報錯:zookeeper not connected,時間不夠,還沒連上就超時取消了。

 

提供服務的包也可以引導類上指定:

@SpringBootApplication
// @EnableDubbo  //會掃描所有的包,從中找出dubbo的@Service標注的類
// @DubboComponentScan(basePackages = "com.chy.user-service.service")  //只掃描指定的包
public class UserServiceApplication {
    
    public static void main(String[] args) {
        SpringApplication.run(UserServiceApplication.class, args);
    }
    
}

可以在配置文件中配置,也可以使用上面2個注解中的一個。

 

  

 

 

3、新建子模塊order-service,springboot web項目,作為服務消費者。groupId為com.chy.mall,artifactId為order-service

(1)pom.xml

   <!-- api接口的jar包 -->
    <dependency>
        <groupId>com.chy.mall</groupId>
        <artifactId>api</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>

    <!-- dubbo的依賴 -->
    <dependency>
        <groupId>org.apache.dubbo</groupId>
        <artifactId>dubbo-spring-boot-starter</artifactId>
        <version>2.7.6</version>
    </dependency>

    <!-- zk的依賴 -->
    <dependency>
        <groupId>org.apache.dubbo</groupId>
        <artifactId>dubbo-dependencies-zookeeper</artifactId>
        <version>2.7.6</version>
        <type>pom</type>
        <exclusions>
            <exclusion>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-log4j12</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

 web項目自然要有spring-boot-start-web。

 

 

(2)新建包controller,包下新建類OrderController來調用服務

@Controller
public class OrderController {
    @Reference  //注入要調用的服務
    private UserService userService;

    @RequestMapping("/user/{id}")
    @ResponseBody
    public User getUser(@PathVariable Integer id){
        //調用服務
        User user= userService.findUserById(id);
        return user;
    }
    
}

一般是在service層調用服務,此處只是demo

 

 

(3)配置文件

#應用名稱
spring.application.name=order-service
#dubbo.application.name=order-service

#注冊中心地址 dubbo.registry.address
=zookeeper://192.168.1.9:2181 #dubbo.registry.port=2181
#協議、端口 dubbo.protocol.name
=dubbo dubbo.protocol.port=20880
#連接zk的超時時間,ms dubbo.registry.timeout
=10000
#啟動應用時是否檢查注冊中心上有沒有依賴的服務,默認true #dubbo.consumer.check
=false

 

缺省dubbo.consumer.check配置時,默認為true,要檢查。

消費者連接注冊中心時,會訂閱要調用的服務,如果提供該服務的服務器一台都沒有,會報錯,這個消費者無法啟動,這樣在消費者啟動時就能檢查到是否有可用的生產者,提前發現問題。

調試時,如果先啟動消費者,后啟動|未啟動生產者,消費者往往啟動不了,報錯:創建不了xxx bean,因為 Injection of @Reference dependencies is failed ,沒有生產者提供該服務。

 設置為false,消費者啟動時不檢查,就算沒有生產者提供該服務,消費者也能正常啟動,只是調用該服務時會出錯。

 

 

 

 

4、先啟動生產者,再啟動消費者

地址欄輸入  http://127.0.0.1:8080/user/1  看到已經輸出user對象信息

 

zkServer上,dubbo的根目錄是/dubbo,

一個提供的服務對應一個znode,包名.服務接口名  的形式,/dubbo/service.UserService

這個節點的子節點providers存儲此服務的所有提供者的注冊信息,子節點consumers存儲訂閱此服務的所有消費者的信息。

 

dubbo @Service標注的類所實現的接口,會自動在zkServer上創建一個對應的znode,包名.接口名的形式;

生產者實現該接口,並使用dubbo @Service標識該類是服務提供者,實現的接口就是它提供的服務;消費者使用@Reference來訂閱、引用服務。

 

 

 


 

 

 

說明

官方demo是用spring整合dubbo、使用xml文件進行配置,因為springboot是近幾年才推出、流行的,對dubbo的支持比spring要差一些,少數(冷門)配置尚未實現。

dubbo的配置可以寫在springboot配置文件中,也可以在resources下新建spring配置文件,來寫dubbo的配置。

 

 

Dubbo的架構:

http://dubbo.apache.org/zh-cn/docs/user/preface/architecture.html

 

 

dubbo配置加載流程:

http://dubbo.apache.org/zh-cn/docs/user/configuration/configuration-load-process.html

 

 

dubbo的協議有很多種,最常用的是dubbo協議:

http://dubbo.apache.org/zh-cn/docs/user/references/protocol/introduction.html

 

 

集群容錯:

http://dubbo.apache.org/zh-cn/docs/user/demos/fault-tolerent-strategy.html

調用服務時,如果調用失敗,默認會重試2次,總共3次。

 

 

dubbo的注冊中心也有很多種,設置可以不要注冊中心,消費者可以通過ip、port直連提供者,直接調用。

一般使用zk作為注冊中心。

 

 

dubbo一般使用20880端口,可以改,

消費者、提供者使用的端口可以相同,也可以不同。

 

 

指定注冊中心:

#協議、ip:port可以寫在一起
dubbo.config-center.address=zookeeper://192.168.1.9:2181    

#也可以分開寫 dubbo.registry.protocol=zookeeper dubbo.registry.address=192.168.1.9:2181 #如果是集群,逗號分隔 dubbo.registry.address=192.168.1.9:2181,192.168.1.10:2181

 

 

設置連接到注冊中心的超時時間:

#這個是提供者、消費者都可以使用的
dubbo.registry.timeout=10000


#也可以使用專門的
dubbo.consumer.timeout=10000
dubbo.provider.timeout=10000

  

 

升級系統時dubbo的服務接口不兼容怎么辦?

使用版本號,dubbo的@Service、@Reference都可以指定version屬性,@Service指定提供的是該服務接口哪個版本的實現,@Reference指定調用該服務接口的哪個版本,提供者、消費者使用版本號來對接。

xml配置思想相同。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM