簡單說下接觸webservice的背景吧,因為之前的接口對接更多的是成熟的接口品牌像是阿里巴巴、騰訊、聚合數據等,他們接口規范一般都是基於restful進行接口對接。什么是restful接口,可以通過這篇文章了解《簡單易懂的restful接口規范》。言歸正傳,就是當下的項目中因為對接保險公司一些業務,所以對接的協議是通過web service進行對接,我認為,是很old的技術,但是對於我來說挺新的知識。正如簡單描述可知,目前對於web service的通信協議其實越來越少了,不排除有一些比較喜歡老技術的公司,繼續沿用這種方式,至於為什么,在下面文章中詳細闡述。
什么是web service?怎么進行web service協議接口調用?web service和其他通信協議像是dubbo、hessian、RMI、thrif區別在哪里?下面標題解答:
一 什么是web service?
首先,web service是一種接口遠程對接協議,通過這種協議編寫的接口能跨平台和跨語言,跨項目,也就是一處編寫部署,其他處處調用。對於項目開發中不建議使用,對外項目研發中,可以使用。早先的傳輸方式通過SOAP協議,然后通過WSDL(web service description language)web服務描述語言展示,這種方式就是我們公司才用的方式,比較old的一種方式,最新的方式是遵循RESTful規則,通過最簡單的 http 協議傳輸數據 ( 包括 xml 或 json) ,既簡化了設計,也減少了網絡傳輸量(因為只傳輸代表數據的 xml 或 json ,沒有額外的 xml 包裝)。
web service相對http (post/get)有好處嗎?
1.接口中實現的方法和要求參數一目了然,通過WSDL可以查詢,具體想學習WSDL可以參考這篇文章《簡單易懂的restful接口規范》如下圖所示:
調用測試WSDL的網址,可以通過 http://www.webxml.com.cn/zh_cn/web_services.aspx
2.不用擔心大小寫問題(這里說的大小寫問題,是對於輸入的參數值,不需要注意大小寫)
3.不用擔心中文urlencode問題
4.代碼中不用多次聲明認證(賬號,密碼)參數
5.傳遞參數可以為數組,對象等...(因為是基於SOAP對象傳輸協議,所以XML能容納一切)
web service相對http(post/get)快嗎?
由於要進行xml解析,速度可能會有所降低。調用接口時候,需要轉換為XML對象,接收接口時候,需要通過把XML文件轉為對象。
XStreamUtils.xmltoBean(result, ReturnInfo.class);
web service 可以被http(post/get)替代嗎?
完全可以,而且現在的開放平台都是用的HTTP(post/get)實現的。
二 怎么進行web service協議接口調用?
1、對於web service接口的調用,傳統代碼調用方式:
Call call = (Call) service.createCall(); String path = bean.getPath(); String nameSpace = bean.getNameSpace(); call.setTargetEndpointAddress(path); QName qName = new QName(nameSpace, "testService"); call.setOperationName(qName); call.setUseSOAPAction(true); call.addParameter("param1", XMLType.XSD_STRING, ParameterMode.IN); call.addParameter("param1", XMLType.XSD_STRING, ParameterMode.IN); call.setReturnType(XMLType.XSD_STRING); result = (String) call.invoke(new Object[] { "001001", xml });
2、推薦一個超級強大的工具類,https://hutool.cn/docs/#/
import cn.hutool.http.webservice.SoapClient; /** * @author admin * @date 2019/11/29 13:55 */ public class Test { public static final String url1 = "http://www.webxml.com.cn/WebServices/IpAddressSearchWebService.asmx"; public static final String url2 = "http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx?wsdl"; public static final String url3 = "http://ws.webxml.com.cn/WebServices/TrainTimeWebService.asmx?wsdl"; public static final String url4 = "http://fy.webxml.com.cn/webservices/EnglishChinese.asmx?wsdl"; public static void main(String[] args) { String message = ""; // message = getMobileAddress(); message = getChinese(); System.out.println(message); } /** * 中文翻譯 */ public static String getChinese() { // 新建客戶端 SoapClient client = SoapClient.create(url4) // 設置要請求的方法,此接口方法前綴為web,傳入對應的命名空間 .setMethod("web:TranslatorString", "http://WebXml.com.cn/") // 設置參數,此處自動添加方法的前綴:web .setParam("wordKey", "make MONEY"); // 發送請求,參數true表示返回一個格式化后的XML內容 // 返回內容為XML字符串,可以配合XmlUtil解析這個響應 return client.send(true); } }
三 web service和其他通信協議像是dubbo、hessian、RMI、thrif區別在哪里?

1、dubbo傳入傳出參數數據包較小(建議小於100K),消費者比提供者個數多,單一消費者無法壓滿提供者,盡量不要用dubbo協議傳輸大文件或超大字符串
為什么要消費者比提供者個數多:
因dubbo協議采用單一長連接,
假設網絡為千兆網卡(1024Mbit=128MByte),
根據測試經驗數據每條連接最多只能壓滿7MByte(不同的環境可能不一樣,供參考),
理論上1個服務提供者需要20個服務消費者才能壓滿網卡。
為什么不能傳大包:
因dubbo協議采用單一長連接,
如果每次請求的數據包大小為500KByte,假設網絡為千兆網卡(1024Mbit=128MByte),每條連接最大7MByte(不同的環境可能不一樣,供參考),
單個服務提供者的TPS(每秒處理事務數)最大為:128MByte / 500KByte = 262。
單個消費者調用單個服務提供者的TPS(每秒處理事務數)最大為:7MByte / 500KByte = 14。
如果能接受,可以考慮使用,否則網絡將成為瓶頸。
為什么采用異步單一長連接:
因為服務的現狀大都是服務提供者少,通常只有幾台機器,
而服務的消費者多,可能整個網站都在訪問該服務,
比如Morgan的提供者只有6台提供者,卻有上百台消費者,每天有1.5億次調用,
如果采用常規的hessian服務,服務提供者很容易就被壓跨,
通過單一連接,保證單一消費者不會壓死提供者,
長連接,減少連接握手驗證等,
並使用異步IO,復用線程池,防止C10K問題。
2、RMI
RMI協議采用JDK標准的java.rmi.*實現,采用阻塞式短連接和JDK標准序列化方式
3、Hessian協議
Hessian協議用於集成Hessian的服務,Hessian底層采用Http通訊,采用Servlet暴露服務,Dubbo缺省內嵌Jetty作為服務器實現
4、http
采用Spring的HttpInvoker實現
5、thrif
Thrift是Facebook捐給Apache的一個RPC框架,當前 dubbo 支持的 thrift 協議是對 thrift 原生協議的擴展,在原生協議的基礎上添加了一些額外的頭信息,比如service name,magic number等。
參考文章
https://www.cnblogs.com/h-c-g/p/10870913.html
https://blog.csdn.net/zh521zh/article/details/76445520
https://blog.csdn.net/f1ame1/article/details/80506929