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