1. 程式人生 > >java架構之路-(dubbo專題)dubbo的基本使用

java架構之路-(dubbo專題)dubbo的基本使用

  今天我們來說一下dubbo的基本使用,沒有什麼高階的知識,真的超級簡單易懂。

Dubbo核心功能解釋

  dubbo 阿里開源的一個SOA服務治理框架,從目前來看把它稱作是一個RPC遠端呼叫框架更為貼切。單從RPC框架來說,功能較完善,支援多種傳輸和序列化方案。所以想必大家已經知道他的核心功能了:就是遠端呼叫。太多的理論知識我就不說了,這是他的官網http://dubbo.apache.org/en-us/,有時間的自己去看看吧,我們就直接上程式碼吧~!

基於程式碼的方式(最簡單的例項)

  先說一下我們的場景,就是我們有一個使用者服務,對外提供一個介面,可以根據我們的使用者ID來查詢我們的使用者物件,然後一個一個client服務想呼叫我們的使用者服務的查詢介面,就這麼簡單的一個例子我們來看一下。

  首先加入我們的maven依賴

<!-- https://mvnrepository.com/artifact/org.apache.dubbo/dubbo -->
<dependency>
    <groupId>org.apache.dubbo</groupId>
    <artifactId>dubbo</artifactId>
    <version>2.7.3</version>
</dependency>

使用者服務:

  我們先建立一個使用者物件,並且給予序列化,必須序列化,不然會報錯,後面會說為什麼需要例項化。

package com.simple.bean;

import java.io.Serializable;

public class UserBean implements Serializable {

    private Integer id;
    private String nama;
    private Integer age;

    public Integer getId() {
        return id;
    }

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

    public String getNama() {
        return nama;
    }

    public void setNama(String nama) {
        this.nama = nama;
    }

    public Integer getAge() {
        return age;
    }

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

    @Override
    public String toString() {
        return "UserBean{" +
                "id=" + id +
                ", nama='" + nama + '\'' +
                ", age=" + age +
                '}';
    }

    public UserBean(Integer id, String nama, Integer age) {
        this.id = id;
        this.nama = nama;
        this.age = age;
    }
}

  建立一個簡單的UserService,並且給予實現類。

package com.simple.service;

import com.simple.bean.UserBean;

public interface UserService {

    UserBean getUserById(Integer id);
}
package com.simple.service;

import com.simple.bean.UserBean;

public class UserServiceImpl implements UserService {
    @Override
    public UserBean getUserById(Integer id) {
        return new UserBean(1, "張三", 18);
    }
}

  前面都是準備工作,我們接下來看一下我們如何將我們的服務暴露出去,並給與其它服務呼叫。

package com.simple;


import com.simple.service.UserService;
import com.simple.service.UserServiceImpl;
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.ProtocolConfig;
import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.ServiceConfig;

import java.io.IOException;

public class ASimpleDubboServer {

    public static void main(String[] args) throws IOException {
        //開始暴露服務
        ApplicationConfig applicationConfig = new ApplicationConfig("simple-app");//設定服務名稱
        ProtocolConfig protocolConfig = new ProtocolConfig();//遠端呼叫配置
        protocolConfig.setName("dubbo");
        protocolConfig.setPort(-1);
        RegistryConfig registryConfig = new RegistryConfig(RegistryConfig.NO_AVAILABLE);//註冊中心配置,RegistryConfig.NO_AVAILABLE為不使用註冊中心

        ServiceConfig serviceConfig = new ServiceConfig();//設定服務
        serviceConfig.setInterface(UserService.class);//給予介面
        serviceConfig.setRef(new UserServiceImpl());//給予例項
        serviceConfig.setRegistry(registryConfig);
        serviceConfig.setProtocol(protocolConfig);
        serviceConfig.setApplication(applicationConfig);
        serviceConfig.export();
        System.out.println("服務已經暴露成功");
        System.in.read();//禁止程式執行結束
    }

}

  我們再來看一下我們的呼叫端程式碼。

package com.simleclient;


import com.simple.service.UserService;
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.ReferenceConfig;

public class ASimleClientApplication {

    public static void main(String[] args) {
        ApplicationConfig applicationConfig = new ApplicationConfig("client-app");//設定服務名稱,不一定要和服務端一致
        ReferenceConfig referenceConfig =  new ReferenceConfig();//設定例項配置
        referenceConfig.setApplication(applicationConfig);
        referenceConfig.setInterface(UserService.class);
        referenceConfig.setUrl("dubbo://192.168.138.1:20880/com.simple.service.UserService");//給予URL

        UserService userService = (UserService)referenceConfig.get();//開始呼叫
        System.out.println("userService.getUserById(1) = " + userService.getUserById(1));
    }
}

  這裡程式碼還是比較多的,比較複雜的,但是便於我們的理解和記憶。記住兩個位置的關鍵程式碼。

  ①.服務端:ApplicationConfig、ProtocolConfig、RegistryConfig、ServiceConfig這四個是必須的。

  ②.呼叫方:ApplicationConfig、ReferenceConfig。

  也不用背,後面的spring會簡單很多,springBoot會更簡單。我們先來看一下spring xml的配置方式是怎麼做的。

