• 在Dubbo中开发REST风格的远程调用(RESTful Remoting)


    PDF版:
     

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

     
    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协议)的支持。

    有鉴于此,我们基于标准的Java REST API——JAX-RS 2.0(Java API for RESTful Web Services的简写),为dubbo提供了接近透明的REST调用支持。由于完全兼容Java标准API,所以为dubbo开发的所有REST服务,未来脱离dubbo或者任何特定的REST底层实现一般也可以正常运行。

    特别值得指出的是,我们并不需要完全严格遵守REST的原始定义和架构风格。即使著名的Twitter REST API也会根据情况做适度调整,而不是机械的遵守原始的REST风格。

    附注:我们将这个功能称之为REST风格的远程调用,即RESTful Remoting(抽象的远程处理或者调用),而不是叫RESTful RPC(具体的远程“过程”调用),是因为REST和RPC本身可以被认为是两种不同的风格。在dubbo的REST实现中,可以说有两个面向,其一是提供或消费正常的REST服务,其二是将REST作为dubbo RPC体系中一种协议实现,而RESTful Remoting同时涵盖了这个面向。

    no image found

     

    标准的Restful框架JAX-RS(JAVATM API FOR RESTFUL WEB SEVICES),具体实现有:

        ①.Apache CXF——XFire和Celtix的合并(一个由IONA赞助的开源ESB,最初寄存在ObjectWeb上),开源的Web服务框架。

        ②.Jersey——Sun公司提供的JAX-RS的参考实现。

        ③.RESTEasy——Jboss公司的实现。

        ④.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等

    ...

     

     

     

     

     

     

     





    附件列表

  • 相关阅读:
    非root用户加入docker用户组省去sudo
    walle2.0 nginx.conf配置文件参数
    CentOS7.6 yum方式安装mysql2.7.25
    云服务器Ubuntu 14.04.2和centos7.5实现nfs挂载
    fs.inotify.max_user_watches默认值太小,导致too many open files
    CentOS7.X首次安装docker无法启动的问题解决
    【转载】Linux启动初始化配置文件浅析(解决source /etc/profile重启后就失效?)
    Apache:SSLCertificateFile:文件不存在或为空(操作系统RHEL7)
    20181023红帽学习笔记
    Undefined symbols for architecture x86_64:
  • 原文地址:https://www.cnblogs.com/douJiangYouTiao888/p/6473982.html
Copyright © 2020-2023  润新知