dubbo入門(一)
1、簡介
Dubbo由阿裏巴巴開源,是一個分布式服務框架,致力於提供高性能和透明化的RPC(遠程過程調用)遠程服務調用方案,以及SOA服務治理方案。如果沒有分布式的需求,Dbubbo是不需要的,其本質是遠程服務調用的分布式框架,與之前的WebService不同。
電商系統的演變過程:
1、單一應用架構,所有的功能均部署在一起,即在一個發布包中;缺點:難以維護
2、垂直應用架構,將系統拆分成幾個子系統,每個子系統完成特定的業務;缺點:相同邏輯的代碼需要不斷復制,無法復用
3、分布式應用架構,將核心業務抽取出來作為單獨服務,形成穩定的服務中心,
4、流動計算框架(SOA)。隨著服務越來越多,服務之間會產生相互調用會越來越復雜,誕生了面向服務的架構體系(SOA),因此衍生出了一系列相應的技術,如對服務提供、服務調用、連接處理、通信協議、序列化方式、服務發現、服務路由、日誌輸出等行為進行封裝的服務框架。
Dubbo:
1、一款分布式服務框架
2、高性能和透明化的RPC遠程服務調用方案;
3、SOA服務治理方案;
2、架構
Provider:服務提供方
Registry:服務註冊與調用的註冊中心
Consumer:服務消費方
Monitor:服務監控中心,統計服務調用時間及調用次數
服務過程:
0 服務容器啟動、加載、運行服務提供者
1 服務提供者在啟動時向註冊中心註冊自己的服務
2 服務消費方在服務啟動時向註冊中心訂閱自己需要的服務
3 註冊中心返回服務提供者服務列表給你服務消費方,如有變更,註冊中心將基於長連接推送給服務消費方
4 服務消費方基於軟負載均衡算法選擇一臺服務提供者進行調用,調用失敗選擇另外的一臺
5 服務消費者和提供者在內存中累計調用次數和時間,定時每分鐘發送給監控中心
3、Dubbo註冊中心
Dubbo提供了一下集中註冊中心的類型
1、Multicast註冊中心 多播
2、Zookeeper註冊中心,使用zookeeper
3、Redis註冊中心,使用Redis
4、Simple註冊中心,
4、Dbubbo優缺點
4.1、優點
1、透明化的遠程方法調用
- 像調用本地方法一樣調用遠程方法;只需簡單配置,沒有任何API侵入。/2、軟負載均衡及容錯機制
可在內網替代nginx lvs等硬件負載均衡器。
3、服務註冊中心自動註冊 & 配置管理
-不需要寫死服務提供者地址,註冊中心基於接口名自動查詢提供者ip。
使用類似zookeeper等分布式協調服務作為服務註冊中心,可以將絕大部分項目配置移入zookeeper集群。
4、服務接口監控與治理
-Dubbo-admin與Dubbo-monitor提供了完善的服務接口管理與監控功能,針對不同應用的不同接口,可以進行 多版本,多協議,多註冊中心管理。
4.2、缺點
僅支持JAVA語言
5、Demo
5.1、簡介
註冊中心使用zookeeper,安裝使用可參見下面。
項目使用maven的構建方式,提供服務提供者和服務消費者,另外還需一個服務接口,共新建三個maven項目:dubbo-api、dubbo-provider、dubbo-consumer;
dubbo-api:服務接口,需單獨打包,供服務提供者和消費者使用;
dubbo-provider:服務提供者,依賴dubbo-api,實現其接口;
dubbo-consumer:服務消費者,依賴dubbo-api,調用服務提供者的服務;
Dubbo采用全Spring配置方式,透明化接入應用,對應用沒有任何API侵入,只需用spring加載Dubbo配置即可,基於spring的Schema擴展進行加載。
此demo需要用到spring、zookeeper、zkclient等jar包。使用spring-4.3.16.RELEASE、zookeeper.3.4.10、dubbo.2.5.2、zkclient.0.10
5.2、zookeeper安裝
詳見《zookeeper安裝》
5.3、dubbo-api
新建maven項目,此項目中提供一個服務接口:UserService,另為了方便接口間數據的交互可使用javabean,這裏提供一個User類,由於是網絡間的傳輸,需實現Serializable。
UserService
package cn.com.dubbo_api.service; import java.util.List; import cn.com.dubbo_api.entity.User; /** * * *<p>Title: UserService</p> * <p>Description: 用戶服務API</p> * <p>Company: </p> * @author Administrator * @date 2018年5月24日 上午10:30:59 */ public interface UserService { //批量新增 public int addUsers(List<User> users); //查詢所有 public List<User> findUsers(); //刪除 public int deleteUser(User user); //單個新增 public int addUser(User user); //更新 public int updateUser(User user); //查詢單個 public User findUser(User user); }
User
package cn.com.dubbo_api.entity; import java.io.Serializable; /** * * *<p>Title: User</p> * <p>Description:用戶實體類 </p> * <p>Company: </p> * @author Administrator * @date 2018年5月24日 上午10:30:43 */ public class User implements Serializable{ private Long id; private String name; private String address; private Integer age; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public User() { // TODO Auto-generated constructor stub } public User(Long id,String name,String address,Integer age) { // TODO Auto-generated constructor stub this.id=id; this.name=name; this.address=address; this.age=age; } @Override public String toString() { return "User [id=" + id + ", name=" + name + ", address=" + address + ", age=" + age + "]"; } }
5.4、dubbo-provider
新建maven項目,由於此為服務提供者故需引入spring、zookeeper等的jar包,還需引入dubbo-api,具體實現類為;
UserServiceImpl
package cn.com.dubbo_provider.serviceImpl; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import cn.com.dubbo_api.entity.User; import cn.com.dubbo_api.service.UserService; public class UserServiceImpl implements UserService { private Map<Long,User> userMap=new HashMap<Long,User>(); public int addUsers(List<User> users) { // TODO Auto-generated method stub int num=0; if(users!=null&&users.size()>0) { for (User user : users) { userMap.put(user.getId(), user); } num=users.size(); } return num; } public List<User> findUsers() { // TODO Auto-generated method stub if(isNull(userMap)) { return null; } List<User> users=new ArrayList<User>(); Set<Long> keySet=userMap.keySet(); for (Long id : keySet) { users.add(userMap.get(id)); } return users; } public int deleteUser(User user) { // TODO Auto-generated method stub if(isNull(userMap)) { return 0; } User delUser=userMap.remove(user.getId()); if(delUser!=null) { return 1; } return 0; } public int addUser(User user) { // TODO Auto-generated method stub userMap.put(user.getId(), user); return 1; } public int updateUser(User user) { // TODO Auto-generated method stub if(userMap.containsKey(user.getId())) { userMap.put(user.getId(), user); } return 1; } public User findUser(User user) { // TODO Auto-generated method stub return userMap.get(user.getId()); } //判斷Map是為空 public boolean isNull(Map map) { boolean b=false; if(map.isEmpty()) { b= true; } return b; } }
Spring的配置:spring-privider.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://code.alibabatech.com/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> <!-- 定義服務的實現接口 --> <bean id="userService" class="cn.com.dubbo_provider.serviceImpl.UserServiceImpl"></bean> <!--定義了提供方應用信息,用於計算依賴關系;在 dubbo-admin 或 dubbo-monitor 會顯示這個名字,方便辨識--> <dubbo:application name="demotest-provider" owner="programmer" organization="dubbox"/> <!--使用 zookeeper 註冊中心暴露服務,註意要先開啟 zookeeper--> <dubbo:registry address="zookeeper://192.168.199.128:2181"/> <!-- 用dubbo協議在20880端口暴露服務 --> <dubbo:protocol name="dubbo" port="20880" /> <!--使用 dubbo 協議實現定義好的 api.PermissionService 接口--> <dubbo:service interface="cn.com.dubbo_api.service.UserService" ref="userService" protocol="dubbo" /> </beans>
服務啟動類:
package cn.com.dubbo_provider; import java.io.IOException; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * Hello world! * */ public class App { public static void main( String[] args ) throws IOException { System.out.println( "Hello World!" ); ClassPathXmlApplicationContext cac=new ClassPathXmlApplicationContext("spring-provider.xml"); cac.start(); System.out.println("服務已經啟動..."); System.in.read(); } }
5.5、dubbo-consumer
新建maven項目,引入spring、zookeeper、dubbo-api的依賴。
由於是服務消費者則直接測試即可,下面看spring配置文件,
spring的配置文件:spring-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://code.alibabatech.com/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> <dubbo:application name="demotest-consumer" owner="programmer" organization="dubbox"/> <!--向 zookeeper 訂閱 provider 的地址,由 zookeeper 定時推送--> <dubbo:registry address="zookeeper://192.168.199.128:2181"/> <!--使用 dubbo 協議調用定義好的 api.PermissionService 接口--> <dubbo:reference id="permissionService" interface="cn.com.dubbo_api.service.UserService"/> </beans>
測試類:
package cn.com.dubbo_consumer; import java.util.List; import org.springframework.context.support.ClassPathXmlApplicationContext; import cn.com.dubbo_api.entity.User; import cn.com.dubbo_api.service.UserService; /** * Hello world! * */ public class App { public static void main( String[] args ) { System.out.println( "Hello consumer!" ); ClassPathXmlApplicationContext cac=new ClassPathXmlApplicationContext("spring-consumer.xml"); cac.start(); UserService us=cac.getBean(UserService.class); User u=new User(1l,"tom1","uc",22); int k=us.addUser(u); System.out.println("k:"+k); List<User> list=us.findUsers(); System.out.println(list.size()); for (User user : list) { System.out.println("user:"+user.toString()); } System.out.println(us.findUser(new User(3l,null,null,0))); } }
以上的三個項目,dubbo-api作為服務接口,只提供接口的定義,作為服務提供者和服務消費者的接口,需單獨打包。dubbo-provider和dubbo-consumer作為服務提供者和服務消費者分別打包、運行。
感謝,1046386199可交流!
dubbo入門(一)