Spring配置

  首先,我們建立兩個xml檔案,一個是consumer.xml,一個是provide.xml。看一下具體的實現和上面的基本是一個道理的。

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="spring-dubbo"/>
    <dubbo:registry address="N/A"/>
    <dubbo:reference id="userService" interface="com.spring.service.UserService" url="dubbo://127.0.0.1:20880"/>
</beans>

provide.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="spring-dubbo"/>
    <dubbo:registry address="N/A"/>
    <dubbo:protocol name="dubbo" port="-1"/>
    <dubbo:service interface="com.spring.service.UserService" ref="userService"/>

    <bean id="userService" class="com.spring.service.UserServiceImpl"></bean>
</beans>

服務端啟動類

package com.spring;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.io.IOException;

public class SpringServer {

    public static void main(String[] args) throws IOException {
        new ClassPathXmlApplicationContext("provide.xml");
        System.in.read();
    }

}

請求類

package com.spring;

import com.spring.service.UserService;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringClient {

    public static void main(String[] args) {
        ClassPathXmlApplicationContext context =
                new ClassPathXmlApplicationContext("consumer.xml");
        UserService userService = context.getBean(UserService.class);
        System.out.println(userService.getUserById(1));
    }
}

  說完了原始碼連線的方式,再來看spring的,簡直超級簡單的。每次啟動會報出一個埠衝突的錯誤,別在意,會自動生成20880後面的埠,在啟動時新增-Ddubbo.application.qos.enable=false引數即可。

 springboot配置

  ①.新增依賴

<dependency>
    <groupId>org.apache.dubbo</groupId>
    <artifactId>dubbo-spring-boot-starter</artifactId>
    <version>2.7.4.1</version>
</dependency>

  ②.寫註解,在啟動類加入@EnableDubbo註解

package com.server;

import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@EnableDubbo
@SpringBootApplication
public class CDubboServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(CDubboServerApplication.class, args);
        System.out.println("服務已開啟");
    }

}

  在你的服務給予sevice直接,註解需要引用dubbo包下的service,並且加入@Component引用為Bean

package com.server.service;


import com.server.bean.UserBean;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.stereotype.Component;

@Component
@Service
public class UserServiceImpl implements UserService {
    @Override
    public UserBean getUserById(Integer id) {
        return new UserBean(1, "張三", 18);
    }
}

  ③.寫配置

dubbo.application.name=bootServer
dubbo.registry.address=zookeeper://192.168.138.129:2181
dubbo.protocol.name=dubbo
dubbo.protocol.port=-1

  呼叫方配置

dubbo.application.name=bootClient
dubbo.registry.address=zookeeper://192.168.138.129:2181

  springboot比起spring來會更簡單,接下來我們看一下一些高階的配置。

高階配置

  這裡的配置太多,太多了,我只挑幾個用的比較多來說一下吧。

## 只引用服務,但不提供服務
dubbo.registry.register=false 

## 呼叫方不會驗證服務端是否啟動,而持續重連
dubbo.registry.check=false 

  服務的分組和版本控制。

@Service(group = "",version = "")

  如果呼叫失敗,重試次數

@Service(group = "",version = "",retries = 2)

  呼叫策略

@Service(group = "",version = "",retries = 2,loadbalance = "roundrobin")
//random=隨機
//roundrobin=輪詢
//leastactive=最少呼叫
//consistenthash=hash雜湊

  超時時間

@Service(group = "",version = "",retries = 2,loadbalance = "roundrobin",timeout = 2000)

  上述的配置也可以用配置檔案來統一配置

dubbo.provider.version=
dubbo.provider.group=
dubbo.provider.loadbalance=
dubbo.provider.retries=
dubbo.provider.timeout=
## provider獨有的執行緒數
dubbo.provider.threads=
## 執行緒模型
dubbo.provider.threadpool=

## fixed 固定
## cached 快取
## limited 
## eager 

  這些配置都是雙向可配置的,就是說,服務方和呼叫方都可以配置的,一般的引數都是在服務端配置,在客戶端使用,比如我們的超時時間,你配置了2秒鐘,配置在服務端,你客戶端也是需要遵循這個兩秒鐘超時時間的。

  超時時間是按照

 

 總結:

  今天說了dubbo的基本使用和一些簡單的配置,都是一些基礎,還是很好理解的。

 

&n