【SSM框架】Spring整合Dubbo服務(附帶原始碼)
本專案是在上一篇搭建的SSM框架的基礎上做的,同樣是一個非maven的傳統web專案。
與傳統軟體行業不同的是,網際網路產品多是高併發的。高併發就需要從硬體和軟體兩方面共同來解決。阿里巴巴的大牛攻城獅們提供了一套解決高併發的框架---Dubbo。看過相關的文章,個人的理解就是,將我們傳統所寫的單一服務做成Dubbo服務,並將該服務釋出註冊,阿里dubbo團隊推薦的是zookeeper,將dubbo服務註冊在zookeeper中,每個dubbo服務都會有服務的釋出者和服務的消費者,釋出者將服務釋出在zookeeper中,消費者去zookeeper中獲取自己需要的服務。從而實現程式的解耦。當請求的併發量增加時,採用訊息佇列,將所有的請求仍在佇列中,按照資源的先後順序請求服務。從而解決高併發的問題。 以上只是個人對於Dubbo粗淺的認識,歡迎糾正。
好了,廢話不多說。本文是在同一個專案之下,建立了一個dubbo服務,並用main方法模擬這個服務的消費者。
開始之前 推薦兩篇文章,裡面詳細的講了 如何配置zookeeper伺服器,和dubbo admin服務(檢視dubbo服務數量)。這裡就不多說了哈。
開始正題,在上一篇的搭建好的框架的基礎上進行修改。
1、建立Dubbo單獨的程式碼包
建立單獨的程式碼包,將原先的Test下的包移到這個下面。
建立DubboAppNewsService介面類:
注意:@Server是org.springframework.stereotype.Service包下的,不是 dubbo包下的。
package com.weikai.dubboServer.service; import org.springframework.stereotype.Service; import com.weikai.common.AppReply; import com.weikai.dubboServer.entity.DubboAppNews; @Service public interface DubboAppNewsService { public AppReply<DubboAppNews> findAll(String pageSize,String pageNumber); }
建立DubboAppNewsService介面實現類DubboAppNewsServiceImpl:
package com.weikai.dubboServer.service.impl;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import com.weikai.common.AppReply;
import com.weikai.dubboServer.dao.DubboAppNewsDao;
import com.weikai.dubboServer.entity.DubboAppNews;
import com.weikai.dubboServer.service.DubboAppNewsService;
import com.weikai.test.entity.AppNews;
@Service
public class DubboAppNewsServiceImpl implements DubboAppNewsService {
@Resource
private DubboAppNewsDao dao;
@Override
@SuppressWarnings("null")
public AppReply<DubboAppNews> findAll(String pageSize,String pageNumber){
AppReply<DubboAppNews> reply = new AppReply<DubboAppNews>();
Map<String, Object> parpam = new HashMap<String, Object>();
List<AppNews> appList = null;
parpam.put("pageNumber", (Integer.parseInt(pageNumber)-1) * Integer.parseInt(pageSize));
parpam.put("pageSize", Integer.valueOf(pageSize));
appList = dao.findAll(parpam);
if(appList != null || appList.size() > 0){
reply.setCode("0");
reply.setMsg("查詢資料成功!");
reply.setObj(appList);
}else{
reply.setCode("1");
reply.setMsg("查詢資料為空!");
reply.setObj(new ArrayList<AppNews>());
}
return reply;
}
}
建立DubboAppNewsDao介面和對應表的實體類:
實體類是資料庫中自己的表,這裡就不展示實體類了,可以根據自己專案的實際情況修改這兩部分內容。同時記得修改mapper檔案。
package com.weikai.dubboServer.dao;
import java.util.List;
import java.util.Map;
import com.weikai.test.entity.AppNews;
public interface DubboAppNewsDao {
public List<AppNews> findAll(Map<String, Object> parpam);
}
2、注入dubbo服務提供者
建立好service層後,需要將service層注入到Spring中 並做成dubbo服務,對外暴露介面。
首先建立一個spring-context-dubbo-myProvider.xml,這裡注意名字,因為之前的專案web.xml中是採用萬用字元配置的,所以這個時候只需要起名為spring-context-*.xml即可,並且不用在配置web.xml檔案。
spring-context-dubbo-myProvider.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服務,具體的實現bean -->
<bean id="dubboProvider" class="com.weikai.dubboServer.service.impl.DubboAppNewsServiceImpl" />
<!-- 提供方應用資訊,用於計算依賴關係 -->
<dubbo:application name="dubboProviderRef" />
<!-- 使用multicast廣播註冊中心暴露服務地址 -->
<!--<dubbo:registry address="multicast://224.5.6.7:1234" /> -->
<!-- 使用zookeeper註冊中心暴露服務地址 即zookeeper的所在伺服器ip地址和埠號 -->
<dubbo:registry address="zookeeper://172.16.67.183:2181" />
<!-- 用dubbo協議在20880埠暴露服務 -->
<dubbo:protocol name="dubbo" port="20888" />
<!-- 宣告需要暴露的服務介面 -->
<dubbo:service interface="com.weikai.dubboServer.service.DubboAppNewsService"
ref="dubboProvider" />
</beans>
這裡會出現一個問題,就是<dubbo:application>這個 標籤可能會報錯,處理辦法如下:
如果按照上述方法處理完了 還是報錯,請檢視xml中是否引入xmlns:dubbo="http://code.alibabatech.com/schema/dubbo 等標籤引入語句。
至此服務者已經處理完畢,啟動服務 即可在Dubbo admin中檢視到服務資訊。可以看到這個服務目前是沒有 消費者的。
3、建立消費者類。
服務已經發布,必須要有消費者呼叫,所以我們在單個專案中使用main()方法呼叫服務。建立GetNewsConsumer這個類。並帶main方法。
GetNewsConsumer類:
package com.weikai.dubboConsumer;
import java.util.List;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.weikai.common.AppReply;
import com.weikai.dubboServer.entity.DubboAppNews;
import com.weikai.dubboServer.service.DubboAppNewsService;
public class GetNewsConsumer {
public static void main(String[] args) {
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("spring-dubbo-myConsumer.xml");
String pageSize = "10";
String pageNumber = "1";
ctx.start();
DubboAppNewsService dubboAppNewsService = (DubboAppNewsService) ctx.getBean("dubboProviderRef");
AppReply<DubboAppNews> appReply = dubboAppNewsService.findAll(pageSize, pageNumber);
@SuppressWarnings("unchecked")
List<DubboAppNews> news = (List<DubboAppNews>)appReply.getObj();
for (int i = 0; i < news.size(); i++) {
System.out.print(news.get(i).getId());
System.out.print("\t");
System.out.print(news.get(i).getKeyword());
System.out.print("\t");
System.out.print(news.get(i).getTitle());
System.out.print("\t");
System.out.print(news.get(i).getThumbnailL());
System.out.print("\t");
System.out.print(news.get(i).getThumbnailM());
System.out.print("\t");
System.out.print(news.get(i).getDescrption());
System.out.print("\t");
System.out.print(news.get(i).getContent());
System.out.println();
}
try {
Thread.sleep(500000);
} catch (InterruptedException e) {
e.printStackTrace();
}
ctx.close();
}
}
4、將消費者註冊到容器中
建立spring-dubbo-myConsumer.xml配置檔案,將消費者註冊到伺服器中。注意取名不能取spring-context-*開頭,因為這樣按照我們之前的配置Spring就會同時載入服務者和消費者這樣就會導致dubbo檔案兩次載入從而報錯。在同一個專案下部署dubbo時一定保證服務著在Spring啟動的時候 就啟動,而消費者 則在容器啟動後 再載入。
spring-dubbo-myConsumer.xml檔案內容:
注意:服務者和消費者必須公用API,即必須指向同一個service。
<?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="dubboConsumer" />
<!-- 使用zookeeper註冊中心暴露服務地址 -->
<!-- <dubbo:registry address="multicast://224.5.6.7:1234" /> -->
<dubbo:registry address="zookeeper://172.16.67.183:2181" />
<!-- 用dubbo協議在20880埠暴露服務 -->
<dubbo:protocol name="dubbo" port="20888" />
<!-- 生成遠端服務代理,可以像使用本地bean一樣使用demoService -->
<dubbo:reference id="dubboProviderRef"
interface="com.weikai.dubboServer.service.DubboAppNewsService" />
</beans>
4、測試
測試步驟:
1、啟動web專案,保證啟動不報錯,並在 dubbo admin中能夠看到釋出的服務。
2、執行main方法。呼叫服務。
啟動專案之前zookeeper服務必須啟動!!!
測試結果:
dubbo admin介面:
由於我們短時間 執行了三次main方法,所以這裡會有三個消費者。
SSM完美集成了Dubbo服務,歡迎有問題一起探討。