在Dubbo中開發REST風格的遠程調用(RESTful Remoting)

PDF版:
 

原文:http://dangdangdotcom.github.io/dubbox/rest.htmlphp

 
IBM的JAX-RS:http://www.ibm.com/developerworks/cn/java/j-lo-jaxrs/

概述:

dubbo支持多種遠程調用方式,例如dubbo RPC(二進制序列化 + tcp協議)、http invoker(二進制序列化 + http協議,至少在開源版本沒發現對文本序列化的支持)、hessian(二進制序列化 + http協議)、WebServices (文本序列化 + http協議)等等,但缺少對當今特別流行的REST風格遠程調用(文本序列化 + http協議)的支持。html

有鑑於此,咱們基於標準的Java REST API——JAX-RS 2.0(Java API for RESTful Web Services的簡寫),爲dubbo提供了接近透明的REST調用支持。因爲徹底兼容Java標準API,因此爲dubbo開發的全部REST服務,將來脫離dubbo或者任何特定的REST底層實現通常也能夠正常運行。java

特別值得指出的是,咱們並不須要徹底嚴格遵照REST的原始定義和架構風格。即便著名的Twitter REST API也會根據狀況作適度調整,而不是機械的遵照原始的REST風格。git

附註:咱們將這個功能稱之爲REST風格的遠程調用,即RESTful Remoting(抽象的遠程處理或者調用),而不是叫RESTful RPC(具體的遠程「過程」調用),是由於REST和RPC自己能夠被認爲是兩種不一樣的風格。在dubbo的REST實現中,能夠說有兩個面向,其一是提供或消費正常的REST服務,其二是將REST做爲dubbo RPC體系中一種協議實現,而RESTful Remoting同時涵蓋了這個面向。github

no image found

 

標準的Restful框架JAX-RS(JAVATM API FOR RESTFUL WEB SEVICES),具體實現有:web

    ①.Apache CXF——XFire和Celtix的合併(一個由IONA贊助的開源ESB,最初寄存在ObjectWeb上),開源的Web服務框架。spring

    ②.Jersey——Sun公司提供的JAX-RS的參考實現。json

    ③.RESTEasy——Jboss公司的實現。tomcat

    ④.Restlet——JAX-RS以前就存在的最先的REST框架。服務器

    ⑤.Apache Wink,一個Apache軟件基金會孵化器中的項目,其服務模塊實現JAX-RS規範

 

經常使用註解:

@PATH,接口請求的路徑

@GET、@PUT、@DELETE、@POST,分別對應着查、改、刪、增四種Http請求類型

@Produces,標記返回的MIME媒體類型。理解:能夠接受的出參類型,通常爲json、xml

@Consumes,標記可接受的MIME媒體類型。理解:能夠接受的入參類型。

@PathParam、@QueryParam、@FormParam、@HeaderParam、@CookieParam、@MatrixParam,請求參數的類型

 

 

Annotation放在接口類仍是實現類

 

通常放在實現類中,防止接口污染,保證接口的可維護性、可擴展性。

接口和實現類同時配置註解,則實現類生效,接口的註解會被直接忽略。

 

 

JSON、XML等多數據格式的支持

支持同時返回多種數據格式,好比同時返回json和xml,根據JAX-RS的標準,根據http中的MIME header決定使用哪一種類型的數據。
 

中文字符支持

編碼也能夠直接配置到註解中。
 

XML數據格式的額外要求

須要在返回對象的類上標註以下註解: @ XmlRootElement
返回基本數據類型則沒法被解析爲json或xml,可使用wrapper對象等方式來封裝返回。

 

 

定製序列化

dubbo中使用 JAXB作XML的序列化,使永jackson作json的序列化。能夠在對象上添加JAXB、jackson的相關注解實現定製序列化,如添加@JsonIgnore
 

配置REST Server的實現

單獨啓動進程,可使用嵌入式容器:
<dubbo:protocol name="rest" server="jetty"/>

 

非單獨啓動進程,可使用外部容器:

 

<dubbo:protocol name="rest" server="servlet"/>

 

web.xml:

 

<web-app>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/classes/META-INF/spring/dubbo-demo-provider.xml</param-value>
    </context-param>

    <listener>
        <listener-class>com.alibaba.dubbo.remoting.http.servlet.BootstrapListener</listener-class>
    </listener>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>com.alibaba.dubbo.remoting.http.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
</web-app>

 

 

即必須將dubbo的BootstrapListener和DispatherServlet添加到web.xml,以完成dubbo的REST功能與外部servlet容器的集成。

注意:若是你是用spring的ContextLoaderListener來加載spring,則必須保證BootstrapListener配置在ContextLoaderListener以前,不然dubbo初始化會出錯。

其實,這種場景下你依然能夠堅持用嵌入式server,但外部應用服務器的servlet容器每每比嵌入式server更增強大(特別是若是你是部署到更健壯更可伸縮的WebLogic,WebSphere等),另外有時也便於在應用服務器作統一管理、監控等等。

 

 

獲取上下文(Context)信息

第一種方式,用JAX-RS標準的@Context annotation:

public User getUser(@PathParam("id") Long id, @Context HttpServletRequest request) {
    System.out.println("Client address is " + request.getRemoteAddr());
} 

 

 

第二種方式,用dubbo中經常使用的RpcContext:(代碼具備入侵式,將來可能重構,server=jetty、tomcat、servlet、tjws才能用)

public User getUser(@PathParam("id") Long id) {
    System.out.println("Client address is " + RpcContext.getContext().getRemoteAddressString());
} 

 

 

 

 

配置端口號和Context Path

端口默認80
<dubbo:protocol name="rest" port="8888"/>

 

web上下午contextPath配置:

 

<dubbo:protocol name="rest" port="8888" contextpath="services" server="servlet"/>

 

 

 

配置線程數和IO線程數

配置長鏈接

配置最大的HTTP鏈接數

配置每一個消費端的超時時間和HTTP鏈接數

...

詳見PDF

 

GZIP數據壓縮(不推薦)

Dubbo的REST支持用GZIP壓縮請求和響應的數據,以減小網絡傳輸時間和帶寬佔用,但這種方式會也增長CPU開銷。

 

 

 

用Annotation取代部分Spring XML配置

 

 

添加自定義的Filter、Interceptor等

 

...

 

 

 

 

 

 

 





附件列表

相關文章
相關標籤/搜索