blob: 1a110f795ad5367b1c3d1b0e52d57b2dd181f87d [file] [log] [blame]
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Apache Dubbo – User Documentation</title><link>https://dubbo.apache.org/en/docs/v2.7/user/</link><description>Recent content in User Documentation on Apache Dubbo</description><generator>Hugo -- gohugo.io</generator><language>en</language><atom:link href="https://dubbo.apache.org/en/docs/v2.7/user/index.xml" rel="self" type="application/rss+xml"/><item><title>Docs: Preface</title><link>https://dubbo.apache.org/en/docs/v2.7/user/preface/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/en/docs/v2.7/user/preface/</guid><description/></item><item><title>Docs: Quick start</title><link>https://dubbo.apache.org/en/docs/v2.7/user/quick-start/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/en/docs/v2.7/user/quick-start/</guid><description>
&lt;p>The most common way to use Dubbo is to run it in Spring framework. The following content will guide you to develop a Dubbo application with Spring framework&amp;rsquo;s &lt;a href="https://docs.spring.io/spring/docs/4.2.x/spring-framework-reference/html/xsd-configuration.html">XML configuration&lt;/a>.&lt;/p>
&lt;p>If you don&amp;rsquo;t want to rely on Spring, you can try using &lt;a href="../configuration/api">API configuration&lt;/a>.&lt;/p>
&lt;p>First let&amp;rsquo;s create a root directory called dubbo-demo:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>mkdir dubbo-demo
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#b58900">cd&lt;/span> dubbo-demo
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Next, we are going to create 3 sub-directories under root directory:&lt;/p>
&lt;ul>
&lt;li>dubbo-demo-api: the common service api&lt;/li>
&lt;li>dubbo-demo-provider: the demo provider codes&lt;/li>
&lt;li>dubbo-demo-consumer: the demo consumer codes&lt;/li>
&lt;/ul>
&lt;h2 id="service-provider">Service provider&lt;/h2>
&lt;h3 id="defining-service-interfaces">Defining service interfaces&lt;/h3>
&lt;p>DemoService.java &lt;sup id="fnref:1">&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref">1&lt;/a>&lt;/sup>:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">package&lt;/span> org.apache.dubbo.demo;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">interface&lt;/span> &lt;span style="color:#268bd2">DemoService&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> String &lt;span style="color:#268bd2">sayHello&lt;/span>(String name);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The project structure should look like this:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>.
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>├── dubbo-demo-api
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   ├── pom.xml
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   └── src
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   └── main
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   └── java
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   └── org
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   └── apache
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   └── dubbo
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   └── demo
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   └── DemoService.java
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="implement-interface-in-service-provider">Implement interface in service provider&lt;/h3>
&lt;p>DemoServiceImpl.java &lt;sup id="fnref:2">&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref">2&lt;/a>&lt;/sup>:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">package&lt;/span> org.apache.dubbo.demo.provider;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.demo.DemoService;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">DemoServiceImpl&lt;/span> &lt;span style="color:#268bd2">implements&lt;/span> DemoService {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> String &lt;span style="color:#268bd2">sayHello&lt;/span>(String name) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">return&lt;/span> &lt;span style="color:#2aa198">&amp;#34;Hello &amp;#34;&lt;/span> &lt;span style="color:#719e07">+&lt;/span> name;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="exposing-service-with-spring-configuration">Exposing service with Spring configuration&lt;/h3>
&lt;p>provider.xml:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;beans&lt;/span> xmlns:xsi=&lt;span style="color:#2aa198">&amp;#34;http://www.w3.org/2001/XMLSchema-instance&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> xmlns:dubbo=&lt;span style="color:#2aa198">&amp;#34;http://dubbo.apache.org/schema/dubbo&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> xmlns=&lt;span style="color:#2aa198">&amp;#34;http://www.springframework.org/schema/beans&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> xsi:schemaLocation=&lt;span style="color:#2aa198">&amp;#34;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#2aa198"> http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd&amp;#34;&lt;/span>&lt;span style="color:#268bd2">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">&amp;lt;!-- provider&amp;#39;s application name, used for tracing dependency relationship --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;dubbo:application&lt;/span> name=&lt;span style="color:#2aa198">&amp;#34;demo-provider&amp;#34;&lt;/span>&lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">&amp;lt;!-- use multicast registry center to export service --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;dubbo:registry&lt;/span> address=&lt;span style="color:#2aa198">&amp;#34;multicast://224.5.6.7:1234&amp;#34;&lt;/span>&lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">&amp;lt;!-- use dubbo protocol to export service on port 20880 --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;dubbo:protocol&lt;/span> name=&lt;span style="color:#2aa198">&amp;#34;dubbo&amp;#34;&lt;/span> port=&lt;span style="color:#2aa198">&amp;#34;20880&amp;#34;&lt;/span>&lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">&amp;lt;!-- service implementation, as same as regular local bean --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;bean&lt;/span> id=&lt;span style="color:#2aa198">&amp;#34;demoService&amp;#34;&lt;/span> class=&lt;span style="color:#2aa198">&amp;#34;org.apache.dubbo.demo.provider.DemoServiceImpl&amp;#34;&lt;/span>&lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">&amp;lt;!-- declare the service interface to be exported --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;dubbo:service&lt;/span> interface=&lt;span style="color:#2aa198">&amp;#34;org.apache.dubbo.demo.DemoService&amp;#34;&lt;/span> ref=&lt;span style="color:#2aa198">&amp;#34;demoService&amp;#34;&lt;/span>&lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;/beans&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The demo uses multicast as the registry since it is simple and does not require to extra installation.
If you prefer a registry like zookeeper, please check out examples &lt;a href="https://github.com/dubbo/dubbo-samples">here&lt;/a>.&lt;/p>
&lt;h3 id="configure-the-logging-system">Configure the logging system&lt;/h3>
&lt;p>Dubbo use log4j as logging system by default, it also support slf4j, Apache Commons Logging, and JUL logging.&lt;/p>
&lt;p>Following is a sample configuration:&lt;/p>
&lt;p>log4j.properties&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-properties" data-lang="properties">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">###set log levels###&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>log4j.rootLogger&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">info, stdout&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">###output to the console###&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>log4j.appender.stdout&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">org.apache.log4j.ConsoleAppender&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>log4j.appender.stdout.Target&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">System.out&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>log4j.appender.stdout.layout&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">org.apache.log4j.PatternLayout&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>log4j.appender.stdout.layout.ConversionPattern&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">[%d{dd/MM/yy hh:mm:ss:sss z}] %t %5p %c{2}: %m%n&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="bootstrap-the-service-provider">Bootstrap the service provider&lt;/h3>
&lt;p>Provider.java&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">package&lt;/span> org.apache.dubbo.demo.provider;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.springframework.context.support.ClassPathXmlApplicationContext;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">Provider&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">static&lt;/span> &lt;span style="color:#dc322f">void&lt;/span> &lt;span style="color:#268bd2">main&lt;/span>(String&lt;span style="color:#719e07">[]&lt;/span> args) &lt;span style="color:#268bd2">throws&lt;/span> Exception {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> System.setProperty(&lt;span style="color:#2aa198">&amp;#34;java.net.preferIPv4Stack&amp;#34;&lt;/span>, &lt;span style="color:#2aa198">&amp;#34;true&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ClassPathXmlApplicationContext context &lt;span style="color:#719e07">=&lt;/span> &lt;span style="color:#719e07">new&lt;/span> ClassPathXmlApplicationContext(&lt;span style="color:#719e07">new&lt;/span> String&lt;span style="color:#719e07">[]&lt;/span>{&lt;span style="color:#2aa198">&amp;#34;META-INF/spring/dubbo-demo-provider.xml&amp;#34;&lt;/span>});
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> context.start();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> System.out.println(&lt;span style="color:#2aa198">&amp;#34;Provider started.&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> System.in.read(); &lt;span style="color:#586e75">// press any key to exit&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Finally, the project structure should look like this:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>├── dubbo-demo-provider
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   ├── pom.xml
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   └── src
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   └── main
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   ├── java
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   │   └── org
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   │   └── apache
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   │   └── dubbo
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   │   └── demo
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   │   └── provider
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   │   ├── DemoServiceImpl.java
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   │   └── Provider.java
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   └── resources
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   ├── META-INF
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   │   └── spring
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   │   └── dubbo-demo-provider.xml
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   └── log4j.properties
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="service-consumer">Service consumer&lt;/h2>
&lt;p>Complete installation steps, see:&lt;a href="../../admin/install/consumer-demo">Consumer demo installation&lt;/a>&lt;/p>
&lt;h3 id="using-the-spring-configuration-to-reference-a-remote-service">Using the Spring configuration to reference a remote service&lt;/h3>
&lt;p>consumer.xml:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">&amp;lt;?xml version=&amp;#34;1.0&amp;#34; encoding=&amp;#34;UTF-8&amp;#34;?&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;beans&lt;/span> xmlns:xsi=&lt;span style="color:#2aa198">&amp;#34;http://www.w3.org/2001/XMLSchema-instance&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> xmlns:dubbo=&lt;span style="color:#2aa198">&amp;#34;http://dubbo.apache.org/schema/dubbo&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> xmlns=&lt;span style="color:#2aa198">&amp;#34;http://www.springframework.org/schema/beans&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> xsi:schemaLocation=&lt;span style="color:#2aa198">&amp;#34;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#2aa198"> http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd&amp;#34;&lt;/span>&lt;span style="color:#268bd2">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">&amp;lt;!-- consumer&amp;#39;s application name, used for tracing dependency relationship (not a matching criterion),
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> don&amp;#39;t set it same as provider --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;dubbo:application&lt;/span> name=&lt;span style="color:#2aa198">&amp;#34;demo-consumer&amp;#34;&lt;/span>&lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">&amp;lt;!-- use multicast registry center to discover service --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;dubbo:registry&lt;/span> address=&lt;span style="color:#2aa198">&amp;#34;multicast://224.5.6.7:1234&amp;#34;&lt;/span>&lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">&amp;lt;!-- generate proxy for the remote service, then demoService can be used in the same way as the
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> local regular interface --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;dubbo:reference&lt;/span> id=&lt;span style="color:#2aa198">&amp;#34;demoService&amp;#34;&lt;/span> check=&lt;span style="color:#2aa198">&amp;#34;false&amp;#34;&lt;/span> interface=&lt;span style="color:#2aa198">&amp;#34;org.apache.dubbo.demo.DemoService&amp;#34;&lt;/span>&lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;/beans&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="bootstrap-the-consumer">Bootstrap the consumer&lt;/h3>
&lt;p>Consumer.java &lt;sup id="fnref:3">&lt;a href="#fn:3" class="footnote-ref" role="doc-noteref">3&lt;/a>&lt;/sup>:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.springframework.context.support.ClassPathXmlApplicationContext;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.demo.DemoService;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">Consumer&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">static&lt;/span> &lt;span style="color:#dc322f">void&lt;/span> &lt;span style="color:#268bd2">main&lt;/span>(String&lt;span style="color:#719e07">[]&lt;/span> args) &lt;span style="color:#268bd2">throws&lt;/span> Exception {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ClassPathXmlApplicationContext context &lt;span style="color:#719e07">=&lt;/span> &lt;span style="color:#719e07">new&lt;/span> ClassPathXmlApplicationContext(&lt;span style="color:#719e07">new&lt;/span> String&lt;span style="color:#719e07">[]&lt;/span> {&lt;span style="color:#2aa198">&amp;#34;META-INF/spring/dubbo-demo-consumer.xml&amp;#34;&lt;/span>});
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> context.start();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// Obtaining a remote service proxy&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> DemoService demoService &lt;span style="color:#719e07">=&lt;/span> (DemoService)context.getBean(&lt;span style="color:#2aa198">&amp;#34;demoService&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// Executing remote methods&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> String hello &lt;span style="color:#719e07">=&lt;/span> demoService.sayHello(&lt;span style="color:#2aa198">&amp;#34;world&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// Display the call result&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> System.out.println(hello);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="config-the-logging-system">Config the logging system&lt;/h3>
&lt;p>This is the same as how to config it on provider side.&lt;/p>
&lt;p>Finally, the project structure should be look like this:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>├── dubbo-demo-consumer
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   ├── pom.xml
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   └── src
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   └── main
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   ├── java
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   │   └── org
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   │   └── apache
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   │   └── dubbo
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   │   └── demo
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   │   └── consumer
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   │   └── Consumer.java
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   └── resources
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   ├── META-INF
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   │   └── spring
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   │   └── dubbo-demo-consumer.xml
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   └── log4j.properties
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="start-the-demo">Start the demo&lt;/h2>
&lt;h3 id="start-service-provider">Start service provider&lt;/h3>
&lt;p>Run the &lt;code>org.apache.dubbo.demo.provider.Provider&lt;/code> class to start the provider.&lt;/p>
&lt;h3 id="start-service-consumer">Start service consumer&lt;/h3>
&lt;p>Run the &lt;code>org.apache.dubbo.demo.provider.Consumer&lt;/code> class to start the consumer, and you should be able to see the following result:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>Hello world
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="complete-example">Complete example&lt;/h2>
&lt;p>You can find the complete example code in the Github repository.&lt;/p>
&lt;ul>
&lt;li>&lt;a href="../../admin/install/provider-demo">Provider demo&lt;/a>&lt;/li>
&lt;li>&lt;a href="../../admin/install/consumer-demo">Consumer demo&lt;/a>&lt;/li>
&lt;/ul>
&lt;div class="footnotes" role="doc-endnotes">
&lt;hr>
&lt;ol>
&lt;li id="fn:1">
&lt;p>The interface needs to be packaged separately, shared by the service provider and the consumer&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink">&amp;#x21a9;&amp;#xfe0e;&lt;/a>&lt;/p>
&lt;/li>
&lt;li id="fn:2">
&lt;p>Hidden realization for service consumer&amp;#160;&lt;a href="#fnref:2" class="footnote-backref" role="doc-backlink">&amp;#x21a9;&amp;#xfe0e;&lt;/a>&lt;/p>
&lt;/li>
&lt;li id="fn:3">
&lt;p>IoC injection can also be used&amp;#160;&lt;a href="#fnref:3" class="footnote-backref" role="doc-backlink">&amp;#x21a9;&amp;#xfe0e;&lt;/a>&lt;/p>
&lt;/li>
&lt;/ol>
&lt;/div></description></item><item><title>Docs: Dependencies</title><link>https://dubbo.apache.org/en/docs/v2.7/user/dependencies/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/en/docs/v2.7/user/dependencies/</guid><description>
&lt;h2 id="necessary-dependencies">Necessary dependencies&lt;/h2>
&lt;p>JDK 1.6+ &lt;sup id="fnref:1">&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref">1&lt;/a>&lt;/sup>&lt;/p>
&lt;h2 id="default-dependencies">Default dependencies&lt;/h2>
&lt;p>use &lt;code>mvn dependency:tree &amp;gt; dep.log&lt;/code> command to analysis,Dubbo default depends on the following 3rd party libraries:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">[&lt;/span>INFO&lt;span style="color:#719e07">]&lt;/span> +- com.alibaba:dubbo:jar:2.5.9-SNAPSHOT:compile
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">[&lt;/span>INFO&lt;span style="color:#719e07">]&lt;/span> | +- org.springframework:spring-context:jar:4.3.10.RELEASE:compile
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">[&lt;/span>INFO&lt;span style="color:#719e07">]&lt;/span> | +- org.javassist:javassist:jar:3.21.0-GA:compile
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">[&lt;/span>INFO&lt;span style="color:#719e07">]&lt;/span> | &lt;span style="color:#cb4b16">\-&lt;/span> org.jboss.netty:netty:jar:3.2.5.Final:compile
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>All dependencies here are selected for the default configuration of the Dubbo, which are based on stability and performance considerations.&lt;/p>
&lt;ul>
&lt;li>javassist.jar &lt;sup id="fnref:2">&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref">2&lt;/a>&lt;/sup>: if &lt;code>&amp;lt;dubbo:provider proxy=&amp;quot;jdk&amp;quot; /&amp;gt;&lt;/code> or &lt;code>&amp;lt;dubbo:consumer proxy=&amp;quot;jdk&amp;quot; /&amp;gt;&lt;/code>,or &lt;code>&amp;lt;dubbo:application compiler=&amp;quot;jdk&amp;quot; /&amp;gt;&lt;/code>, is not required.&lt;/li>
&lt;li>spring-context.jar &lt;sup id="fnref:3">&lt;a href="#fn:3" class="footnote-ref" role="doc-noteref">3&lt;/a>&lt;/sup>: If you are using &lt;code>ServiceConfig&lt;/code> and &lt;code>ReferenceConfig&lt;/code> API calls, is not required.&lt;/li>
&lt;li>netty.jar &lt;sup id="fnref:4">&lt;a href="#fn:4" class="footnote-ref" role="doc-noteref">4&lt;/a>&lt;/sup>: if &lt;code>&amp;lt;dubbo:protocol server=&amp;quot;mina&amp;quot;/&amp;gt;&lt;/code> or &lt;code>&amp;lt;dubbo:protocol server=&amp;quot;grizzly&amp;quot;/&amp;gt;&lt;/code>,Then change to mina.jar or grizzly.jar. If &lt;code>&amp;lt;protocol name=&amp;quot;rmi&amp;quot;/&amp;gt;&lt;/code>, is not required.&lt;/li>
&lt;/ul>
&lt;h2 id="optional-dependencies">Optional dependencies&lt;/h2>
&lt;p>These dependencies needs to be added to project manually,when you need them.&lt;/p>
&lt;ul>
&lt;li>netty-all 4.0.35.Final&lt;/li>
&lt;li>mina: 1.1.7&lt;/li>
&lt;li>grizzly: 2.1.4&lt;/li>
&lt;li>httpclient: 4.5.3&lt;/li>
&lt;li>hessian_lite: 3.2.1-fixed&lt;/li>
&lt;li>fastjson: 1.2.31&lt;/li>
&lt;li>zookeeper: 3.4.9&lt;/li>
&lt;li>jedis: 2.9.0&lt;/li>
&lt;li>xmemcached: 1.3.6&lt;/li>
&lt;li>hessian: 4.0.38&lt;/li>
&lt;li>jetty: 6.1.26&lt;/li>
&lt;li>hibernate-validator: 5.4.1.Final&lt;/li>
&lt;li>zkclient: 0.2&lt;/li>
&lt;li>curator: 2.12.0&lt;/li>
&lt;li>cxf: 3.0.14&lt;/li>
&lt;li>thrift: 0.8.0&lt;/li>
&lt;li>servlet: 3.0 &lt;sup id="fnref:5">&lt;a href="#fn:5" class="footnote-ref" role="doc-noteref">5&lt;/a>&lt;/sup>&lt;/li>
&lt;li>validation-api: 1.1.0.GA &lt;sup id="fnref1:5">&lt;a href="#fn:5" class="footnote-ref" role="doc-noteref">5&lt;/a>&lt;/sup>&lt;/li>
&lt;li>jcache: 1.0.0 &lt;sup id="fnref2:5">&lt;a href="#fn:5" class="footnote-ref" role="doc-noteref">5&lt;/a>&lt;/sup>&lt;/li>
&lt;li>javax.el: 3.0.1-b08 &lt;sup id="fnref3:5">&lt;a href="#fn:5" class="footnote-ref" role="doc-noteref">5&lt;/a>&lt;/sup>&lt;/li>
&lt;li>kryo: 4.0.1&lt;/li>
&lt;li>kryo-serializers: 0.42&lt;/li>
&lt;li>fst: 2.48-jdk-6&lt;/li>
&lt;li>resteasy: 3.0.19.Final&lt;/li>
&lt;li>tomcat-embed-core: 8.0.11&lt;/li>
&lt;li>slf4j: 1.7.25&lt;/li>
&lt;li>log4j: 1.2.16&lt;/li>
&lt;/ul>
&lt;div class="footnotes" role="doc-endnotes">
&lt;hr>
&lt;ol>
&lt;li id="fn:1">
&lt;p>In theory, Dubbo only depend on JDK, not depend on any 3rd party libs, you can finish logic by using JDK.&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink">&amp;#x21a9;&amp;#xfe0e;&lt;/a>&lt;/p>
&lt;/li>
&lt;li id="fn:2">
&lt;p>Bytecode generation&amp;#160;&lt;a href="#fnref:2" class="footnote-backref" role="doc-backlink">&amp;#x21a9;&amp;#xfe0e;&lt;/a>&lt;/p>
&lt;/li>
&lt;li id="fn:3">
&lt;p>Configuration parsing&amp;#160;&lt;a href="#fnref:3" class="footnote-backref" role="doc-backlink">&amp;#x21a9;&amp;#xfe0e;&lt;/a>&lt;/p>
&lt;/li>
&lt;li id="fn:4">
&lt;p>Network transmission&amp;#160;&lt;a href="#fnref:4" class="footnote-backref" role="doc-backlink">&amp;#x21a9;&amp;#xfe0e;&lt;/a>&lt;/p>
&lt;/li>
&lt;li id="fn:5">
&lt;p>JAVAEE&amp;#160;&lt;a href="#fnref:5" class="footnote-backref" role="doc-backlink">&amp;#x21a9;&amp;#xfe0e;&lt;/a>&amp;#160;&lt;a href="#fnref1:5" class="footnote-backref" role="doc-backlink">&amp;#x21a9;&amp;#xfe0e;&lt;/a>&amp;#160;&lt;a href="#fnref2:5" class="footnote-backref" role="doc-backlink">&amp;#x21a9;&amp;#xfe0e;&lt;/a>&amp;#160;&lt;a href="#fnref3:5" class="footnote-backref" role="doc-backlink">&amp;#x21a9;&amp;#xfe0e;&lt;/a>&lt;/p>
&lt;/li>
&lt;/ol>
&lt;/div></description></item><item><title>Docs: Maturity</title><link>https://dubbo.apache.org/en/docs/v2.7/user/maturity/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/en/docs/v2.7/user/maturity/</guid><description>
&lt;h2 id="function-maturity">Function maturity&lt;/h2>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Feature&lt;/th>
&lt;th>Maturity&lt;/th>
&lt;th>Strength&lt;/th>
&lt;th>Problem&lt;/th>
&lt;th>Advise&lt;/th>
&lt;th>User&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>Concurrency control&lt;/td>
&lt;td>Tested&lt;/td>
&lt;td>concurrency control&lt;/td>
&lt;td>&lt;/td>
&lt;td>On trial&lt;/td>
&lt;td>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Connection control&lt;/td>
&lt;td>Tested&lt;/td>
&lt;td>connection number control&lt;/td>
&lt;td>&lt;/td>
&lt;td>On trial&lt;/td>
&lt;td>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Connecting certain provider straightly&lt;/td>
&lt;td>Tested&lt;/td>
&lt;td>Provider service for point-to-point connecting straightly, for test&lt;/td>
&lt;td>&lt;/td>
&lt;td>Can be used in the test environment&lt;/td>
&lt;td>Alibaba&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Grouping polymerization&lt;/td>
&lt;td>Tested&lt;/td>
&lt;td>Return value of grouping polymerization, service for menu aggregation and other services&lt;/td>
&lt;td>Used in special scenes&lt;/td>
&lt;td>Can be used in the production environment&lt;/td>
&lt;td>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Parameters validator&lt;/td>
&lt;td>Tested&lt;/td>
&lt;td>parameters validator, JSR303 validation framework integration&lt;/td>
&lt;td>Have effect on Performance&lt;/td>
&lt;td>On trial&lt;/td>
&lt;td>LaiWang&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Result cache&lt;/td>
&lt;td>Tested&lt;/td>
&lt;td>result cache, for accelerating requests&lt;/td>
&lt;td>&lt;/td>
&lt;td>On trial&lt;/td>
&lt;td>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Generic reference&lt;/td>
&lt;td>Stable&lt;/td>
&lt;td>Generic reference, remote call without a business interface class,for test platforms, open api proxy service, and so on&lt;/td>
&lt;td>&lt;/td>
&lt;td>Can be used in the production environment&lt;/td>
&lt;td>Alibaba&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Generic service&lt;/td>
&lt;td>Stable&lt;/td>
&lt;td>Generic service, no interface class is required to implement any interface, for mock platform&lt;/td>
&lt;td>&lt;/td>
&lt;td>Can be used in the production environment&lt;/td>
&lt;td>Alibaba&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Echo test&lt;/td>
&lt;td>Tested&lt;/td>
&lt;td>echo test&lt;/td>
&lt;td>&lt;/td>
&lt;td>On trial&lt;/td>
&lt;td>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Attachment&lt;/td>
&lt;td>Stable&lt;/td>
&lt;td>Attachment&lt;/td>
&lt;td>&lt;/td>
&lt;td>Can be used in the production environment&lt;/td>
&lt;td>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Asynchronous call&lt;/td>
&lt;td>Tested&lt;/td>
&lt;td>Unavailable asynchronous call&lt;/td>
&lt;td>&lt;/td>
&lt;td>On trial&lt;/td>
&lt;td>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Local call&lt;/td>
&lt;td>Tested&lt;/td>
&lt;td>Local call&lt;/td>
&lt;td>&lt;/td>
&lt;td>On trial&lt;/td>
&lt;td>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Callback parameter&lt;/td>
&lt;td>Tested&lt;/td>
&lt;td>Callback parameter&lt;/td>
&lt;td>Used in special scenes&lt;/td>
&lt;td>On trial&lt;/td>
&lt;td>Registry&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Events notify&lt;/td>
&lt;td>Tested&lt;/td>
&lt;td>Events notify, triggering before and after the remote call is executed&lt;/td>
&lt;td>&lt;/td>
&lt;td>On trial&lt;/td>
&lt;td>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Local stub&lt;/td>
&lt;td>Stable&lt;/td>
&lt;td>Performing part of the logic on the client side&lt;/td>
&lt;td>&lt;/td>
&lt;td>Can be used in the production environment&lt;/td>
&lt;td>Alibaba&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Local mock&lt;/td>
&lt;td>Stable&lt;/td>
&lt;td>Forged return results, which can be executed when failed or directly executed, for service degradation&lt;/td>
&lt;td>Need support of registry&lt;/td>
&lt;td>Can be used in the production environment&lt;/td>
&lt;td>Alibaba&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Delay publish&lt;/td>
&lt;td>Stable&lt;/td>
&lt;td>Delay publish, used to wait for the application to load warmup data or wait for spring context to load completely&lt;/td>
&lt;td>&lt;/td>
&lt;td>Can be used in the production environment&lt;/td>
&lt;td>Alibaba&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Lazy connect&lt;/td>
&lt;td>Tested&lt;/td>
&lt;td>Delay setting up connections, when invocation is set up&lt;/td>
&lt;td>&lt;/td>
&lt;td>On trial&lt;/td>
&lt;td>Registry&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Stickness connections&lt;/td>
&lt;td>Tested&lt;/td>
&lt;td>Stickness connections, always make a request to the same provider service unless the service is down, and then switch to another&lt;/td>
&lt;td>&lt;/td>
&lt;td>On trial&lt;/td>
&lt;td>Registry&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Token authorization&lt;/td>
&lt;td>Tested&lt;/td>
&lt;td>Token authorization, is used for service authorization&lt;/td>
&lt;td>Need support of registry&lt;/td>
&lt;td>On trial&lt;/td>
&lt;td>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Routing rule&lt;/td>
&lt;td>Tested&lt;/td>
&lt;td>Dynamically determining the call relationship&lt;/td>
&lt;td>Need support of registry&lt;/td>
&lt;td>On trial&lt;/td>
&lt;td>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Configuration rule&lt;/td>
&lt;td>Tested&lt;/td>
&lt;td>Distribute the configuration dynamically, is the switch of business logic&lt;/td>
&lt;td>Need support of registry&lt;/td>
&lt;td>On trial&lt;/td>
&lt;td>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Accesslog&lt;/td>
&lt;td>Tested&lt;/td>
&lt;td>Accesslog, used to record call information&lt;/td>
&lt;td>Local storage, impact performance, limited by disk size&lt;/td>
&lt;td>On trial&lt;/td>
&lt;td>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Distributed transaction&lt;/td>
&lt;td>Research&lt;/td>
&lt;td>JTA/XA three phase submission transaction(TCC)&lt;/td>
&lt;td>Unstable&lt;/td>
&lt;td>Unavailable&lt;/td>
&lt;td>&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h2 id="strategy-maturity">Strategy maturity&lt;/h2>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Feature&lt;/th>
&lt;th>Maturity&lt;/th>
&lt;th>Strength&lt;/th>
&lt;th>Problem&lt;/th>
&lt;th>Advise&lt;/th>
&lt;th>User&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>Zookeeper registry&lt;/td>
&lt;td>Stable&lt;/td>
&lt;td>Support the cluster, have various of related open source products, dubbo-2.3.3 and above versions are recommended&lt;/td>
&lt;td>Depended on the stability of zookeeper&lt;/td>
&lt;td>Can be used in the production environment&lt;/td>
&lt;td>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Redis registry&lt;/td>
&lt;td>Stable&lt;/td>
&lt;td>Support the client - based double - write clustering method with high performance&lt;/td>
&lt;td>Please ensure server time synchronization, be used to check the expired dirty data of heartbeat&lt;/td>
&lt;td>Can be used in the production environment&lt;/td>
&lt;td>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Multicast registry&lt;/td>
&lt;td>Tested&lt;/td>
&lt;td>Decentration, no registry needs to be installed&lt;/td>
&lt;td>Depending on the network topology and routing, there is a risk across the server rooms&lt;/td>
&lt;td>Can be used in a small range, in development/test environment&lt;/td>
&lt;td>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Simple registry&lt;/td>
&lt;td>Tested&lt;/td>
&lt;td>Dogfooding, the registry itself is also a standard RPC service&lt;/td>
&lt;td>No cluster support, may occur single-point failure&lt;/td>
&lt;td>On trial&lt;/td>
&lt;td>&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Feature&lt;/th>
&lt;th>Maturity&lt;/th>
&lt;th>Strength&lt;/th>
&lt;th>Problem&lt;/th>
&lt;th>Advise&lt;/th>
&lt;th>User&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>Simple monitor system&lt;/td>
&lt;td>Stable&lt;/td>
&lt;td>Support JFreeChart statistics report&lt;/td>
&lt;td>No cluster support, may occur single-point failure, but the failure does not affect the RPC call&lt;/td>
&lt;td>Can be used in the production environment&lt;/td>
&lt;td>&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Feature&lt;/th>
&lt;th>Maturity&lt;/th>
&lt;th>Strength&lt;/th>
&lt;th>Problem&lt;/th>
&lt;th>Advise&lt;/th>
&lt;th>User&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>Dubbo protocol&lt;/td>
&lt;td>Stable&lt;/td>
&lt;td>Use NIO to reuse a single long connection and use a thread pool to process requests concurrently, Reduce handshake and increase concurrency efficiency, good performance&lt;/td>
&lt;td>A single connection will become a bottleneck in the transmission of large files&lt;/td>
&lt;td>Can be used in the production environment&lt;/td>
&lt;td>Alibaba&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Rmi protocol&lt;/td>
&lt;td>Stable&lt;/td>
&lt;td>Interoperable with native RMI, based on the TCP protocol&lt;/td>
&lt;td>Occasionally the connection fails, and the stub needs to be rebuilt&lt;/td>
&lt;td>Can be used in the production environment&lt;/td>
&lt;td>Alibaba&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Hessian protocol&lt;/td>
&lt;td>Stable&lt;/td>
&lt;td>Interoperable with native Hessian, based on the HTTP protocol&lt;/td>
&lt;td>Hessian.jar support is required, and the overhead of HTTP short connections is large&lt;/td>
&lt;td>Can be used in the production environment&lt;/td>
&lt;td>&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Feature&lt;/th>
&lt;th>Maturity&lt;/th>
&lt;th>Strength&lt;/th>
&lt;th>Problem&lt;/th>
&lt;th>Advise&lt;/th>
&lt;th>User&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>Netty Transporter&lt;/td>
&lt;td>Stable&lt;/td>
&lt;td>The NIO framework of JBoss, has good performance&lt;/td>
&lt;td>A request sends two events and needs to shield useless events&lt;/td>
&lt;td>Can be used in the production environment&lt;/td>
&lt;td>Alibaba&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Mina Transporter&lt;/td>
&lt;td>Stable&lt;/td>
&lt;td>Classic NIO framework,stable&lt;/td>
&lt;td>The dispatch of the message queue is not timely, under great pressure, there will be FullGC&lt;/td>
&lt;td>Can be used in the production environment&lt;/td>
&lt;td>Alibaba&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Grizzly Transporter&lt;/td>
&lt;td>Tested&lt;/td>
&lt;td>The NIO framework of Sun, applied in the GlassFish container&lt;/td>
&lt;td>The thread pool is not extensible, and Filter can&amp;rsquo;t intercept the next filter&lt;/td>
&lt;td>On trial&lt;/td>
&lt;td>&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Feature&lt;/th>
&lt;th>Maturity&lt;/th>
&lt;th>Strength&lt;/th>
&lt;th>Problem&lt;/th>
&lt;th>Advise&lt;/th>
&lt;th>User&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>Hessian Serialization&lt;/td>
&lt;td>Stable&lt;/td>
&lt;td>Good performance, multilingual support (recommended)&lt;/td>
&lt;td>The compatibility of various versions of Hessian is not good, it may be in conflict with the Hessian used in the application, and the Dubbo is embedded with the source code of the hessian3.2.1&lt;/td>
&lt;td>Can be used in the production environment&lt;/td>
&lt;td>Alibaba&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Dubbo Serialization&lt;/td>
&lt;td>Tested&lt;/td>
&lt;td>The performance is better in a large number of POJO transmission by not transmitting the class information of POJO.&lt;/td>
&lt;td>When a field is added to the parameter object, an external file declaration is required&lt;/td>
&lt;td>On trial&lt;/td>
&lt;td>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Json Serialization&lt;/td>
&lt;td>Tested&lt;/td>
&lt;td>pure text, can be cross-language parsed, default using FastJson&lt;/td>
&lt;td>Poor performance&lt;/td>
&lt;td>On trial&lt;/td>
&lt;td>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Java Serialization&lt;/td>
&lt;td>Stable&lt;/td>
&lt;td>Java native support&lt;/td>
&lt;td>Poor performance&lt;/td>
&lt;td>Can be used in the production environment&lt;/td>
&lt;td>&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Feature&lt;/th>
&lt;th>Maturity&lt;/th>
&lt;th>Strength&lt;/th>
&lt;th>Problem&lt;/th>
&lt;th>Advise&lt;/th>
&lt;th>User&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>Javassist ProxyFactory&lt;/td>
&lt;td>Stable&lt;/td>
&lt;td>Bytecode generation instead of reflection, good performance(recommended)&lt;/td>
&lt;td>Depending on the javassist.jar and taking up the JVM&amp;rsquo;s Perm memory, the Perm may have to be larger:java -XX:PermSize=128m&lt;/td>
&lt;td>Can be used in the production environment&lt;/td>
&lt;td>Alibaba&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Jdk ProxyFactory&lt;/td>
&lt;td>Stable&lt;/td>
&lt;td>JDK native support&lt;/td>
&lt;td>Poor performance&lt;/td>
&lt;td>Can be used in the production environment&lt;/td>
&lt;td>&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Feature&lt;/th>
&lt;th>Maturity&lt;/th>
&lt;th>Strength&lt;/th>
&lt;th>Problem&lt;/th>
&lt;th>Advise&lt;/th>
&lt;th>User&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>Failover Cluster&lt;/td>
&lt;td>Stable&lt;/td>
&lt;td>Failure automatically switches, when failure occurs, retries other servers, usually used for read operations.(recommended)&lt;/td>
&lt;td>Retry will lead to longer delays&lt;/td>
&lt;td>Can be used in the production environment&lt;/td>
&lt;td>Alibaba&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Failfast Cluster&lt;/td>
&lt;td>Stable&lt;/td>
&lt;td>Fast failure, only one call, failure to be reported immediately, usually used for non idempotent writing.&lt;/td>
&lt;td>If a server is being restarted, a call failure may occur&lt;/td>
&lt;td>Can be used in the production environment&lt;/td>
&lt;td>Alibaba&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Failsafe Cluster&lt;/td>
&lt;td>Stable&lt;/td>
&lt;td>Failsafe, when abnormal, directly ignored, usually used to write to the audit log and other operations&lt;/td>
&lt;td>Call information loss&lt;/td>
&lt;td>Can be used in the production environment&lt;/td>
&lt;td>Monitor&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Failback Cluster&lt;/td>
&lt;td>Tested&lt;/td>
&lt;td>Failure auto recovery, backstage record failure request, regular retransmission, usually used for message notification operations&lt;/td>
&lt;td>Unreliable, lost when restart the server&lt;/td>
&lt;td>Can be used in the production environment&lt;/td>
&lt;td>Registry&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Forking Cluster&lt;/td>
&lt;td>Tested&lt;/td>
&lt;td>Multiple servers are invoked in parallel, as long as one success is returned, often used for high real-time reading operations.&lt;/td>
&lt;td>Need to waste more service resources&lt;/td>
&lt;td>Can be used in the production environment&lt;/td>
&lt;td>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Broadcast Cluster&lt;/td>
&lt;td>Tested&lt;/td>
&lt;td>A broadcast calls all providers, one by one, and any error is wrongly reported, usually used to update the provider&amp;rsquo;s local state&lt;/td>
&lt;td>The speed is slow, and any false report is wrong.&lt;/td>
&lt;td>Can be used in the production environment&lt;/td>
&lt;td>&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Feature&lt;/th>
&lt;th>Maturity&lt;/th>
&lt;th>Strength&lt;/th>
&lt;th>Problem&lt;/th>
&lt;th>Advise&lt;/th>
&lt;th>User&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>Random LoadBalance&lt;/td>
&lt;td>Stable&lt;/td>
&lt;td>Random probability, set random probability according to weight(recommended)&lt;/td>
&lt;td>The probability of a collision on a cross section is high. When retrying, there may be an unequal instantaneous pressure.&lt;/td>
&lt;td>Can be used in the production environment&lt;/td>
&lt;td>Alibaba&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>RoundRobin LoadBalance&lt;/td>
&lt;td>Stable&lt;/td>
&lt;td>Round Robin, setting wheel based ratio according to the weight after the Convention&lt;/td>
&lt;td>There is a slow machine accumulation request problem, and extreme circumstances may cause an avalanche&lt;/td>
&lt;td>Can be used in the production environment&lt;/td>
&lt;td>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>LeastActive LoadBalance&lt;/td>
&lt;td>Stable&lt;/td>
&lt;td>The least active call number, the random number of the same active number, the active number is the count difference before and after the call, making the slow machine receive less request.&lt;/td>
&lt;td>Do not support the weight, in the capacity planning, not to pressure a machine oriented pressure measurement by weight capacity&lt;/td>
&lt;td>Can be used in the production environment&lt;/td>
&lt;td>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>ConsistentHash LoadBalance&lt;/td>
&lt;td>Stable&lt;/td>
&lt;td>The consistency hash, the same parameters always request to the same provider, when one provider hung, originally sent to the provider&amp;rsquo;s request, based on virtual nodes, spread to other providers, will not cause dramatic changes&lt;/td>
&lt;td>Uneven distribution of pressure&lt;/td>
&lt;td>Can be used in the production environment&lt;/td>
&lt;td>&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Feature&lt;/th>
&lt;th>Maturity&lt;/th>
&lt;th>Strength&lt;/th>
&lt;th>Problem&lt;/th>
&lt;th>Advise&lt;/th>
&lt;th>User&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>Condition routing rule&lt;/td>
&lt;td>Stable&lt;/td>
&lt;td>Routing rules based on conditional expressions, simple and easy to use&lt;/td>
&lt;td>There are some complex multi branch conditions, and the rules are difficult to describe&lt;/td>
&lt;td>Can be used in the production environment&lt;/td>
&lt;td>Alibaba&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Script routing rules&lt;/td>
&lt;td>Tested&lt;/td>
&lt;td>Routing rules based on the script engine, powerful&lt;/td>
&lt;td>No sandbox is running, scripting ability is too powerful and may be the back door&lt;/td>
&lt;td>On trial&lt;/td>
&lt;td>&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Feature&lt;/th>
&lt;th>Maturity&lt;/th>
&lt;th>Strength&lt;/th>
&lt;th>Problem&lt;/th>
&lt;th>Advise&lt;/th>
&lt;th>User&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>Spring Container&lt;/td>
&lt;td>Stable&lt;/td>
&lt;td>Automatically load all Spring configurations under the META-INF/spring directory&lt;/td>
&lt;td>&lt;/td>
&lt;td>Can be used in the production environment&lt;/td>
&lt;td>Alibaba&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Jetty Container&lt;/td>
&lt;td>Stable&lt;/td>
&lt;td>Start an embedded Jetty for reporting state&lt;/td>
&lt;td>When a large number of pages are accessed, the threads and memory of the server are affected&lt;/td>
&lt;td>Can be used in the production environment&lt;/td>
&lt;td>Alibaba&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Log4j Container&lt;/td>
&lt;td>Stable&lt;/td>
&lt;td>Configuring the configuration of the log4j automatically, automatically subdirecting the log files by process at the startup of multiple processes&lt;/td>
&lt;td>The user can&amp;rsquo;t control the configuration of log4j, inflexible&lt;/td>
&lt;td>Can be used in the production environment&lt;/td>
&lt;td>Alibaba&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table></description></item><item><title>Docs: Dubbo Configuration</title><link>https://dubbo.apache.org/en/docs/v2.7/user/configuration/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/en/docs/v2.7/user/configuration/</guid><description/></item><item><title>Docs: Dubbo Examples</title><link>https://dubbo.apache.org/en/docs/v2.7/user/examples/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/en/docs/v2.7/user/examples/</guid><description>
&lt;div class="alert alert-primary" role="alert">
&lt;h4 class="alert-heading">Tips&lt;/h4>
&lt;p>To complete run, please see: &lt;a href="../quick-start">quick start&lt;/a>, here just lists the configuration of various scenarios.&lt;/p>
&lt;p>The following examples are all based on Spring configuration: &lt;a href="../configuration/xml">XML configuration&lt;/a> for reference, if you do not want to use Spring, but want to be use it via the directly API, please see: &lt;a href="../configuration/api">API configuration&lt;/a>&lt;/p>
&lt;/div></description></item><item><title>Docs: References</title><link>https://dubbo.apache.org/en/docs/v2.7/user/references/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/en/docs/v2.7/user/references/</guid><description/></item><item><title>Docs: Best practice</title><link>https://dubbo.apache.org/en/docs/v2.7/user/best-practice/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/en/docs/v2.7/user/best-practice/</guid><description>
&lt;h2 id="modularization">Modularization&lt;/h2>
&lt;p>It is recommended to put service interfaces, service models, service exceptions, and so on in the API package,Because the service model and exception are part of the API, it is also in conformity with the modularization principle:Reusing the publish equivalence principle (REP) and the Common Reuse Principle (CRP).&lt;/p>
&lt;p>If you need, you can also consider placing a spring reference configuration in the API package, so that the user can only use the configuration in the spring loading process, and the configuration suggestion is placed in the package directory of the module, so as not to conflict, eg:&lt;code>com/alibaba/china/xxx/dubbo-reference.xml&lt;/code>。&lt;/p>
&lt;h2 id="granularity">Granularity&lt;/h2>
&lt;p>The service interface should have large granularity as possible.Each service method should represent a function rather than a step of a function, otherwise it will be faced with distributed transaction problem. Dubbo does not provide distributed transaction support at present.&lt;/p>
&lt;p>The service interface recommends the division of the business scene as a unit and abstract the similar business to prevent the explosion of the number of interfaces.&lt;/p>
&lt;p>It is not recommended to use an too abstract universal interface, such as Map query (Map), which has no explicit semantics, which will inconvenience later maintenance.&lt;/p>
&lt;h2 id="version">Version&lt;/h2>
&lt;p>Each interface should define a version number to provide possible subsequent incompatible upgrades,eg: &lt;code>&amp;lt;dubbo:service interface=&amp;quot;com.xxx.XxxService&amp;quot; version=&amp;quot;1.0&amp;quot; /&amp;gt;&lt;/code>。&lt;/p>
&lt;p>It is recommended to use a two bit version number, because the third - bit version number is usually compatible with a compatible upgrade, and a change of service version is required only when incompatible.&lt;/p>
&lt;p>When incompatible, half of the provider is upgraded to a new version, and all the consumers are upgraded to a new version, and the remaining half providers are upgraded to a new version.&lt;/p>
&lt;h2 id="compatibility">Compatibility&lt;/h2>
&lt;p>The service interface adds method or the service model adds fields. It can be backward compatible, delete methods or delete fields, and will not be compatible. The new fields of the enumerated type are not compatible, so we need to upgrade by changing the version number.&lt;/p>
&lt;p>The compatibility of each protocol is different, see: &lt;a href="../references/protocol/">Protocol introduction&lt;/a>&lt;/p>
&lt;h2 id="enumeration-type">Enumeration type&lt;/h2>
&lt;p>If it is a complete set, you can use Enum, eg:&lt;code>ENABLE&lt;/code>, &lt;code>DISABLE&lt;/code>。&lt;/p>
&lt;p>If it is the type of business, there will be an obvious type of increase in the future, and it is not recommended to use &lt;code>Enum&lt;/code>, and it is not recommended to use Enum and can be replaced by &lt;code>String&lt;/code> .&lt;/p>
&lt;p>If you use&lt;code>Enum&lt;/code>in the return value,And add the &lt;code>Enum&lt;/code> value,suggestions to upgrade the service consumption, so that the service provider does not return a new value.&lt;/p>
&lt;p>If the &lt;code>Enum&lt;/code> value is used in the incoming parameter,and add the &lt;code>Enum&lt;/code> value,it is suggested that the service provider be upgraded first, so that the service consumer will not pass the new value.&lt;/p>
&lt;h2 id="serialization">Serialization&lt;/h2>
&lt;p>The service parameters and return values suggest that the POJO object is used, that is, the object of the attribute is represented by the &lt;code>setter&lt;/code>, &lt;code>getter&lt;/code> method.&lt;/p>
&lt;p>Service parameters and return values do not recommend the use of interfaces, because data model abstraction is of little significance, and serialization requires interfaces to implement meta information of classes, and can not play the purpose of hiding implementation.&lt;/p>
&lt;p>Service parameters and return values must be byValue, but not byReference. The reference or return values of consumers and providers are not the same, but the values are the same. Dubbo does not support remote objects.&lt;/p>
&lt;h2 id="exception">Exception&lt;/h2>
&lt;p>It is suggested that abnormal reporting errors are used rather than return error codes, and exception information can carry more information and have more semantic friendliness.&lt;/p>
&lt;p>If you are worried about performance problems, you can use the override () method of fillInStackTrace () out of the exception class as an empty method to make it not a copy of the stack information when necessary.&lt;/p>
&lt;p>Query method is not recommended throws checked, otherwise the caller in the query will be too much &lt;code>try...catch, and can not be processed.&lt;/code>&lt;/p>
&lt;p>Service providers should not throw the exception of DAO or SQL to the consumer side. They should package the exception that consumers do not care about in service implementation, otherwise consumers may not be able to serialize the corresponding exception.&lt;/p>
&lt;h2 id="call">Call&lt;/h2>
&lt;p>Not just because it is a Dubbo call, wrap the call logic with &lt;code>try...catch&lt;/code>clause. &lt;code>try...catch&lt;/code> should be added to the appropriate rollback boundary.&lt;/p>
&lt;p>The check logic for the input parameters should be available at the Provider side. For performance considerations, the service implementer may consider adding a service Stub class to the API package to complete the test.&lt;/p></description></item><item><title>Docs: Recommended usage</title><link>https://dubbo.apache.org/en/docs/v2.7/user/recommend/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/en/docs/v2.7/user/recommend/</guid><description>
&lt;h2 id="configuring-the-attributes-of-the-consumer-side-as-much-as-possible-on-the-provider-side">Configuring the attributes of the consumer side as much as possible on the provider side&lt;/h2>
&lt;p>the reason is:&lt;/p>
&lt;ul>
&lt;li>Service providers are more aware of service performance parameters than service users,Such as the timeout time of the call, the reasonable retry times, and so on.&lt;/li>
&lt;li>If a attribute is configurated in provider side, not configurated in consumer side, consumer service will use the attribute in provider side. That is to say, the provider side&amp;rsquo;s attribute can be used as consumer&amp;rsquo;s default value &lt;sup id="fnref:1">&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref">1&lt;/a>&lt;/sup>. Otherwise, consumer service will use consumer-side&amp;rsquo;s attribute,but can&amp;rsquo;t cnotrol the provider service,it&amp;rsquo;s usually unreasonable.&lt;/li>
&lt;/ul>
&lt;p>Configuring the attributes of the consumer side as much as possible on the provider side,Make the provider service developer think more about the characteristics and quality of the provider side service.&lt;/p>
&lt;p>Examples:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:service&lt;/span> interface=&lt;span style="color:#2aa198">&amp;#34;com.alibaba.hello.api.HelloService&amp;#34;&lt;/span> version=&lt;span style="color:#2aa198">&amp;#34;1.0.0&amp;#34;&lt;/span> ref=&lt;span style="color:#2aa198">&amp;#34;helloService&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> timeout=&lt;span style="color:#2aa198">&amp;#34;300&amp;#34;&lt;/span> retry=&lt;span style="color:#2aa198">&amp;#34;2&amp;#34;&lt;/span> loadbalance=&lt;span style="color:#2aa198">&amp;#34;random&amp;#34;&lt;/span> actives=&lt;span style="color:#2aa198">&amp;#34;0&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:service&lt;/span> interface=&lt;span style="color:#2aa198">&amp;#34;com.alibaba.hello.api.WorldService&amp;#34;&lt;/span> version=&lt;span style="color:#2aa198">&amp;#34;1.0.0&amp;#34;&lt;/span> ref=&lt;span style="color:#2aa198">&amp;#34;helloService&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> timeout=&lt;span style="color:#2aa198">&amp;#34;300&amp;#34;&lt;/span> retry=&lt;span style="color:#2aa198">&amp;#34;2&amp;#34;&lt;/span> loadbalance=&lt;span style="color:#2aa198">&amp;#34;random&amp;#34;&lt;/span> actives=&lt;span style="color:#2aa198">&amp;#34;0&amp;#34;&lt;/span> &lt;span style="color:#268bd2">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;dubbo:method&lt;/span> name=&lt;span style="color:#2aa198">&amp;#34;findAllPerson&amp;#34;&lt;/span> timeout=&lt;span style="color:#2aa198">&amp;#34;10000&amp;#34;&lt;/span> retries=&lt;span style="color:#2aa198">&amp;#34;9&amp;#34;&lt;/span> loadbalance=&lt;span style="color:#2aa198">&amp;#34;leastactive&amp;#34;&lt;/span> actives=&lt;span style="color:#2aa198">&amp;#34;5&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:service/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The consumer side properties that can be configured on provider are:&lt;/p>
&lt;ol start="0">
&lt;li>&lt;code>timeout&lt;/code> Method call timeout&lt;/li>
&lt;li>&lt;code>retries&lt;/code> The number of failed retries, default value is 1 &lt;sup id="fnref:2">&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref">2&lt;/a>&lt;/sup>&lt;/li>
&lt;li>&lt;code>loadbalance&lt;/code> Load balance algorithm &lt;sup id="fnref:3">&lt;a href="#fn:3" class="footnote-ref" role="doc-noteref">3&lt;/a>&lt;/sup>,default algorithm is random &lt;code>random&lt;/code>,and polling &lt;code>roundrobin&lt;/code>、least active &lt;sup id="fnref:4">&lt;a href="#fn:4" class="footnote-ref" role="doc-noteref">4&lt;/a>&lt;/sup> &lt;code>leastactive&lt;/code>&lt;/li>
&lt;li>&lt;code>actives&lt;/code> Consumer side, maximum concurrent call limitation. That is , when the concurrent requests of consumer service reach maximum configuration,the new call will wait until to catch a timeout error.
Configurated in &lt;code>dubbo:method&lt;/code>(method level configuration) , then the concurrent limitation point at method.Configurated in &lt;code>dubbo:service&lt;/code>(service level configuration),then the concurrent limitation point at service.&lt;/li>
&lt;/ol>
&lt;p>Detailed configuration instructions see:&lt;a href="../references/xml/">Dubbo configuration introduction&lt;/a>&lt;/p>
&lt;h2 id="configuring-reasonable-provider-end-properties-on-provider">Configuring reasonable provider end properties on provider&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:protocol&lt;/span> threads=&lt;span style="color:#2aa198">&amp;#34;200&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:service&lt;/span> interface=&lt;span style="color:#2aa198">&amp;#34;com.alibaba.hello.api.HelloService&amp;#34;&lt;/span> version=&lt;span style="color:#2aa198">&amp;#34;1.0.0&amp;#34;&lt;/span> ref=&lt;span style="color:#2aa198">&amp;#34;helloService&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> executes=&lt;span style="color:#2aa198">&amp;#34;200&amp;#34;&lt;/span> &lt;span style="color:#268bd2">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;dubbo:method&lt;/span> name=&lt;span style="color:#2aa198">&amp;#34;findAllPerson&amp;#34;&lt;/span> executes=&lt;span style="color:#2aa198">&amp;#34;50&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;/dubbo:service&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The provider side properties that can be configured on provider service are:&lt;/p>
&lt;ol start="0">
&lt;li>&lt;code>threads&lt;/code> service thread pool size&lt;/li>
&lt;li>&lt;code>executes&lt;/code> If concurrent requests number that a provider service handled reach the maximum thead pool count , the new call will wait,then the consumer call may catch a timeout error. Configurated in &lt;code>dubbo:method&lt;/code>(method level configuration) , then the concurrent limitation point at method.Configurated in &lt;code>dubbo:service&lt;/code>(service level configuration),then the concurrent limitation point at service.&lt;/li>
&lt;/ol>
&lt;h2 id="configuration-management-information">Configuration management information&lt;/h2>
&lt;p>Now we have the owner information and organization infomation to differentiate the sites。It&amp;rsquo;s easy to contact with the service owners when there is a problem, please write at least two persons for backup. The information of owners and organizations can be seen in the registry.&lt;/p>
&lt;p>application configuration owners,organizations:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:application&lt;/span> owner=&lt;span style="color:#2aa198">”ding.lid,william.liangf”&lt;/span> organization=&lt;span style="color:#2aa198">”intl”&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>service configuration owners:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:service&lt;/span> owner=&lt;span style="color:#2aa198">”ding.lid,william.liangf”&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>reference configuration owners:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:reference&lt;/span> owner=&lt;span style="color:#2aa198">”ding.lid,william.liangf”&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;code>dubbo:service&lt;/code>、&lt;code>dubbo:reference&lt;/code> have no configuration owner, then use the owner configured in &lt;code>dubbo:application&lt;/code>.&lt;/p>
&lt;h2 id="set-up-the-dubbo-cache-file">Set up the Dubbo cache file&lt;/h2>
&lt;p>Provider service list caching file:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:registry&lt;/span> file=&lt;span style="color:#2aa198">”${user.home}/output/dubbo.cache”&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Notations:&lt;/p>
&lt;ol start="0">
&lt;li>You can modify the cahe file path of the application according to the needs. Ensure that the file will not be cleared during the release process.&lt;/li>
&lt;li>If there are more than one application process, do not use the same file path to avoid the content being overwritten.&lt;/li>
&lt;/ol>
&lt;p>This file caches the list of the registry and the list of service providers. With this configuration, when the application is restarted , if the Dubbo registry is not available, the application will read the information from the service provider list from the cache file. That can ensure the availability of the application.&lt;/p>
&lt;h2 id="monitor-configuration">Monitor configuration&lt;/h2>
&lt;ol start="0">
&lt;li>
&lt;p>Expose service with a fixed port, instead of using a random port&lt;/p>
&lt;p>In this way, when there is a delay in the registry push, the consumer can also call the original provider service address hrough the cache list and succeed。&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Use Dragoon&amp;rsquo;s HTTP monitoring item to monitor the service provider on the registry&lt;/p>
&lt;p>The state of Dragoon monitoring service in the registry : &lt;code>http://dubbo-reg1.hst.xyi.cn.alidc.net:8080/status/com.alibaba.morgan.member.MemberService:1.0.5&lt;/code> Ensure that the service exists on the registry .&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Service provider,use Dragoon&amp;rsquo;s telnet mommand or shell monitor command&lt;/p>
&lt;p>Monitoring service provider port status :&lt;code>echo status | nc -i 1 20880 | grep OK | wc -l&lt;/code>, 20880 is the service port&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Service consumer side, cast the service to EchoService,and call &lt;code>$echo()&lt;/code> to test whether the provider of the service is available&lt;/p>
&lt;p>eg: &lt;code>assertEqauls(“OK”, ((EchoService)memberService).$echo(“OK”));&lt;/code>&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h2 id="dont-use-the-configuration-of-dubboproperties-file-suggeset-to-use--the-configuration-of-xml">Don&amp;rsquo;t use the configuration of dubbo.properties file, suggeset to use the configuration of XML&lt;/h2>
&lt;p>All of the configuration items in the dubbo can be configured in the spring configuration file,and can be configured for a single service.&lt;/p>
&lt;p>The Dubbo default value is used if completely not set up , please see the instructions in the article &lt;a href="../references/xml/">Dubbo configuration introduction&lt;/a> .&lt;/p>
&lt;h3 id="the-relation-between-attribute-name-of-dubboproperties-and-xml">The relation between attribute name of dubbo.properties and XML&lt;/h3>
&lt;ol start="0">
&lt;li>
&lt;p>application name &lt;code>dubbo.application.name&lt;/code>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:application&lt;/span> name=&lt;span style="color:#2aa198">&amp;#34;myalibaba&amp;#34;&lt;/span> &lt;span style="color:#268bd2">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;li>
&lt;p>registry address &lt;code>dubbo.registry.address&lt;/code>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:registry&lt;/span> address=&lt;span style="color:#2aa198">&amp;#34;11.22.33.44:9090&amp;#34;&lt;/span> &lt;span style="color:#268bd2">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;li>
&lt;p>call timeout &lt;code>dubbo.service.*.timeout&lt;/code>&lt;/p>
&lt;p>Timeout can be set in multiple configuration items &lt;code>timeout&lt;/code>,cover from top to bottom (The top one have a higher priority )&lt;sup id="fnref:5">&lt;a href="#fn:5" class="footnote-ref" role="doc-noteref">5&lt;/a>&lt;/sup>,The coverage strategy of other parameters(&lt;code>retries&lt;/code>、&lt;code>loadbalance&lt;/code>、&lt;code>actives&lt;/code> and so on)is:&lt;/p>
&lt;p>Certain method Configuration of a provider service&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:service&lt;/span> interface=&lt;span style="color:#2aa198">&amp;#34;com.alibaba.xxx.XxxService&amp;#34;&lt;/span> &lt;span style="color:#268bd2">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;dubbo:method&lt;/span> name=&lt;span style="color:#2aa198">&amp;#34;findPerson&amp;#34;&lt;/span> timeout=&lt;span style="color:#2aa198">&amp;#34;1000&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;/dubbo:service&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Configuration of a provider specific interface&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:service&lt;/span> interface=&lt;span style="color:#2aa198">&amp;#34;com.alibaba.xxx.XxxService&amp;#34;&lt;/span> timeout=&lt;span style="color:#2aa198">&amp;#34;200&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;li>
&lt;p>Service provider protocol &lt;code>dubbo.service.protocol&lt;/code>、Service monitor port &lt;code>dubbo.service.server.port&lt;/code>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:protocol&lt;/span> name=&lt;span style="color:#2aa198">&amp;#34;dubbo&amp;#34;&lt;/span> port=&lt;span style="color:#2aa198">&amp;#34;20880&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;li>
&lt;p>Service thread pool size &lt;code>dubbo.service.max.thread.threads.size&lt;/code>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:protocol&lt;/span> threads=&lt;span style="color:#2aa198">&amp;#34;100&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;li>
&lt;p>No provider throws exceptions (Fast-Fail) when the consumer is started ()
&lt;code>alibaba.intl.commons.dubbo.service.allow.no.provider&lt;/code>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:reference&lt;/span> interface=&lt;span style="color:#2aa198">&amp;#34;com.alibaba.xxx.XxxService&amp;#34;&lt;/span> check=&lt;span style="color:#2aa198">&amp;#34;false&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;/ol>
&lt;div class="footnotes" role="doc-endnotes">
&lt;hr>
&lt;ol>
&lt;li id="fn:1">
&lt;p>Overlay rules for configuration: 1) The method level configuration has a higher priority than the interface level, that is to say,small scope have a high priority 2) Consumer side configuration has a higher priority than provider side, better than global configuration, the last one is the Dubbo hard coded configuration value(&lt;a href="https://dubbo.apache.org/en/docs/v2.7/user/configuration/properties/">Dubbo configuration introduction&lt;/a>)&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink">&amp;#x21a9;&amp;#xfe0e;&lt;/a>&lt;/p>
&lt;/li>
&lt;li id="fn:2">
&lt;p>With the first call, the call will be called 3 times&amp;#160;&lt;a href="#fnref:2" class="footnote-backref" role="doc-backlink">&amp;#x21a9;&amp;#xfe0e;&lt;/a>&lt;/p>
&lt;/li>
&lt;li id="fn:3">
&lt;p>How to select a service to call when there are multiple Provider services&amp;#160;&lt;a href="#fnref:3" class="footnote-backref" role="doc-backlink">&amp;#x21a9;&amp;#xfe0e;&lt;/a>&lt;/p>
&lt;/li>
&lt;li id="fn:4">
&lt;p>It means that consumer service can call the best provider service, and reduce to call the the slow provider service.&amp;#160;&lt;a href="#fnref:4" class="footnote-backref" role="doc-backlink">&amp;#x21a9;&amp;#xfe0e;&lt;/a>&lt;/p>
&lt;/li>
&lt;li id="fn:5">
&lt;p>&lt;code>timeout&lt;/code> Can be set in multiple places, configuration items and overlay rules: &lt;a href="../references/xml/">Dubbo Schema configuration introduction&lt;/a>&amp;#160;&lt;a href="#fnref:5" class="footnote-backref" role="doc-backlink">&amp;#x21a9;&amp;#xfe0e;&lt;/a>&lt;/p>
&lt;/li>
&lt;/ol>
&lt;/div></description></item><item><title>Docs: Capacity plan</title><link>https://dubbo.apache.org/en/docs/v2.7/user/capacity-plan/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/en/docs/v2.7/user/capacity-plan/</guid><description>
&lt;p>The following data for reference:&lt;/p>
&lt;h2 id="use-member-service-project-of-dubbo">Use member service project of Dubbo&lt;/h2>
&lt;ul>
&lt;li>Receive 400,000,000 remote calls one day&lt;/li>
&lt;li>Use 12 standard servers to provide services (CPU:8 core, memory: 8G)&lt;/li>
&lt;li>The average load is less than 1 (For 8 core CPU, the load is very low)&lt;/li>
&lt;li>The average response time is 2.3 to 2.5 ms,Network cost about 1.5 to 1.6 ms(Related to the size of the packet )&lt;/li>
&lt;/ul>
&lt;h2 id="use-product-authorization-service-project-of-dubbo">Use product authorization service project of Dubbo&lt;/h2>
&lt;ul>
&lt;li>Receive 300,000,000 remote calls one day&lt;/li>
&lt;li>Use 8 standard servers to provide services (CPU:8 core, memory: 8G)&lt;/li>
&lt;li>The average load is less than 1 (For 8 core CPU, the load is very low)&lt;/li>
&lt;li>The average response time is 1.4 to 2.8 ms,Network cost about 1.0 to 1.1 ms(Related to the size of the packet )&lt;/li>
&lt;/ul></description></item><item><title>Docs: Performance</title><link>https://dubbo.apache.org/en/docs/v2.7/user/perf-test/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/en/docs/v2.7/user/perf-test/</guid><description>
&lt;h2 id="test-instructions">Test instructions&lt;/h2>
&lt;ol start="0">
&lt;li>In this performance test, the performance of all Dubbo 2.0 supported protocols in different sizes and data types is tested and compared with the Dubbo 1.0.&lt;/li>
&lt;li>The overall performance is increased by 1.0 compared with 10%, and the average increase is 10%. The performance improvement of 10%~50% can also be achieved by using the new Dubbo serialization of Dubbo 2.0 .&lt;/li>
&lt;li>In the stability test, because the underlying communication framework is changed from Mina to netty, the growth of objects in old area is greatly reduced, and the 50 hour operation increases less than 200m and no fullgc.&lt;/li>
&lt;li>There is a problem: performance of 2.0 is less than 1.0 in 50K data, and it is doubted that it may be a buffer setting problem, and the next version will be further confirmed.&lt;/li>
&lt;/ol>
&lt;h2 id="test-environment">Test environment&lt;/h2>
&lt;h3 id="hardware-deployment-and-parameter-adjustment">Hardware deployment and parameter adjustment&lt;/h3>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Model&lt;/th>
&lt;th>CPU&lt;/th>
&lt;th>Memory&lt;/th>
&lt;th>Network&lt;/th>
&lt;th>Disk&lt;/th>
&lt;th>Kernel&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>Tecal BH620&lt;/td>
&lt;td>model name : Intel(R) Xeon(R) CPU E5520 @ 2.27GHz cache size : 8192 KB processor_count : 16&lt;/td>
&lt;td>Total System Memory: 6G Hardware Memory Info: Size: 4096MB&lt;/td>
&lt;td>eth0: Link is up at 1000 Mbps, full duplex. peth0: Link is up at 1000 Mbps, full duplex.&lt;/td>
&lt;td>/dev/sda: 597.9 GB&lt;/td>
&lt;td>2.6.18-128.el5xen x86_64&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h3 id="software-architecture">Software architecture&lt;/h3>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Software name and version&lt;/th>
&lt;th>key parameter&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>java version &amp;ldquo;1.6.0_18&amp;rdquo; Java(TM) SE Runtime Environment (build 1.6.0_18-b07) Java HotSpot(TM) 64-Bit Server VM (build 16.0-b13, mixed mode)&lt;/td>
&lt;td>-server -Xmx2g -Xms2g -Xmn256m -XX:PermSize=128m -Xss256k -XX:+DisableExplicitGC -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:LargePageSizeInBytes=128m -XX:+UseFastAccessorMethods -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=70&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>jboss-4.0.5.GA&lt;/td>
&lt;td>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>httpd-2.0.61&lt;/td>
&lt;td>KeepAlive On MaxKeepAliveRequests 100000 KeepAliveTimeout 180 MaxRequestsPerChild 1000000 &lt;IfModule worker.c> StartServers 5 MaxClients 1024 MinSpareThreads 25 MaxSpareThreads 75 ThreadsPerChild 64 ThreadLimit 128 ServerLimit 16 &lt;/IfModule>&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h2 id="test-purpose">Test purpose&lt;/h2>
&lt;h3 id="expected-performance-indicators-quantized">Expected performance indicators (quantized)&lt;/h3>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Scene name&lt;/th>
&lt;th>Corresponding index name&lt;/th>
&lt;th>Range of expected values&lt;/th>
&lt;th>Actual value&lt;/th>
&lt;th>Whether or not to meet expectations (yes / no)&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>1k data&lt;/td>
&lt;td>Response time&lt;/td>
&lt;td>0.9ms&lt;/td>
&lt;td>0.79ms&lt;/td>
&lt;td>Yes&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>1k data&lt;/td>
&lt;td>TPS&lt;/td>
&lt;td>10000&lt;/td>
&lt;td>11994&lt;/td>
&lt;td>Yes&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h3 id="expected-operating-conditions-non-quantified-optional">Expected operating conditions (non quantified, optional)&lt;/h3>
&lt;ul>
&lt;li>The performance of 2.0 is not less than 1, and the performance of the intermodulation of 2.0 and 1.0 is not significantly reduced. In addition to 50K string, the rest are passed&lt;/li>
&lt;li>JVM memory is running stable, no OOM, and there is no reasonable large object in the heap memory. Passed&lt;/li>
&lt;li>CPU, memory, network, disk, file handle are occupied smoothly. Passed&lt;/li>
&lt;li>There is no frequent thread lock, and the number of threads is stable. Passed&lt;/li>
&lt;li>Business thread load balance. Passed&lt;/li>
&lt;/ul>
&lt;h2 id="test-script">Test script&lt;/h2>
&lt;ol start="0">
&lt;li>
&lt;p>Performance test scence (10 concurrency)&lt;/p>
&lt;ul>
&lt;li>Pass in 1K String, do not do anything, return the original&lt;/li>
&lt;li>Pass in 50K String, do not do anything, return the original&lt;/li>
&lt;li>Pass in 200K String, do not do anything, return the original&lt;/li>
&lt;li>Incoming 1K POJO (nested complex person objects) without any processing, return to the original&lt;/li>
&lt;/ul>
&lt;p>The above scenario is tested for 10 minutes in Dubbo 1.0, Dubbo 2.0 (hessian2 serialization), Dubbo 2.0 (Dubbo serialization), RMI, Hessian 3.2.0, HTTP (JSON serialization). It mainly examines the performance of serialization and network IO, so the server has no business logic. 10 is to consider the concurrent HTTP protocol in high with the use of CPU high rate may hit the bottleneck.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Concurrent scene (20 concurrency)
1K String is introduced into the server segment for 1W times, and a random number is regenerated each time and then assembled. Examine whether business threads can be assigned to each CPU.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Stability scence (20 concurrency)
At the same time, we call the 1 parameter String (5K) method, the 1 parameter is the person object method, the 1 parameter is map (the value is 3 person), and it runs for 50 hours continuously.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>High pressure scene (20 concurrency)
On the basis of the stability scenario, the providers and consumers are arranged into 2 sets (one machine and 2 instances), and the parameters of String are 20byte to 200K, and are randomly transformed every 10 minutes.&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h2 id="test-result">Test result&lt;/h2>
&lt;h3 id="scene-name-scence-pojo">Scene name: scence POJO&lt;/h3>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>&lt;/th>
&lt;th>TPS success avg value&lt;/th>
&lt;th>Response time avg value(ms)&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>dubbo1 (hessian2 serialization+mina)&lt;/td>
&lt;td>10813.5&lt;/td>
&lt;td>0.9&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>dubbo2 (hessian2 serialization+netty)&lt;/td>
&lt;td>11994&lt;/td>
&lt;td>0.79&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>dubbo2 (dubbo serialization+netty)&lt;/td>
&lt;td>13620&lt;/td>
&lt;td>0.67&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>rmi&lt;/td>
&lt;td>2461.79&lt;/td>
&lt;td>4&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>hessian&lt;/td>
&lt;td>2417.7&lt;/td>
&lt;td>4.1&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>http(json serialization)&lt;/td>
&lt;td>8179.08&lt;/td>
&lt;td>1.15&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>The default percentage of 2.0 and 1.0&lt;/td>
&lt;td>10.92&lt;/td>
&lt;td>-12.22&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Dubbo serialization compared to the percentage of hessian2 serialization&lt;/td>
&lt;td>13.56&lt;/td>
&lt;td>-15.19&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>POJO TPS&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/user/pojotps.png" alt="pojotps.png">&lt;/p>
&lt;p>POJO Response&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/user/pojores.png" alt="pojores.png">&lt;/p>
&lt;h3 id="scene-name-scence-1k-string">Scene name: scence 1k string&lt;/h3>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>&lt;/th>
&lt;th>TPS success avg value&lt;/th>
&lt;th>Response time avg value(ms)&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>dubbo1(hessian2 serialization+mina)&lt;/td>
&lt;td>11940&lt;/td>
&lt;td>0.8&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>dubbo2 (hessian2 serialization+netty)&lt;/td>
&lt;td>14402&lt;/td>
&lt;td>0.64&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>dubbo2 (dubbo serialization+netty)&lt;/td>
&lt;td>15096&lt;/td>
&lt;td>0.6&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>rmi&lt;/td>
&lt;td>11136.02&lt;/td>
&lt;td>0.81&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>hessian&lt;/td>
&lt;td>11426.83&lt;/td>
&lt;td>0.79&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>http(json serialization)&lt;/td>
&lt;td>8919.27&lt;/td>
&lt;td>1.04&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>The default percentage of 2.0 and 1.0&lt;/td>
&lt;td>20.62&lt;/td>
&lt;td>-20.00&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Dubbo serialization compared to the percentage of hessian2 serialization&lt;/td>
&lt;td>4.82&lt;/td>
&lt;td>-6.25&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>1k TPS&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/user/1ktps.png" alt="1ktps.png">&lt;/p>
&lt;p>1k Response&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/user/1kres.png" alt="1kres.png">&lt;/p>
&lt;h3 id="scene-name-scence-50k-string">Scene name: scence 50k string&lt;/h3>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>TPS success avg value&lt;/th>
&lt;th>Response time avg value(ms)&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>dubbo1(hessian2 serialization+mina&lt;/td>
&lt;td>1962.7&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>dubbo2 (hessian2 serialization+netty)&lt;/td>
&lt;td>1293&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>dubbo2 (dubbo serialization+netty)&lt;/td>
&lt;td>1966&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>rmi&lt;/td>
&lt;td>3349.88&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>hessian&lt;/td>
&lt;td>1925.33&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>http(json serialization)&lt;/td>
&lt;td>3247.1&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>The default percentage of 2.0 and 1.0&lt;/td>
&lt;td>-34.12&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Dubbo serialization compared to the percentage of hessian2 serialization&lt;/td>
&lt;td>52.05&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>50K TPS&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/user/50ktps.png" alt="50ktps.png">&lt;/p>
&lt;p>50K Response&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/user/50kres.png" alt="50kres.png">&lt;/p>
&lt;h3 id="scene-name-scence-200k-string">Scene name: scence 200k string&lt;/h3>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>TPS success avg value&lt;/th>
&lt;th>Response time avg value(ms)&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>dubbo1(hessian2 serialization+mina)&lt;/td>
&lt;td>324.2&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>dubbo2 (hessian2 serialization+netty)&lt;/td>
&lt;td>362.92&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>dubbo2 (dubbo serialization+netty)&lt;/td>
&lt;td>569.5&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>rmi&lt;/td>
&lt;td>1031.28&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>hessian&lt;/td>
&lt;td>628.06&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>http(json serialization)&lt;/td>
&lt;td>1011.97&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>The default percentage of 2.0 and 1.0&lt;/td>
&lt;td>11.94&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Dubbo serialization compared to the percentage of hessian2 serialization&lt;/td>
&lt;td>56.92&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>200K TPS&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/user/200ktps.png" alt="200ktps.png">&lt;/p>
&lt;p>&lt;strong>200K Response&lt;/strong>&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/user/200kres.png" alt="200kres.png">&lt;/p>
&lt;h2 id="test-analysis">Test analysis&lt;/h2>
&lt;h3 id="performance-analysis-and-evaluation">Performance analysis and evaluation&lt;/h3>
&lt;p>The performance test conclusion of Dubbo 2 has been improved and improved from performance, memory footprint and stability. Because of its memory management, the change of Mina into netty greatly reduces the 1 version of the large memory sawtooth in high concurrency and large data.&lt;/p>
&lt;h3 id="performance-comparison-analysis-new-and-old-environment-different-data-magnitude-etc">Performance comparison analysis (new and old environment, different data magnitude, etc.)&lt;/h3>
&lt;p>The performance of Dubbo 2 is compared with that of Dubbo 1, which is all hessian2 serialization. The performance is improved (except for 50K String). See the performance data of the fifth chapter in detail.&lt;/p>
&lt;p>For compatibility default serialization and 1 consistent with hessian2, such as have higher requirements on the performance of Dubbo serialization can be used, which is in the process of complicated object, can be obtained in 50% large data upgrade (but it is not recommended for use Dubbo protocol).&lt;/p>
&lt;p>The purpose of Dubbo is to meet the RPC calls with high concurrent and small data volume. The performance is not good under large data volume. It is recommended to use RMI or HTTP protocol.&lt;/p>
&lt;h3 id="test-limitation-analysis-optional">Test limitation analysis (optional)&lt;/h3>
&lt;p>This performance test examines the performance of the Dubbo itself, and the performance of the actual use needs to be verified.&lt;/p>
&lt;p>Because the performance of Dubbo itself is in millisecond and the base number is small, performance improvement may not change the performance of the application as a whole.&lt;/p>
&lt;p>All the monitoring charts are not listed because of the limit of length.&lt;/p></description></item><item><title>Docs: Test coverage report</title><link>https://dubbo.apache.org/en/docs/v2.7/user/coveragence/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/en/docs/v2.7/user/coveragence/</guid><description>
&lt;ul>
&lt;li>v2.0 Codecov report , Statistics since 2017-12-29
The test coverage is : &lt;a href="https://codecov.io/gh/apache/dubbo">&lt;img src="https://codecov.io/gh/apache/dubbo/branch/master/graph/badge.svg" alt="codecov">&lt;/a> , we can get the report in &lt;a href="https://codecov.io/gh/apache/dubbo">https://codecov.io/gh/apache/dubbo&lt;/a>&lt;/li>
&lt;li>v1.0 Based on version &lt;code>2.0.12&lt;/code>,Statistics on 2012-02-03&lt;/li>
&lt;/ul>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/user/code-quality1.jpg" alt="code-quality1.jpg">&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/user/code-quality2.jpg" alt="code-quality2.jpg">&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/user/code-quality3.jpg" alt="code-quality3.jpg">&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/user/code-quality4.jpg" alt="code-quality4.jpg">&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/user/code-quality5.jpg" alt="code-quality5.jpg">&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/user/code-quality6.jpg" alt="code-quality6.jpg">&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/user/code-quality7.jpg" alt="code-quality7.jpg">&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/user/code-coverage.jpg" alt="code-coverage.jpg">&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/user/code-tendency.jpg" alt="code-tendency.jpg">&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/user/code-dependency.jpg" alt="code-dependency.jpg">&lt;/p></description></item><item><title>Docs: Benchmark Suite</title><link>https://dubbo.apache.org/en/docs/v2.7/user/benchmark-tool/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/en/docs/v2.7/user/benchmark-tool/</guid><description>
&lt;ul>
&lt;li>download: git clone &lt;a href="https://github.com/apache/dubbo.git">https://github.com/apache/dubbo.git&lt;/a>&lt;/li>
&lt;li>compile benchmark: cd dubbo/dubbo-test/dubbo-test-benchmark; mvn clean install&lt;/li>
&lt;li>uncompress benchmark: dubbo/dubbo-test/dubbo-test-benchmark/target/dubbo-test-benchmark-2.6.2-SNAPSHOT.tar.gz&lt;/li>
&lt;/ul>
&lt;p>Read ReadMe.txt (the contents are as follows, in the compressed package.)&lt;/p>
&lt;ul>
&lt;li>
&lt;p>Build a new benchmark project, such as demo.benchmark&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Import the your own interface api jar and dubbo.benchmark.jar (Unzip dubbo.benchmark.tar.gz, under the lib directory )&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Create a new class to implement AbstractClientRunnable&lt;/p>
&lt;ul>
&lt;li>Implement the constructor of the parent class&lt;/li>
&lt;li>Implement the invoke method and create a local interface proxy by serviceFactory,and finish your own business logic, as follows:&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> Object &lt;span style="color:#268bd2">invoke&lt;/span>(ServiceFactory serviceFactory) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> DemoService demoService &lt;span style="color:#719e07">=&lt;/span> (DemoService) serviceFactory.get(DemoService.class);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">return&lt;/span> demoService.sendRequest(&lt;span style="color:#2aa198">&amp;#34;hello&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;li>
&lt;p>Make your own benchmark project into a jar package, such as demo.benchmark.jar&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Put the demo.benchmark.jar and service API jar into directory dubbo.benchmark/lib&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Configuring dubbo.properties&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Run run.bat(windows) or run.sh(linux)&lt;/p>
&lt;/li>
&lt;/ul>
&lt;p>If you want to test the different versions of Dubbo, you can replace the jar of the Dubbo.&lt;/p></description></item><item><title>Docs: REST support</title><link>https://dubbo.apache.org/en/docs/v2.7/user/rest/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/en/docs/v2.7/user/rest/</guid><description>
&lt;div class="pageinfo pageinfo-primary">
&lt;p>Original author: Li Shen
Document copyright: &lt;a href="HTTP://www.apache.org/licenses/LICENSE-2.0">Apache 2.0license Signature - No interpretation&lt;/a>&lt;/p>
&lt;p>Working in progress &amp;hellip;&lt;/p>
&lt;/div>
&lt;blockquote>
&lt;p>This article is lengthy since REST involves many aspects. Besides, it refers to the document style of Spring and so on. Not only limited to usage of the framework but also strives to present the design concept of the framework and the architectural idea of an excellent application.
For people who only want to get a glimpse of Dubbo and REST, all they need is to browse through the &lt;code>Overview&lt;/code> to &lt;code>Introduction to Standard Java REST API: JAX-RS&lt;/code>.&lt;/p>
&lt;/blockquote>
&lt;h2 id="content">CONTENT&lt;/h2>
&lt;ul>
&lt;li>Overview&lt;/li>
&lt;li>Advantages of REST&lt;/li>
&lt;li>Application Scenarios&lt;/li>
&lt;li>Quick Start&lt;/li>
&lt;li>Introduction to Standard Java REST API: JAX-RS&lt;/li>
&lt;li>Details of REST Service Provider
&lt;ul>
&lt;li>Implementation of HTTP POST/GET&lt;/li>
&lt;li>Should Annotation be Placed in the Interface or Implementation&lt;/li>
&lt;li>Support for Multiple Data Formats (JSON, XML, etc.)&lt;/li>
&lt;li>Support for Chinese Characters&lt;/li>
&lt;li>Additional Requirements for XML Format&lt;/li>
&lt;li>Custom Serialization&lt;/li>
&lt;li>Configure the Implementation of REST Server&lt;/li>
&lt;li>Access Context Data&lt;/li>
&lt;li>Configure the Port Number and Context Path&lt;/li>
&lt;li>Configure Number of Threads and IO Threads&lt;/li>
&lt;li>Configure Persistent Connection&lt;/li>
&lt;li>Configure Maximum Number of HTTP Connections&lt;/li>
&lt;li>Configure Timeout and HTTP Connections Per Consumer&lt;/li>
&lt;li>Gzip Data Compression&lt;/li>
&lt;li>Replace Part of Spring XML Configuration With Annotation&lt;/li>
&lt;li>Add Custom Filter, Interceptor, etc.&lt;/li>
&lt;li>Add Custom Exception Handler&lt;/li>
&lt;li>Configure HTTP Log Output&lt;/li>
&lt;li>Verification of Input Parameters&lt;/li>
&lt;li>Should REST Services be Published Transparently&lt;/li>
&lt;li>Get Headers In Dubbo Rest Provider&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Details of REST Service Consumer
&lt;ul>
&lt;li>Scenario 1: Non-Dubbo Consumer Calls Dubbo REST Service&lt;/li>
&lt;li>Scenario 2: Dubbo Consumer Calls Dubbo REST Service&lt;/li>
&lt;li>Scenario 3: Dubbo Consumer Calls Non-Dubbo REST Service&lt;/li>
&lt;li>Custom Header By Dubbo Consumer while Calling REST Service&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>JAX-RS Restrictions in Dubbo&lt;/li>
&lt;li>REST FAQ
&lt;ul>
&lt;li>Can Dubbo REST Services be Integrated With Dubbo Registration Center and Monitoring Center?&lt;/li>
&lt;li>How to Implement Load Balancing and Failover in Dubbo REST?&lt;/li>
&lt;li>Can Overloaded Methods in JAX-RS Map to Single URL?&lt;/li>
&lt;li>Can a Method in JAX-RS Receive Multiple Parameters Via POST?&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Possible shortcomings of Current Dubbo System (Related to REST)
&lt;ul>
&lt;li>Invasiveness of Rpc Context&lt;/li>
&lt;li>Limitations of Protocol Configuration&lt;/li>
&lt;li>XML Naming Does Not Conform to the Convention of Spring&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>REST Best Practices&lt;/li>
&lt;li>Performance Benchmark
&lt;ul>
&lt;li>Test Environment&lt;/li>
&lt;li>Test Script&lt;/li>
&lt;li>Test Result&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Extended Discussion
&lt;ul>
&lt;li>Comparison of REST, Thrift, Protobuf, etc.&lt;/li>
&lt;li>Comparison Between REST and Traditional Web Services&lt;/li>
&lt;li>Comparison Between JAX-RS and Spring MVC&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Future&lt;/li>
&lt;/ul>
&lt;h2 id="overview">Overview&lt;/h2>
&lt;p>Dubbo supports a variety of remote calling methods, such as Dubbo RPC (Binary Serialization + TCP), HTTP Invoker (Binary Serialization + HTTP, at least there is no support for Text Serialization in the open source version), Hessian (Binary Serialization + HTTP), Web Services (Text Serialization + HTTP), etc., but lacks support for trending RESTful Remote Calls (Text Serialization + HTTP).&lt;/p>
&lt;p>Therefore, based on the standard Java REST API: JAX-RS 2.0 (Abbreviation of Java API for RESTful Web Services), we provide a mostly transparent REST Call support for Dubbo. Since it is fully compatible with the Standard Java API, all REST services developed for Dubbo may normally work without Dubbo or any specific underlying REST implementation.&lt;/p>
&lt;p>It is particularly worth noting that we do not need to strictly adhere to the original definition and architectural style of REST. Even the famous Twitter REST API will make modest adjustments according to the situations, rather than mechanically follow the original REST style.&lt;/p>
&lt;blockquote>
&lt;p>Note: We call this feature RESTful Remoting (abstracted remote process or call) rather than a RESTful RPC (specific remote &amp;ldquo;procedure&amp;rdquo; call) because REST and RPC can be thought of two different styles. In Dubbo&amp;rsquo;s REST implementation, there are two aspects, one is to provide or consume regular REST services, the other is to make REST a protocol implementation in the Dubbo RPC system, and RESTful Remoting covers both aspects.&lt;/p>
&lt;/blockquote>
&lt;h2 id="advantages-of-rest">Advantages of REST&lt;/h2>
&lt;p>The following is quoted from Wikipedia:&lt;/p>
&lt;ul>
&lt;li>REST can use cache to improve response speed more efficiently.&lt;/li>
&lt;li>The stateless nature of the communication allows a set of servers to handle different requests in series, resulting in the increment of server scalability.&lt;/li>
&lt;li>Browser can be used as a client to simplify software requirements.&lt;/li>
&lt;li>REST software dependency is smaller than other mechanisms superimposed on HTTP.&lt;/li>
&lt;li>REST does not require additional resource discovery mechanism.&lt;/li>
&lt;li>REST&amp;rsquo;s long-term compatibility is better in software technology evolution.&lt;/li>
&lt;/ul>
&lt;p>Here I also want to add a particular advantage of REST: REST bases on simple text format messages and universal HTTP. Therefore, it has a broad applicability and is supported by almost all languages and platforms, together with a lower threshold in using and learning.&lt;/p>
&lt;h2 id="application-scenarios">Application scenarios&lt;/h2>
&lt;p>Because of the advantages of REST in applicability, supporting REST in Dubbo can bring (significant) benefits to most of current mainstream remoting call scenarios:&lt;/p>
&lt;ol>
&lt;li>
&lt;p>Significantly simplify (cross-language) calls between heterogeneous systems within the enterprise. This is mainly for the following scene: Dubbo acts as a service provider, and systems that are written by other languages (including some java systems that do not base on Dubbo) works as service consumers. The two systems communicate through HTTP and text messages. REST has its unique advantages even comparing to binary cross-language RPC frameworks such as Thrift and ProtoBuf. (See discussion below)&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Significantly simplify the development of the external Open API (Open Platform). You can use Dubbo to develop a specific Open API application, or you can directly publish the internal Dubbo service as a &amp;ldquo;transparent&amp;rdquo; REST API (Of course, it&amp;rsquo;s better for Dubbo itself to provide more features transparently, for example, permission control, frequency control, billing and so on).&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Significantly simplify the development of mobile (tablet) apps or desktop clients. Similar to point 2, you can use Dubbo to develop a specialized server for the applications, or transparently expose the internal Dubbo service. Of course in some projects, mobile or desktop applications can directly access the Open API described in point 2.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Significantly simplify the development of AJAX applications on the browser. Similar to point 2, you can use Dubbo to develop a specialized server for AJAX, or transparently expose the internal Dubbo service directly to JavaScript in the browser. Of course, many AJAX applications work better with web frameworks, so direct access to the Dubbo service may not be an exquisite architecture in many web projects.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Provide a text-based, easy-to-read remote call method for Dubbo systems within the enterprise (that is, both the service provider and the consumer are Dubbo-based systems).&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Simplify the call from the Dubbo system to other heterogeneous systems. You can use a simple way like Dubbo to &amp;ldquo;transparently&amp;rdquo; call REST services provided by Non-Dubbo systems (regardless of whether the service provider is inside or outside the enterprise)&lt;/p>
&lt;/li>
&lt;/ol>
&lt;p>It should be pointed out that I think that 1~3 are the most valuable application scenarios for Dubbo&amp;rsquo;s REST call. And the main purpose why we add REST calls for Dubbo is to provide a service-oriented provider. In other words, to develop REST services for Non-Dubbo (heterogeneous) consumers.&lt;/p>
&lt;p>To sum up, all application scenarios are shown below:
&lt;img src="https://dubbo.apache.org/imgs/user/rest.jpg" alt="rest.jpg">&lt;/p>
&lt;p>Borrowing the most famous slogan of Java in the past, by adding REST calls to Dubbo, you can implement the &amp;ldquo;Write once, access everywhere&amp;rdquo; service, which can theoretically be accessed all over the world, thus truly achieving an idealized Service-oriented Architecture (SOA).&lt;/p>
&lt;p>Of course, traditional Web Services (WSDL/SOAP) can meet the requirements (even those that require enterprise-level features) of the above scenarios (except for scenario 4). But due to the complexity and other issues, they are less and less used.&lt;/p>
&lt;h2 id="quick-start">Quick Start&lt;/h2>
&lt;p>Developing a RESTful service in Dubbo is relatively straightforward. Let&amp;rsquo;s take a simple user registration service for example.&lt;/p>
&lt;p>The function to be implemented by this service is to provide the following URL (Note: This URL is not entirely RESTful, but more straightforward and more practical):&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-fallback" data-lang="fallback">&lt;span style="display:flex;">&lt;span>http://localhost:8080/users/register
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Any client can POST a JSON string containing the user&amp;rsquo;s information to the above URL to complete the user registration.&lt;/p>
&lt;p>First, implement the interface of the service:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">UserService&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#dc322f">void&lt;/span> &lt;span style="color:#268bd2">registerUser&lt;/span>(User user);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Then, implement the service:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">@Path&lt;/span>(&lt;span style="color:#2aa198">&amp;#34;users&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">UserServiceImpl&lt;/span> &lt;span style="color:#268bd2">implements&lt;/span> UserService {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">@POST&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">@Path&lt;/span>(&lt;span style="color:#2aa198">&amp;#34;register&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">@Consumes&lt;/span>({MediaType.APPLICATION_JSON})
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#dc322f">void&lt;/span> &lt;span style="color:#268bd2">registerUser&lt;/span>(User user) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// save the user...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The above implementation code for the service is very simple, but since the REST service is to be published to a specific HTTP URL so they can be accessed by clients written by any language or even a browser, there are a few additional JAX-RS standard annotations to be added for the relevant configuration:&lt;/p>
&lt;p>@Path(&amp;ldquo;users&amp;rdquo;): Specify that the relative path for &lt;code>UserService&lt;/code> is &lt;code>/users&lt;/code>, standing for http://localhost:8080/users&lt;/p>
&lt;p>@Path(&amp;ldquo;register&amp;rdquo;): Specify that the relative path for &lt;code>registerUser()&lt;/code> is &lt;code>/register&lt;/code>. Combining the previous @Path specified for &lt;code>UserService&lt;/code>, the URL to call &lt;code>UserService.register()&lt;/code> is HTTP://localhost:8080/users/register&lt;/p>
&lt;p>@POST: Specify that &lt;code>registerUser()&lt;/code> should be accessed with HTTP POST method&lt;/p>
&lt;p>@Consumes({MediaType.APPLICATION_JSON}): Specify that &lt;code>registerUser()&lt;/code> receives data in JSON format. The REST framework will automatically deserialize JSON data into a User object.&lt;/p>
&lt;p>Finally, add this service to the spring configuration file and finish all service development work:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&amp;lt;!-- Exposure service on port 8080 with rest protocol --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;Dubbo:protocol&lt;/span> name=&lt;span style="color:#2aa198">&amp;#34;rest&amp;#34;&lt;/span> port=&lt;span style="color:#2aa198">&amp;#34;8080&amp;#34;&lt;/span>&lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&amp;lt;!-- Declare the service interface that needs to be exposed --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;Dubbo:service&lt;/span> interface=&lt;span style="color:#2aa198">&amp;#34;xxx.UserService&amp;#34;&lt;/span> ref=&lt;span style="color:#2aa198">&amp;#34;userService&amp;#34;&lt;/span>&lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&amp;lt;!-- Implement the service like the local bean --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;bean&lt;/span> id=&lt;span style="color:#2aa198">&amp;#34;userService&amp;#34;&lt;/span> class=&lt;span style="color:#2aa198">&amp;#34;xxx.UserServiceImpl&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="introduction-to-standard-java-rest-api-jax-rs">Introduction to Standard Java REST API: JAX-RS&lt;/h2>
&lt;p>JAX-RS is a standard Java REST API that has been widely supported and applied in the industry. There are many well-known open source implementations, including Oracle&amp;rsquo;s Jersey, RedHat&amp;rsquo;s RestEasy, Apache&amp;rsquo;s CXF and Wink, restlet, etc. In addition, all commercial JavaEE application servers that support the JavaEE 6.0 specifications or above support JAX-RS. Therefore, JAX-RS is a very mature solution, and it does not have any so-called vendor lock-in problems.&lt;/p>
&lt;p>JAX-RS has a wealth of information on the web, such as the following introductory tutorial:&lt;/p>
&lt;ul>
&lt;li>Oracle official tutorial: &lt;a href="https://www.oracle.com/technical-resources/articles/java/jax-rs.html">https://www.oracle.com/technical-resources/articles/java/jax-rs.html&lt;/a>&lt;/li>
&lt;li>Article on IBM developerWorks China: &lt;a href="http://www.ibm.com/developerworks/cn/java/j-lo-jaxrs/">http://www.ibm.com/developerworks/cn/java/j-lo-jaxrs/&lt;/a>&lt;/li>
&lt;/ul>
&lt;p>For more information, please feel free to Google or Baidu. As far as learning JAX-RS is concerned, it is generally enough to master the usage of various annotations.&lt;/p>
&lt;blockquote>
&lt;p>Note: Dubbo is based on the JAX-RS 2.0, and sometimes you need to pay attention to the version of the reference material or REST implementation.&lt;/p>
&lt;/blockquote>
&lt;h2 id="rest-service-provider-details">REST Service Provider Details&lt;/h2>
&lt;p>In this section, we will expand the &lt;code>UserService&lt;/code> in the &amp;ldquo;Quick Start&amp;rdquo; to further demonstrate the development points of the REST service provider in Dubbo.&lt;/p>
&lt;h3 id="implementation-of-http-postget">Implementation of HTTP POST/GET&lt;/h3>
&lt;p>Although it&amp;rsquo;s recommended to use the four standard methods (POST, DELETE, PUT and GET) in the HTTP protocol to implement common CRUD in REST services, but in practice, we generally use POST to implement create and update, and use GET to implement delete and read (DELETE and PUT will even be blocked by some firewalls).&lt;/p>
&lt;p>The implementation of POST has already been briefly demonstrated. Here, we will add a function to get the registered user data to &lt;code>UserService&lt;/code>, in order to demonstrate the implementation of GET.&lt;/p>
&lt;p>This function is to enable the client to obtain user data of different IDs by accessing different URLs as follows:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-fallback" data-lang="fallback">&lt;span style="display:flex;">&lt;span>http://localhost:8080/users/1001
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>http://localhost:8080/users/1002
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>http://localhost:8080/users/1003
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Of course, you can use other forms of URLs to access user data of different IDs, for example:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-gdscript3" data-lang="gdscript3">&lt;span style="display:flex;">&lt;span>http:&lt;span style="color:#719e07">//&lt;/span>localhost:&lt;span style="color:#2aa198">8080&lt;/span>&lt;span style="color:#719e07">/&lt;/span>users&lt;span style="color:#719e07">/&lt;/span>&lt;span style="color:#b58900">load&lt;/span>?id&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">1001&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>JAX-RS itself can support all of these forms. However, the first form of including query parameters in the URL path (http://localhost:8080/users/1001) is more in line with the general habit of REST, so it is recommended to use. Below we will add a &lt;code>getUser()&lt;/code> method to the &lt;code>UserService&lt;/code> to implement this form of URL access:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">@GET&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">@Path&lt;/span>(&lt;span style="color:#2aa198">&amp;#34;{id : \\d+}&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">@Produces&lt;/span>({MediaType.APPLICATION_JSON})
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> User &lt;span style="color:#268bd2">getUser&lt;/span>(&lt;span style="color:#268bd2">@PathParam&lt;/span>(&lt;span style="color:#2aa198">&amp;#34;id&amp;#34;&lt;/span>) Long id) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// ...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>@GET: Specify that the method shoule be accessed with HTTP GET method&lt;/p>
&lt;p>@Path(&amp;quot;{id : \d+}&amp;quot;): According to the above functional requirements, the URL to access &lt;code>getUser()&lt;/code> should be &amp;ldquo;http://localhost:8080/users/ + any number&amp;rdquo;, and this number should passed to &lt;code>getUser()&lt;/code> method as parameter passed to the getUser() method. In the annotation here, the {id: xxx} in @Path specifies that the relative path contains the id parameter, and its value will be automatically passed to the method parameter &lt;code>id&lt;/code> annotated with @PathParam(&amp;ldquo;id&amp;rdquo;). &lt;code>\d+&lt;/code> following &lt;code>{id:&lt;/code> is a regular expression specifies that the id parameter must be a number.&lt;/p>
&lt;p>@Produces({MediaType.APPLICATION_JSON}): Specify that &lt;code>getUser()&lt;/code> outputs data in JSON format. The REST framework automatically serializes the User object into JSON data.&lt;/p>
&lt;h3 id="is-annotation-put-in-interface-class-or-implementation-class">Is annotation put in interface class or implementation class?&lt;/h3>
&lt;p>The development of REST services based on Dubbo is mainly configured through JAX-RS annotations. In the above example, we put the annotation in the implementation class of the service. But in fact, we can completely put the annotation in the interface of the service. These two methods are completely equivalent, for example:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">@Path&lt;/span>(&lt;span style="color:#2aa198">&amp;#34;users&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">interface&lt;/span> &lt;span style="color:#268bd2">UserService&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">@GET&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">@Path&lt;/span>(&lt;span style="color:#2aa198">&amp;#34;{id : \\d+}&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">@Produces&lt;/span>({MediaType.APPLICATION_JSON})
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> User &lt;span style="color:#268bd2">getUser&lt;/span>(&lt;span style="color:#268bd2">@PathParam&lt;/span>(&lt;span style="color:#2aa198">&amp;#34;id&amp;#34;&lt;/span>) Long id);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>In a typical application, we recommend put the annotation in the service implementation class. Then, annotations are closer to Java implementation code and easier to develop and maintain. More importantly, we generally tend to avoid contamination of the interface, maintaining the purity and wide applicability of the interface.&lt;/p>
&lt;p>However, as will be described later, if we access this service by using the consumer directly developed by Dubbo, the annotation must be put in the interface.&lt;/p>
&lt;p>If the interface and the implementation class are both added annotation at the same time, the implementation configuration of the implementation class will take effect, and the annotation on the interface will be ignored.&lt;/p>
&lt;h3 id="support-for-json-xml-and-other-data-formats">Support for JSON, XML and other data formats&lt;/h3>
&lt;p>The dubbo REST services can support the transmission of data in multiple formats to provide maximum flexibility to the client. And we add extra functions to the JSON and XML formats which is most commonly used.&lt;/p>
&lt;p>For example, we want the &lt;code>getUser()&lt;/code> method in the above example support returning JSON and XML format data separately, just need to include two formats in the annotation:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">@Produces&lt;/span>({MediaType.APPLICATION_JSON, MediaType.TEXT_XML})
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>User &lt;span style="color:#268bd2">getUser&lt;/span>(&lt;span style="color:#268bd2">@PathParam&lt;/span>(&lt;span style="color:#2aa198">&amp;#34;id&amp;#34;&lt;/span>) Long id);
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Or you can directly represent a MediaType with a string (also supports wildcards):&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">@Produces&lt;/span>({&lt;span style="color:#2aa198">&amp;#34;application/json&amp;#34;&lt;/span>, &lt;span style="color:#2aa198">&amp;#34;text/xml&amp;#34;&lt;/span>})
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>User &lt;span style="color:#268bd2">getUser&lt;/span>(&lt;span style="color:#268bd2">@PathParam&lt;/span>(&lt;span style="color:#2aa198">&amp;#34;id&amp;#34;&lt;/span>) Long id);
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>If all methods support the same type of input and output data format, then we do not need to make configure on each method, just add annotation to the service class:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">@Path&lt;/span>(&lt;span style="color:#2aa198">&amp;#34;users&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">@Consumes&lt;/span>({MediaType.APPLICATION_JSON, MediaType.TEXT_XML})
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">@Produces&lt;/span>({MediaType.APPLICATION_JSON, MediaType.TEXT_XML})
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">UserServiceImpl&lt;/span> &lt;span style="color:#268bd2">implements&lt;/span> UserService {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// ...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>In the case where a REST service supports multiple data formats, according to the JAX-RS standard, the MIME header (content-type and accept) in HTTP is generally used to specify which format data is currently used.&lt;/p>
&lt;p>But in dubbo, we also automatically support the current common use of the industry, that is, use a URL suffix (.json and .xml) to specify the data format you want to use. For example, after adding the above annotation, directly accessing &lt;code>http://localhost:8888/users/1001.json&lt;/code> means using the json format, and directly accessing &lt;code>http://localhost:8888/users/1002.xml&lt;/code> means using the xml format. It&amp;rsquo;s simpler and more intuitive than using HTTP Header. This way is used by the REST APIs of Twitter, Weibo, etc.&lt;/p>
&lt;p>If you don&amp;rsquo;t add HTTP header or suffix, the REST of dubbo will give priority to enable the top ranked data format in the above definition of annotation.&lt;/p>
&lt;blockquote>
&lt;p>Note: To support XML format data, you can use either &lt;code>MediaType.TEXT_XML&lt;/code> or &lt;code>MediaType.APPLICATION_XML&lt;/code> in annotation, but TEXT_XML is more commonly used, and if you want to use the above URL suffix to specify the data format, you can only configure it as TEXT_XML to take effect.&lt;/p>
&lt;/blockquote>
&lt;h3 id="chinese-character-support">Chinese character support&lt;/h3>
&lt;p>In order to output Chinese characters normally in dubbo REST, as with the usual Java web applications, we need to set the contentType of the HTTP response to UTF-8 encoding.&lt;/p>
&lt;p>Based on the standard usage of JAX-RS, we only need to do the following annotation configuration:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">@Produces&lt;/span>({&lt;span style="color:#2aa198">&amp;#34;application/json; charset=UTF-8&amp;#34;&lt;/span>, &lt;span style="color:#2aa198">&amp;#34;text/xml; charset=UTF-8&amp;#34;&lt;/span>})
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>User &lt;span style="color:#268bd2">getUser&lt;/span>(&lt;span style="color:#268bd2">@PathParam&lt;/span>(&lt;span style="color:#2aa198">&amp;#34;id&amp;#34;&lt;/span>) Long id);
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>For the convenience of users, we add a support class directly in dubbo REST to define the above constants, which can be used directly and reduce the possibility of error.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">@Produces&lt;/span>({ContentType.APPLICATION_JSON_UTF_8, ContentType.TEXT_XML_UTF_8})
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>User &lt;span style="color:#268bd2">getUser&lt;/span>(&lt;span style="color:#268bd2">@PathParam&lt;/span>(&lt;span style="color:#2aa198">&amp;#34;id&amp;#34;&lt;/span>) Long id);
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="additional-requirements-for-xml-data-format">Additional requirements for XML data format&lt;/h3>
&lt;p>Because the implementation of JAX-RS generally use standard JAXB (Java API for XML Binding) to serialize and deserialize XML format data, we need to add a class-level JAXB annotation for each object to be transferred in XML. Otherwise serialization will report an error. For example, add follows to the User returned in &lt;code>getUser()&lt;/code> :&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">@XmlRootElement&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">User&lt;/span> &lt;span style="color:#268bd2">implements&lt;/span> Serializable {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// ...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>In addition, if the return value in the service method is Java primitive type (such as int, long, float, double, etc.), it is best to add a wrapper object to them, because JAXB can not directly serialize the primitive type.&lt;/p>
&lt;p>For example, we want the above &lt;code>registerUser()&lt;/code> method to return the ID number generated by the server for the user:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#dc322f">long&lt;/span> &lt;span style="color:#268bd2">registerUser&lt;/span>(User user);
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Because the primitive type is not supported by JAXB serialization, add a wrapper object:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">@XmlRootElement&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">RegistrationResult&lt;/span> &lt;span style="color:#268bd2">implements&lt;/span> Serializable {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">private&lt;/span> Long id;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">RegistrationResult&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">RegistrationResult&lt;/span>(Long id) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">this&lt;/span>.id &lt;span style="color:#719e07">=&lt;/span> id;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> Long &lt;span style="color:#268bd2">getId&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">return&lt;/span> id;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#dc322f">void&lt;/span> &lt;span style="color:#268bd2">setId&lt;/span>(Long id) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">this&lt;/span>.id &lt;span style="color:#719e07">=&lt;/span> id;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>And modify the service method:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>RegistrationResult &lt;span style="color:#268bd2">registerUser&lt;/span>(User user);
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>This not only solves the problem of XML serialization, but also makes the returned data conform to the specifications of XML and JSON. For example, in JSON, the returned form would be as follows:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-javascript" data-lang="javascript">&lt;span style="display:flex;">&lt;span>{&lt;span style="color:#2aa198">&amp;#34;id&amp;#34;&lt;/span>&lt;span style="color:#719e07">:&lt;/span> &lt;span style="color:#2aa198">1001&lt;/span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>If you do not add a wrapper, the JSON return value will be directly&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-fallback" data-lang="fallback">&lt;span style="display:flex;">&lt;span>1001
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>In XML, the return value after adding wrapper will be:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;registrationResult&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;id&amp;gt;&lt;/span>1002&lt;span style="color:#268bd2">&amp;lt;/id&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;/registrationResult&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>This wrapper object actually uses the so-called Data Transfer Object (DTO) mode, and DTO can also make more useful customizations for transferring data.
While in XML, after adding wrapper, the return value will be&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;registrationResult&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;id&amp;gt;&lt;/span>1002&lt;span style="color:#268bd2">&amp;lt;/id&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;/registrationResult&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>In fact, this wrapper object uses the so-called Data Transfer Object (DTO) mode. DTO can also be used to make more useful customizations to transfer data.&lt;/p>
&lt;h3 id="custom-serialization">Custom Serialization&lt;/h3>
&lt;p>As mentioned above, the underlying implementation of REST will automatically serialize/deserialize between the service object and the JSON/XML data format.&lt;/p>
&lt;p>The REST implementation in Dubbo uses JAXB for XML serialization and Jackson for JSON serialization,so you can customize the mapping by adding JAXB or Jackson&amp;rsquo;s annotation to the object.&lt;/p>
&lt;p>For example, customizing the object properties to map to the names of the XML elements:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">@XmlRootElement&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">@XmlAccessorType&lt;/span>(XmlAccessType.FIELD)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">User&lt;/span> &lt;span style="color:#268bd2">implements&lt;/span> Serializable {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">@XmlElement&lt;/span>(name&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">&amp;#34;username&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">private&lt;/span> String name;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Customizing the object properties to map to the names of the JSON field:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">User&lt;/span> &lt;span style="color:#268bd2">implements&lt;/span> Serializable {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">@JsonProperty&lt;/span>(&lt;span style="color:#2aa198">&amp;#34;username&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">private&lt;/span> String name;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>For more information, please refer to the official documentation of JAXB and Jackson, or google yourself.&lt;/p>
&lt;h3 id="configuring-rest-server-implementation">Configuring REST Server implementation&lt;/h3>
&lt;p>Currently in dubbo, we support the implementation of five embedded rest servers. The implementation of the rest server is selected by the following XML attribute of the server:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:protocol&lt;/span> name=&lt;span style="color:#2aa198">&amp;#34;rest&amp;#34;&lt;/span> server=&lt;span style="color:#2aa198">&amp;#34;jetty&amp;#34;&lt;/span>&lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The above configuration uses the embedded jetty to do the rest server. At the same time, if you do not configure the server attribute, the rest protocol also uses jetty by default. jetty is a very mature java servlet container and has a good integration with dubbob (Among the five embedded servers, Only jetty and later tomcat、tjws, complete seamless integration with Dubbo monitoring system.), so, if your dubbo system is a separate process, you can use jetty by default.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:protocol&lt;/span> name=&lt;span style="color:#2aa198">&amp;#34;rest&amp;#34;&lt;/span> server=&lt;span style="color:#2aa198">&amp;#34;tomcat&amp;#34;&lt;/span>&lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The above configuration uses the embedded tomcat to do the rest server.On embedded tomcat, REST performance is much better than jetty (See the benchmark below). It is recommended that Tomcat is used in scenarios where high performance is required.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:protocol&lt;/span> name=&lt;span style="color:#2aa198">&amp;#34;rest&amp;#34;&lt;/span> server=&lt;span style="color:#2aa198">&amp;#34;netty&amp;#34;&lt;/span>&lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The above configuration uses embedded netty to do the rest server. (TODO more contents to add)&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:protocol&lt;/span> name=&lt;span style="color:#2aa198">&amp;#34;rest&amp;#34;&lt;/span> server=&lt;span style="color:#2aa198">&amp;#34;tjws&amp;#34;&lt;/span>&lt;span style="color:#268bd2">/&amp;gt;&lt;/span> (tjws is now deprecated)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:protocol&lt;/span> name=&lt;span style="color:#2aa198">&amp;#34;rest&amp;#34;&lt;/span> server=&lt;span style="color:#2aa198">&amp;#34;sunhttp&amp;#34;&lt;/span>&lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The above configuration uses embedded tjws or Sun HTTP server to do the rest server. These two server implementations are very lightweight, it is very convenient for quick start-up in integration testing, of course, it can also be used in a production environment with low load. Note: tjws is currently deprecated because it does not work well with the servlet 3.1 API.&lt;/p>
&lt;p>If your dubbo system is not a separate process,
instead of deploying to a Java application server, we recommend the following configuration:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:protocol&lt;/span> name=&lt;span style="color:#2aa198">&amp;#34;rest&amp;#34;&lt;/span> server=&lt;span style="color:#2aa198">&amp;#34;servlet&amp;#34;&lt;/span>&lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>By setting the server as the servlet, dubbo will use the servlet container of the external application server to do the rest server. At the same time, add the following configuration to the web.xml of the dubbo system:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;web-app&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;context-param&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;param-name&amp;gt;&lt;/span>contextConfigLocation&lt;span style="color:#268bd2">&amp;lt;/param-name&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;param-value&amp;gt;&lt;/span>/WEB-INF/classes/META-INF/spring/dubbo-demo-provider.xml&lt;span style="color:#268bd2">&amp;lt;/param-value&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;/context-param&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;listener&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;listener-class&amp;gt;&lt;/span>org.apache.dubbo.remoting.http.servlet.BootstrapListener&lt;span style="color:#268bd2">&amp;lt;/listener-class&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;/listener&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;listener&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;listener-class&amp;gt;&lt;/span>org.springframework.web.context.ContextLoaderListener&lt;span style="color:#268bd2">&amp;lt;/listener-class&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;/listener&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;servlet&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;servlet-name&amp;gt;&lt;/span>dispatcher&lt;span style="color:#268bd2">&amp;lt;/servlet-name&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;servlet-class&amp;gt;&lt;/span>org.apache.dubbo.remoting.http.servlet.DispatcherServlet&lt;span style="color:#268bd2">&amp;lt;/servlet-class&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;load-on-startup&amp;gt;&lt;/span>1&lt;span style="color:#268bd2">&amp;lt;/load-on-startup&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;/servlet&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;servlet-mapping&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;servlet-name&amp;gt;&lt;/span>dispatcher&lt;span style="color:#268bd2">&amp;lt;/servlet-name&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;url-pattern&amp;gt;&lt;/span>/*&lt;span style="color:#268bd2">&amp;lt;/url-pattern&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;/servlet-mapping&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;/web-app&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>In other words, you must add dubbo&amp;rsquo;s BootstrapListener and DispatherServlet to web.xml to complete the integration of dubbo&amp;rsquo;s REST functionality with the external servlet container.&lt;/p>
&lt;blockquote>
&lt;p>Note:If you are using spring&amp;rsquo;s ContextLoaderListener to load spring, you must ensure that the BootstrapListener is configured before the ContextLoaderListener, otherwise the dubbo initialization will fail.&lt;/p>
&lt;/blockquote>
&lt;p>In fact, you can still stick to the embedded server in this scenario, but the servlet container of the external application server is often more powerful than the embedded server(Especially if you are deploying to a more robust and scalable WebLogic, WebSphere, etc.). In addition, it is sometimes convenient to do unified management, monitoring, and so on in the application server.&lt;/p>
&lt;h3 id="get-context-information">Get Context Information&lt;/h3>
&lt;p>Varieties of context information are valuable when calling procedures remotely. For instance, the IP address from the Client.&lt;/p>
&lt;p>We provide two methods to get the Client&amp;rsquo;s IP in dubbo.&lt;/p>
&lt;p>The first one is using @Context annotation from JAX-RS:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> User &lt;span style="color:#268bd2">getUser&lt;/span>(&lt;span style="color:#268bd2">@PathParam&lt;/span>(&lt;span style="color:#2aa198">&amp;#34;id&amp;#34;&lt;/span>) Long id, &lt;span style="color:#268bd2">@Context&lt;/span> HttpServletRequest request) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> System.out.println(&lt;span style="color:#2aa198">&amp;#34;Client address is &amp;#34;&lt;/span> &lt;span style="color:#719e07">+&lt;/span> request.getRemoteAddr());
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>After decorating a parameter of &lt;code>getUser()&lt;/code> with Context, we can inject the current HttpServletRequest and then call the servlet api to get the IP.&lt;/p>
&lt;blockquote>
&lt;p>Notice: This method can only be used when the server is one of the followings: twjs, tomecat, jetty or servlet. All of them provide servlet container. In addition, standard JAX-RS also allow us to get HttpServletRequest using an instance field in service Class decorated by &lt;code>@Context&lt;/code>.&lt;/p>
&lt;/blockquote>
&lt;p>The second method is to use RpcContext, which is commonly seen in dubbo:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> User &lt;span style="color:#268bd2">getUser&lt;/span>(&lt;span style="color:#268bd2">@PathParam&lt;/span>(&lt;span style="color:#2aa198">&amp;#34;id&amp;#34;&lt;/span>) Long id) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> System.out.println(&lt;span style="color:#2aa198">&amp;#34;Client address is &amp;#34;&lt;/span> &lt;span style="color:#719e07">+&lt;/span> RpcContext.getContext().getRemoteAddressString());
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;blockquote>
&lt;p>Notice: Similarly, this method only works in the jetty, tomcat, servlet or tjws server. In dubbo, the usage of RpcContext is rather invasive. We are likely to refactor it in the future.&lt;/p>
&lt;/blockquote>
&lt;p>The first method is suggested when your project may run without dubbo and need the compatibility with JAX-RS. But if you want a more elegant service interface definition, the second method would be the better choice.&lt;/p>
&lt;p>What&amp;rsquo;s more, in the newest version of dubbo REST service, RpcContext could be used to get HttpServletRequest and HttpServletResponse, providing great flexibility for users to implement some complex functions. The following is an example:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">if&lt;/span> (RpcContext.getContext().getRequest() &lt;span style="color:#719e07">!=&lt;/span> &lt;span style="color:#cb4b16">null&lt;/span> &lt;span style="color:#719e07">&amp;amp;&amp;amp;&lt;/span> RpcContext.getContext().getRequest() &lt;span style="color:#719e07">instanceof&lt;/span> HttpServletRequest) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> System.out.println(&lt;span style="color:#2aa198">&amp;#34;Client address is &amp;#34;&lt;/span> &lt;span style="color:#719e07">+&lt;/span> ((HttpServletRequest) RpcContext.getContext().getRequest()).getRemoteAddr());
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">if&lt;/span> (RpcContext.getContext().getResponse() &lt;span style="color:#719e07">!=&lt;/span> &lt;span style="color:#cb4b16">null&lt;/span> &lt;span style="color:#719e07">&amp;amp;&amp;amp;&lt;/span> RpcContext.getContext().getResponse() &lt;span style="color:#719e07">instanceof&lt;/span> HttpServletResponse) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> System.out.println(&lt;span style="color:#2aa198">&amp;#34;Response object from RpcContext: &amp;#34;&lt;/span> &lt;span style="color:#719e07">+&lt;/span> RpcContext.getContext().getResponse());
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;blockquote>
&lt;p>Notice:
In order to maintain the neutrality of the protocol, &lt;code>RpcContext.getRequest()&lt;/code> and &lt;code>RpcContext.getResponse()&lt;/code> only return an Object which could be null. Therefore, you have to check the type on your own.&lt;/p>
&lt;/blockquote>
&lt;blockquote>
&lt;p>Notice: only when you use jetty, tomcat, servlet as the server can you get the HttpServletRequest and HttpServletResponse as expected. Because only these server
implemented the servlet container.&lt;/p>
&lt;/blockquote>
&lt;p>To simplify the programme, you can also use generic to get a specific type of request/response:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">if&lt;/span> (RpcContext.getContext().getRequest(HttpServletRequest.class) &lt;span style="color:#719e07">!=&lt;/span> &lt;span style="color:#cb4b16">null&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> System.out.println(&lt;span style="color:#2aa198">&amp;#34;Client address is &amp;#34;&lt;/span> &lt;span style="color:#719e07">+&lt;/span> RpcContext.getContext().getRequest(HttpServletRequest.class).getRemoteAddr());
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">if&lt;/span> (RpcContext.getContext().getResponse(HttpServletResponse.class) &lt;span style="color:#719e07">!=&lt;/span> &lt;span style="color:#cb4b16">null&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> System.out.println(&lt;span style="color:#2aa198">&amp;#34;Response object from RpcContext: &amp;#34;&lt;/span> &lt;span style="color:#719e07">+&lt;/span> RpcContext.getContext().getResponse(HttpServletResponse.class));
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>If request/response does not correspond to the specific type, it would return null.&lt;/p>
&lt;h3 id="configure-the-port-number-and-context-path">Configure The Port Number and Context Path&lt;/h3>
&lt;p>The REST protocol in dubbo use 80 as the default port. But you are also allowed to modify it:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:protocol&lt;/span> name=&lt;span style="color:#2aa198">&amp;#34;rest&amp;#34;&lt;/span> port=&lt;span style="color:#2aa198">&amp;#34;8888&amp;#34;&lt;/span>&lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>As what have been metioned before, we can use &lt;code>@Path&lt;/code> to configure relative URL path in single REST service. In fact, we can also set a basic relative path which is known as context path for all REST service.&lt;/p>
&lt;p>All we need to do is to add the contextpath property:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:protocol&lt;/span> name=&lt;span style="color:#2aa198">&amp;#34;rest&amp;#34;&lt;/span> port=&lt;span style="color:#2aa198">&amp;#34;8888&amp;#34;&lt;/span> contextpath=&lt;span style="color:#2aa198">&amp;#34;services&amp;#34;&lt;/span>&lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Let&amp;rsquo;s have a look at the previous code:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">@Path&lt;/span>(&lt;span style="color:#2aa198">&amp;#34;users&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">UserServiceImpl&lt;/span> &lt;span style="color:#268bd2">implements&lt;/span> UserService {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">@POST&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">@Path&lt;/span>(&lt;span style="color:#2aa198">&amp;#34;register&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">@Consumes&lt;/span>({MediaType.APPLICATION_JSON})
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#dc322f">void&lt;/span> &lt;span style="color:#268bd2">registerUser&lt;/span>(User user) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// save the user...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Now the complete path would be:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-fallback" data-lang="fallback">&lt;span style="display:flex;">&lt;span>http://localhost:8888/services/users/register
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Notice: If you use external server as REST server, you should configure as followings,&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:protocol&lt;/span> name=&lt;span style="color:#2aa198">&amp;#34;rest&amp;#34;&lt;/span> port=&lt;span style="color:#2aa198">&amp;#34;8888&amp;#34;&lt;/span> contextpath=&lt;span style="color:#2aa198">&amp;#34;services&amp;#34;&lt;/span> server=&lt;span style="color:#2aa198">&amp;#34;servlet&amp;#34;&lt;/span>&lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>meaning that you should keep the config of port and contextpath are the same with the port and DispatcherServlet&amp;rsquo;s context path (webapp path + servlet url pattern) in external server. For example, when we are configuring the application on tomcat Root path, we need to make sure the contextpath here is totally the same with the &lt;code>&amp;lt;url-pattern/&amp;gt;&lt;/code> of DispacherServlet in web.xml:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;servlet-mapping&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;servlet-name&amp;gt;&lt;/span>dispatcher&lt;span style="color:#268bd2">&amp;lt;/servlet-name&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;url-pattern&amp;gt;&lt;/span>/services/*&lt;span style="color:#268bd2">&amp;lt;/url-pattern&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;/servlet-mapping&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="configure-the-number-of-threads-and-io-threads">Configure the number of threads and IO threads&lt;/h3>
&lt;p>We can set the number of threads of rest service:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:protocol&lt;/span> name=&lt;span style="color:#2aa198">&amp;#34;rest&amp;#34;&lt;/span> threads=&lt;span style="color:#2aa198">&amp;#34;500&amp;#34;&lt;/span>&lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;blockquote>
&lt;p>Notice: Currently, the setting only works when the server is netty, jetty or tomcat. If you use servlet as the server, you are using the external server as the REST server which is out of dubboes&amp;rsquo; control, so the setting would not work expectedly.&lt;/p>
&lt;/blockquote>
&lt;p>You can also set threads number of IO worker of netty server:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:protocol&lt;/span> name=&lt;span style="color:#2aa198">&amp;#34;rest&amp;#34;&lt;/span> iothreads=&lt;span style="color:#2aa198">&amp;#34;5&amp;#34;&lt;/span> threads=&lt;span style="color:#2aa198">&amp;#34;100&amp;#34;&lt;/span>&lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="configure-long-connections">Configure long connections&lt;/h3>
&lt;p>The REST service in Dubbo is accessed by default with http long connection, if you want to switch to short connection, you can configure it as below:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:protocol&lt;/span> name=&lt;span style="color:#2aa198">&amp;#34;rest&amp;#34;&lt;/span> keepalive=&lt;span style="color:#2aa198">&amp;#34;false&amp;#34;&lt;/span>&lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;blockquote>
&lt;p>Notice: This configuration only works in netty and tomcat.&lt;/p>
&lt;/blockquote>
&lt;h3 id="configure-the-maximum-number-of-http-connections">Configure the maximum number of HTTP connections&lt;/h3>
&lt;p>Configuring the maximum number of HTTP connections can prevent REST server from
overload as the basic self-protection mechanism.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:protocol&lt;/span> name=&lt;span style="color:#2aa198">&amp;#34;rest&amp;#34;&lt;/span> accepts=&lt;span style="color:#2aa198">&amp;#34;500&amp;#34;&lt;/span> server=&lt;span style="color:#2aa198">&amp;#34;tomcat/&lt;/span>&lt;span style="color:#268bd2">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;blockquote>
&lt;p>Notice: Currently, it only works in tomcat.&lt;/p>
&lt;/blockquote>
&lt;h3 id="configuring-the-timeout-and-http-connections-for-each-consumer">Configuring the timeout and HTTP connections for each consumer&lt;/h3>
&lt;p>If the consumer of the rest service is also a dubbo system, you can configure the maximum timeout for the consumer to call the rest service, and the maximum number of HTTP connections that each consumer can initiate, just like other dubbo RPC mechanisms.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:service&lt;/span> interface=&lt;span style="color:#2aa198">&amp;#34;xxx&amp;#34;&lt;/span> ref=&lt;span style="color:#2aa198">&amp;#34;xxx&amp;#34;&lt;/span> protocol=&lt;span style="color:#2aa198">&amp;#34;rest&amp;#34;&lt;/span> timeout=&lt;span style="color:#2aa198">&amp;#34;2000&amp;#34;&lt;/span> connections=&lt;span style="color:#2aa198">&amp;#34;10&amp;#34;&lt;/span>&lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Of course, since this configuration is valid for the consumer, it can also be configured on the consumer side:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:reference&lt;/span> id=&lt;span style="color:#2aa198">&amp;#34;xxx&amp;#34;&lt;/span> interface=&lt;span style="color:#2aa198">&amp;#34;xxx&amp;#34;&lt;/span> timeout=&lt;span style="color:#2aa198">&amp;#34;2000&amp;#34;&lt;/span> connections=&lt;span style="color:#2aa198">&amp;#34;10&amp;#34;&lt;/span>&lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>However, we generally recommend configuring the service provider to provide such a configuration. According to the official dubbo documentation, “Provider should configure the properties of the Consumer side as much as possible.
Let the Provider implementer think about the service features and service quality of the Provider from the beginning.”&lt;/p>
&lt;blockquote>
&lt;p>Note: If dubbo REST service is released to non-dubbo clients, the configuration on &lt;code>&amp;lt;dubbo:service/&amp;gt;&lt;/code> is completely invalid because the client is not under dubbo control.&lt;/p>
&lt;/blockquote>
&lt;h3 id="gzip-data-compresssion">GZIP data compresssion&lt;/h3>
&lt;p>Dubbo RESTful Remoting supports the use of Gzip to compress request and response data to reduce network transmission time and bandwidth consumption, but this will also increase CPU overhead.&lt;/p>
&lt;p>TODO more contents to add.&lt;/p>
&lt;h3 id="replacing-part-of-the-spring-xml-configuration-with-annotation">Replacing part of the spring XML configuration with annotation&lt;/h3>
&lt;p>Above discussions are based on the XML configuration of Dubbo in spring.
However, dubbo/spring itself supports the use of annotation for configuration, so we can also follow the steps in the Dubbo document and add the relevant annotation to the REST service implementation, replacing some XML configurations, such as:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">@Service&lt;/span>(protocol &lt;span style="color:#719e07">=&lt;/span> &lt;span style="color:#2aa198">&amp;#34;rest&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">@Path&lt;/span>(&lt;span style="color:#2aa198">&amp;#34;users&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">UserServiceImpl&lt;/span> &lt;span style="color:#268bd2">implements&lt;/span> UserService {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">@Autowired&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">private&lt;/span> UserRepository userRepository;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">@POST&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">@Path&lt;/span>(&lt;span style="color:#2aa198">&amp;#34;register&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">@Consumes&lt;/span>({MediaType.APPLICATION_JSON})
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#dc322f">void&lt;/span> &lt;span style="color:#268bd2">registerUser&lt;/span>(User user) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// save the user&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> userRepository.save(user);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Annotation-based configuration is more concise and precise, and often easier to maintain (modern IDE can support such things as class name refactoring in XML, and therefore the maintenance of XML is good for specific use cases here). XML is less intrusive to code, especially for dynamically modifying configurations, especially when you want to modify the timeout for connection of a single service configuration, the maximum number of connections per client, cluster policy, weights, and so on. In addition, for complex applications or modules, XML provides a central point to cover all the components and configurations. It is at a glance, and generally more convenient for long term maintenance of the project.&lt;/p>
&lt;p>Of course, there&amp;rsquo;s no right or wrong of different choices of configuration method. Sometimes it&amp;rsquo;s just personal preference.&lt;/p>
&lt;h3 id="adding-a-custom-filter-interceptor-etc">Adding a custom Filter, Interceptor, etc&lt;/h3>
&lt;p>Dubbo RESTful Remoting also supports JAX-RS standard Filter and Interceptor to facilitate customized interception of REST request and response processes.&lt;/p>
&lt;p>Here, Filter is mainly used to access and set parameters, URIs for HTTP request and response, and so on, for example, setting the cache header for HTTP response:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">CacheControlFilter&lt;/span> &lt;span style="color:#268bd2">implements&lt;/span> ContainerResponseFilter {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#dc322f">void&lt;/span> &lt;span style="color:#268bd2">filter&lt;/span>(ContainerRequestContext req, ContainerResponseContext res) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">if&lt;/span> (req.getMethod().equals(&lt;span style="color:#2aa198">&amp;#34;GET&amp;#34;&lt;/span>)) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> res.getHeaders().add(&lt;span style="color:#2aa198">&amp;#34;Cache-Control&amp;#34;&lt;/span>, &lt;span style="color:#2aa198">&amp;#34;someValue&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Interceptor is mainly used to access and modify the input and output byte streams, for example, manually adding GZIP compression:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">GZIPWriterInterceptor&lt;/span> &lt;span style="color:#268bd2">implements&lt;/span> WriterInterceptor {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">@Override&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#dc322f">void&lt;/span> &lt;span style="color:#268bd2">aroundWriteTo&lt;/span>(WriterInterceptorContext context)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">throws&lt;/span> IOException, WebApplicationException {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> OutputStream outputStream &lt;span style="color:#719e07">=&lt;/span> context.getOutputStream();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> context.setOutputStream(&lt;span style="color:#719e07">new&lt;/span> GZIPOutputStream(outputStream));
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> context.proceed();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>In standard JAX-RS applications, we generally add @Provider annotations to Filter and Interceptor, and JAX-RS runtime will automatically discover and enable them. In Dubbo, we register Filter and Interceptor by adding an XML configuration:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:protocol&lt;/span> name=&lt;span style="color:#2aa198">&amp;#34;rest&amp;#34;&lt;/span> port=&lt;span style="color:#2aa198">&amp;#34;8888&amp;#34;&lt;/span> extension=&lt;span style="color:#2aa198">&amp;#34;xxx.TraceInterceptor, xxx.TraceFilter&amp;#34;&lt;/span>&lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Here, we can add these three types of objects, Filter, Interceptor and DynamicFeature, to the &lt;code>extension&lt;/code> attributes, separated by commas. (DynamicFeature is another interface that allows us to enable Filter and Interceptor more dynamically. Please feel free to google.)&lt;/p>
&lt;p>Of course, Dubbo itself also supports Filter, but the Filter and Interceptor we discuss here are more like the bottom of the protocol implementation. Compared to Dubbo&amp;rsquo;s filter, you can do a lower level of customization here.&lt;/p>
&lt;blockquote>
&lt;p>Note: The XML attribute here is called extension, not interceptor or filter. That is because we will add more extension types in addition to Interceptor and Filter in the future.&lt;/p>
&lt;/blockquote>
&lt;p>If the REST consumer is also a Dubbo system (see discussion below), you can also configure the Interceptor and Filter for the consumer in a similar way.&lt;/p>
&lt;p>However, it should be noted that the consumer-side Filter and the provider-side Filter in JAX-RS are two different interfaces. For example, in the previous example, the server is the ContainerResponseFilter interface, and the consumer side corresponds to the ClientResponseFilter:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">LoggingFilter&lt;/span> &lt;span style="color:#268bd2">implements&lt;/span> ClientResponseFilter {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#dc322f">void&lt;/span> &lt;span style="color:#268bd2">filter&lt;/span>(ClientRequestContext reqCtx, ClientResponseContext resCtx) &lt;span style="color:#268bd2">throws&lt;/span> IOException {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> System.out.println(&lt;span style="color:#2aa198">&amp;#34;status: &amp;#34;&lt;/span> &lt;span style="color:#719e07">+&lt;/span> resCtx.getStatus());
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> System.out.println(&lt;span style="color:#2aa198">&amp;#34;date: &amp;#34;&lt;/span> &lt;span style="color:#719e07">+&lt;/span> resCtx.getDate());
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> System.out.println(&lt;span style="color:#2aa198">&amp;#34;last-modified: &amp;#34;&lt;/span> &lt;span style="color:#719e07">+&lt;/span> resCtx.getLastModified());
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> System.out.println(&lt;span style="color:#2aa198">&amp;#34;location: &amp;#34;&lt;/span> &lt;span style="color:#719e07">+&lt;/span> resCtx.getLocation());
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> System.out.println(&lt;span style="color:#2aa198">&amp;#34;headers:&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">for&lt;/span> (Entry&lt;span style="color:#719e07">&amp;lt;&lt;/span>String, List&lt;span style="color:#719e07">&amp;lt;&lt;/span>String&lt;span style="color:#719e07">&amp;gt;&amp;gt;&lt;/span> header : resCtx.getHeaders().entrySet()) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> System.out.print(&lt;span style="color:#2aa198">&amp;#34;\t&amp;#34;&lt;/span> &lt;span style="color:#719e07">+&lt;/span> header.getKey() &lt;span style="color:#719e07">+&lt;/span> &lt;span style="color:#2aa198">&amp;#34; :&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">for&lt;/span> (String value : header.getValue()) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> System.out.print(value &lt;span style="color:#719e07">+&lt;/span> &lt;span style="color:#2aa198">&amp;#34;, &amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> System.out.print(&lt;span style="color:#2aa198">&amp;#34;\n&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> System.out.println(&lt;span style="color:#2aa198">&amp;#34;media-type: &amp;#34;&lt;/span> &lt;span style="color:#719e07">+&lt;/span> resCtx.getMediaType().getType());
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="adding-custom-exception-handler">Adding custom Exception handler&lt;/h3>
&lt;p>Dubbo RESTful Remoting also supports JAX-RS standard ExceptionMapper, which can be used to customize the HTTP response after a particular exception occurs.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">CustomExceptionMapper&lt;/span> &lt;span style="color:#268bd2">implements&lt;/span> ExceptionMapper&lt;span style="color:#719e07">&amp;lt;&lt;/span>NotFoundException&lt;span style="color:#719e07">&amp;gt;&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> Response &lt;span style="color:#268bd2">toResponse&lt;/span>(NotFoundException e) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">return&lt;/span> Response.status(Response.Status.NOT_FOUND).entity(&lt;span style="color:#2aa198">&amp;#34;Oops! the requested resource is not found!&amp;#34;&lt;/span>).type(&lt;span style="color:#2aa198">&amp;#34;text/plain&amp;#34;&lt;/span>).build();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Similar to Interceptor and Filter, it can be enabled by adding it to an XML configuration file:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:protocol&lt;/span> name=&lt;span style="color:#2aa198">&amp;#34;rest&amp;#34;&lt;/span> port=&lt;span style="color:#2aa198">&amp;#34;8888&amp;#34;&lt;/span> extension=&lt;span style="color:#2aa198">&amp;#34;xxx.CustomExceptiionMapper&amp;#34;&lt;/span>&lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="configuring-http-log-output">Configuring HTTP log output&lt;/h3>
&lt;p>Dubbo RESTful Remoting supports outputting the header and body in all HTTP requests/responses.&lt;/p>
&lt;p>Add the following REST filter to the XML configuration:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:protocol&lt;/span> name=&lt;span style="color:#2aa198">&amp;#34;rest&amp;#34;&lt;/span> port=&lt;span style="color:#2aa198">&amp;#34;8888&amp;#34;&lt;/span> extension=&lt;span style="color:#2aa198">&amp;#34;org.apache.dubbo.rpc.protocol.rest.support.LoggingFilter&amp;#34;&lt;/span>&lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;strong>Then turn on at least INFO level log output for org.apache.dubbo.rpc.protocol.rest.support in the logging configuration&lt;/strong>,for example,in log4j.xml:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;logger&lt;/span> name=&lt;span style="color:#2aa198">&amp;#34;org.apache.dubbo.rpc.protocol.rest.support&amp;#34;&lt;/span>&lt;span style="color:#268bd2">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;level&lt;/span> value=&lt;span style="color:#2aa198">&amp;#34;INFO&amp;#34;&lt;/span>&lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;appender-ref&lt;/span> ref=&lt;span style="color:#2aa198">&amp;#34;CONSOLE&amp;#34;&lt;/span>&lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;/logger&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Of course, you can also turn on INFO level log output directly in the ROOT logger:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;root&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;level&lt;/span> value=&lt;span style="color:#2aa198">&amp;#34;INFO&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;appender-ref&lt;/span> ref=&lt;span style="color:#2aa198">&amp;#34;CONSOLE&amp;#34;&lt;/span>&lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;/root&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Then there will be something like the following output in the log:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-fallback" data-lang="fallback">&lt;span style="display:flex;">&lt;span>The HTTP headers are:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>accept: application/json;charset=UTF-8
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>accept-encoding: gzip, deflate
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>connection: Keep-Alive
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>content-length: 22
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>content-type: application/json
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>host: 192.168.1.100:8888
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>user-agent: Apache-HttpClient/4.2.1 (java 1.5)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-fallback" data-lang="fallback">&lt;span style="display:flex;">&lt;span>The contents of request body is:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{&amp;#34;id&amp;#34;:1,&amp;#34;name&amp;#34;:&amp;#34;dang&amp;#34;}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>After the HTTP log output is turned on, in addition to the performance overhead of the normal log output, additional overhead is generated in, for example, HTTP request parsing, because an additional memory buffer needs to be allocated to prepare the data for the log output.&lt;/p>
&lt;h3 id="inputing-parameter-validation">Inputing parameter validation&lt;/h3>
&lt;p>Dubbo RESTful Remoting supports the use of the Java standard bean validation annotation(JSR 303) for input validation &lt;a href="http://beanvalidation.org/">http://beanvalidation.org/&lt;/a>.&lt;/p>
&lt;p>In order to be consistent with other Dubbo remote invocation protocols, the annotations that are checked for rest must be placed on the interface of the service, for example:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">interface&lt;/span> &lt;span style="color:#268bd2">UserService&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> User &lt;span style="color:#268bd2">getUser&lt;/span>(&lt;span style="color:#268bd2">@Min&lt;/span>(value&lt;span style="color:#719e07">=&lt;/span>1L, message&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">&amp;#34;User ID must be greater than 1&amp;#34;&lt;/span>) Long id);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Of course, in many other bean validation scenarios, annotations are placed on implementation classes rather than interfaces. At least one advantage of placing an annotation on an interface is that the Dubbo client can share information about the interface. The input validation can be done locally even without RPC.&lt;/p>
&lt;p>Then turn on the validation in the XML configuration in the same way as Dubbo:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:service&lt;/span> interface=&lt;span style="color:#2aa198">xxx.UserService&amp;#34;&lt;/span> ref=&lt;span style="color:#2aa198">&amp;#34;userService&amp;#34;&lt;/span> protocol=&lt;span style="color:#2aa198">&amp;#34;rest&amp;#34;&lt;/span> validation=&lt;span style="color:#2aa198">&amp;#34;true&amp;#34;&lt;/span>&lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>In many other RPC protocols of Dubbo, if the input validation error occurs, the &lt;code>RpcException&lt;/code> is directly thrown to the client, but in the rest, since the client is often non-Dubbo or even non-Java system, it is inconvenient to directly throw a Java exception. Therefore, at present we will return the validation error in XML format:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;violationReport&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;constraintViolations&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;path&amp;gt;&lt;/span>getUserArgument0&lt;span style="color:#268bd2">&amp;lt;/path&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;message&amp;gt;&lt;/span>User ID must be greater than 1&lt;span style="color:#268bd2">&amp;lt;/message&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;value&amp;gt;&lt;/span>0&lt;span style="color:#268bd2">&amp;lt;/value&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;/constraintViolations&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;/violationReport&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The return values of other data formats will also be supported later. As for how to internationalize the verification error message, refer directly to the relevant documentation of the bean validation.&lt;/p>
&lt;p>If you think that the default validation error return format does not meet your requirements, you can add custom ExceptionMapper to custom error return format freely as described in the previous section. It should be noted that this ExceptionMapper must use the generic declaration to capture the RpcException of Dubbo in order to successfully override the default exception handling strategy of Dubbo rest. In order to simplify the operation, the easiest way to do this is to directly inherit the RpcExceptionMapper of Dubbo rest and override the method that handles the validation exception:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">MyValidationExceptionMapper&lt;/span> &lt;span style="color:#268bd2">extends&lt;/span> RpcExceptionMapper {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">protected&lt;/span> Response &lt;span style="color:#268bd2">handleConstraintViolationException&lt;/span>(ConstraintViolationException cve) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ViolationReport report &lt;span style="color:#719e07">=&lt;/span> &lt;span style="color:#719e07">new&lt;/span> ViolationReport();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">for&lt;/span> (ConstraintViolation cv : cve.getConstraintViolations()) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> report.addConstraintViolation(&lt;span style="color:#719e07">new&lt;/span> RestConstraintViolation(
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> cv.getPropertyPath().toString(),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> cv.getMessage(),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> cv.getInvalidValue() &lt;span style="color:#719e07">==&lt;/span> &lt;span style="color:#cb4b16">null&lt;/span> &lt;span style="color:#719e07">?&lt;/span> &lt;span style="color:#2aa198">&amp;#34;null&amp;#34;&lt;/span> : cv.getInvalidValue().toString()));
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// Use json output instead of xml output&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">return&lt;/span> Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(report).type(ContentType.APPLICATION_JSON_UTF_8).build();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Then add this ExceptionMapper to the XML configuration:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:protocol&lt;/span> name=&lt;span style="color:#2aa198">&amp;#34;rest&amp;#34;&lt;/span> port=&lt;span style="color:#2aa198">&amp;#34;8888&amp;#34;&lt;/span> extension=&lt;span style="color:#2aa198">&amp;#34;xxx.MyValidationExceptionMapper&amp;#34;&lt;/span>&lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="whether-to-transparently-publish-rest-service">Whether to transparently publish REST service&lt;/h3>
&lt;p>Dubbo RESTful Remoting differs from some other RPCs in Dubbo in that you need to add JAX-RS annotations (and JAXB, Jackson&amp;rsquo;s annotation) to your service code. If you think these annotations &amp;ldquo;pollute&amp;rdquo; your service code to a certain extent,you can consider writing additional Facade and DTO classes, adding annotations to that, and Facade forwards the calls to the real service implementation class. Of course, adding annotations directly to the service code basically has no negative effects, and this is itself a standard usage in Java EE. In addition, JAX-RS and JAXB annotations belong to the Java standard. Compared with spring, Dubbo, etc., which we often use, annotations have no problem with vendor lock-in, so there is usually no need to introduce additional objects.&lt;/p>
&lt;p>In addition,when you want to use the @Context annotation mentioned above, injecting HttpServletRequest through method parameters (such as &lt;code>public User getUser(@PathParam(&amp;quot;id&amp;quot;) Long id, @Context HttpServletRequest request)&lt;/code>), the method signature of service is changed and HttpServletRequest is a REST-specific parameter, you should introduce additional Facade classes if your service supports multiple RPC mechanisms.&lt;/p>
&lt;p>Of course, your service code may already act as a Facade and DTO before adding RESTful Remoting (as to why some scenarios require these roles, and if you are interested, you can refer to [Micro-SOA: Service Design Principles and Practices] Http://www.infoq.com/cn/articles/micro-soa-1). In this case, after adding REST, if you add additional REST-related Facade and DTO, it is equivalent to wrapping the original code again, which forms the following call chain:&lt;/p>
&lt;p>&lt;code>RestFacade/RestDTO -&amp;gt; Facade/DTO -&amp;gt; Service&lt;/code>&lt;/p>
&lt;p>This kind of system is cumbersome, and the workload of data conversion is not small, so it should be avoided if possible.&lt;/p>
&lt;h3 id="get-headers-in-dubbo-rest-provider">Get Headers In Dubbo Rest Provider&lt;/h3>
&lt;p>Dubbo take out and split headers by RpcContextFilter and put them into attachments of RpcContext, so provider can get headers from RpcContext attachments like:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-fallback" data-lang="fallback">&lt;span style="display:flex;">&lt;span> String header-value1 = RpcContext.getContext().getAttachment(header-key1)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> String header-value2 = RpcContext.getContext().getAttachment(header-key2)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="consumer-of-restful-remoting">Consumer of RESTful Remoting&lt;/h3>
&lt;p>Here we use three scenarios:&lt;/p>
&lt;ol>
&lt;li>The non-Dubbo consumer calls Dubbo REST service (non-Dubbo &amp;ndash;&amp;gt; Dubbo)&lt;/li>
&lt;li>The Dubbo consumer calls Dubbo REST service (Dubbo &amp;ndash;&amp;gt; Dubbo)&lt;/li>
&lt;li>The consumer of Dubbo calls the non-Dubbo REST service (Dubbo &amp;ndash;&amp;gt; non-Dubbo)&lt;/li>
&lt;/ol>
&lt;h3 id="scenario-1-non-dubbo-consumer-calls-dubbo-rest-service">Scenario 1: Non-Dubbo consumer calls Dubbo REST Service&lt;/h3>
&lt;p>The client of this scenario has nothing to do with Dubbo itself, and it can be directly selected in the appropriate language and framework.&lt;/p>
&lt;p>If it is still a Java client (but not using Dubbo), consider using the standard JAX-RS Client API or a specific REST-implemented Client API to invoke the REST service. The following is the registerUser() that uses the JAX-RS Client API to access the above UserService:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>User user &lt;span style="color:#719e07">=&lt;/span> &lt;span style="color:#719e07">new&lt;/span> User();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>user.setName(&lt;span style="color:#2aa198">&amp;#34;Larry&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Client client &lt;span style="color:#719e07">=&lt;/span> ClientBuilder.newClient();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>WebTarget target &lt;span style="color:#719e07">=&lt;/span> client.target(&lt;span style="color:#2aa198">&amp;#34;http://localhost:8080/services/users/register.json&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Response response &lt;span style="color:#719e07">=&lt;/span> target.request().post(Entity.entity(user, MediaType.APPLICATION_JSON_TYPE));
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">try&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">if&lt;/span> (response.getStatus() &lt;span style="color:#719e07">!=&lt;/span> 200) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">throw&lt;/span> &lt;span style="color:#719e07">new&lt;/span> RuntimeException(&lt;span style="color:#2aa198">&amp;#34;Failed with HTTP error code : &amp;#34;&lt;/span> &lt;span style="color:#719e07">+&lt;/span> response.getStatus());
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> System.out.println(&lt;span style="color:#2aa198">&amp;#34;The generated id is &amp;#34;&lt;/span> &lt;span style="color:#719e07">+&lt;/span> response.readEntity(RegistrationResult.class).getId());
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>} &lt;span style="color:#719e07">finally&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> response.close();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> client.close(); &lt;span style="color:#586e75">//Do not close the client every time in real development, such as HTTP long connection is held by the client&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The User and RegistrationResult classes in the code snippet above are written by the consumer itself, and the JAX-RS Client API automatically serializes/deserializes them.&lt;/p>
&lt;p>Of course, in Java, you can also use the familiar technologies such as HttpClient, FastJson, XStream, etc. to implement the REST client, which will not be detailed here.&lt;/p>
&lt;h3 id="scenario-2-dubbo-consumer-calls-dubbo-restful-remoting">Scenario 2: Dubbo consumer calls Dubbo RESTful Remoting&lt;/h3>
&lt;p>In this scenario, same as other Dubbo remote calling methods, the Java service interface is shared directly between the service provider and the service consumer, and the Spring XML configuration is added (of course, the Spring/Dubbo annotation configuration can also be used),the remote REST service can be called transparently:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:reference&lt;/span> id=&lt;span style="color:#2aa198">&amp;#34;userService&amp;#34;&lt;/span> interface=&lt;span style="color:#2aa198">&amp;#34;xxx.UserService&amp;#34;&lt;/span>&lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>As mentioned earlier, in this scenario, JAX-RS annotations must be added to the service interface, so that the corresponding REST configuration information can be shared on the consumer side of Dubbo and remotely called accordingly:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">@Path&lt;/span>(&lt;span style="color:#2aa198">&amp;#34;users&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">interface&lt;/span> &lt;span style="color:#268bd2">UserService&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">@GET&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">@Path&lt;/span>(&lt;span style="color:#2aa198">&amp;#34;{id : \\d+}&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">@Produces&lt;/span>({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> User &lt;span style="color:#268bd2">getUser&lt;/span>(&lt;span style="color:#268bd2">@PathParam&lt;/span>(&lt;span style="color:#2aa198">&amp;#34;id&amp;#34;&lt;/span>) Long id);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>If a variety of data formats are configured in the annotation of the service interface, since both ends are Dubbo systems, a lot of details of REST are blocked, so there is no possibility to select a data format using the aforementioned URL suffix. Currently in this case, the top ranked data format will be used directly.&lt;/p>
&lt;p>Therefore, we recommend that you put the most appropriate data format in front of defining an annotation. For example, we put JSON in front of XML because JSON&amp;rsquo;s transmission performance is better than XML.&lt;/p>
&lt;h3 id="scenario-3-the-consumer-of-dubbo-calls-a-non-dubbo-restful-remoting">Scenario 3: The consumer of Dubbo calls a non-Dubbo RESTful Remoting&lt;/h3>
&lt;p>In this scenario, the REST service can be called directly using the Java method described in Scenario 1. But in fact, you can also use the way described in Scenario 2, that is, calling the REST service more transparently, even if this service is not provided by Dubbo.&lt;/p>
&lt;p>If the scenario 2 is used, since the REST service is not provided by Dubbo, there is generally no shared Java service interface mentioned above, so we need to write the Java interface and the corresponding parameter class according to the external REST service. Add JAX-RS, JAXB, Jackson and other annotations, Dubbo&amp;rsquo;s REST underlying implementation will automatically generate request messages, automatically parse response messages, etc., so as to transparently make remote calls. Or this way can also be understood as, we try to use JAX-RS to copy the implementation of the external REST service provider, and then put the written service interface to the client to use directly, Dubbo REST underlying implementation can call other REST services as it calls Dubbo&amp;rsquo;s REST service .&lt;/p>
&lt;p>For example, we want to call the following external service.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-fallback" data-lang="fallback">&lt;span style="display:flex;">&lt;span>http://api.foo.com/services/users/1001
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>http://api.foo.com/services/users/1002
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Get user data of different IDs, the return format is JSON&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#2aa198">&amp;#34;id&amp;#34;&lt;/span>: 1001,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#2aa198">&amp;#34;name&amp;#34;&lt;/span>: &lt;span style="color:#2aa198">&amp;#34;Larry&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>We can write service interfaces and parameter classes based on this information:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">@Path&lt;/span>(&lt;span style="color:#2aa198">&amp;#34;users&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">interface&lt;/span> &lt;span style="color:#268bd2">UserService&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">@GET&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">@Path&lt;/span>(&lt;span style="color:#2aa198">&amp;#34;{id : \\d+}&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">@Produces&lt;/span>({MediaType.APPLICATION_JSON})
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> User &lt;span style="color:#268bd2">getUser&lt;/span>(&lt;span style="color:#268bd2">@PathParam&lt;/span>(&lt;span style="color:#2aa198">&amp;#34;id&amp;#34;&lt;/span>) Long id);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">User&lt;/span> &lt;span style="color:#268bd2">implements&lt;/span> Serializable {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">private&lt;/span> Long id;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">private&lt;/span> String name;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// …&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>For the configuration in Spring, because the REST service is not provided by Dubbo, you can not use the Dubbo registry to directly configure the url address of the external REST service (such as multiple addresses separated by commas):&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:reference&lt;/span> id=&lt;span style="color:#2aa198">&amp;#34;userService&amp;#34;&lt;/span> interface=&lt;span style="color:#2aa198">&amp;#34;xxx.UserService&amp;#34;&lt;/span> url=&lt;span style="color:#2aa198">&amp;#34;rest://api.foo.com/services/&amp;#34;&lt;/span>&lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;blockquote>
&lt;p>Note: The protocol here must use rest:// instead of http://. If the external REST service has a context path, it must also be added to the url (unless you have a context path in the @Path annotation for each service interface), such as /services/ above. At the same time, the services here must be followed by /, in order to make Dubbo work properly.&lt;/p>
&lt;p>In addition, you can still configure the maximum number of connections and timeouts that the client can start:&lt;/p>
&lt;/blockquote>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:reference&lt;/span> id=&lt;span style="color:#2aa198">&amp;#34;userService&amp;#34;&lt;/span> interface=&lt;span style="color:#2aa198">&amp;#34;xxx.UserService&amp;#34;&lt;/span> url=&lt;span style="color:#2aa198">&amp;#34;rest://api.foo.com/services/&amp;#34;&lt;/span> timeout=&lt;span style="color:#2aa198">&amp;#34;2000&amp;#34;&lt;/span> connections=&lt;span style="color:#2aa198">&amp;#34;10&amp;#34;&lt;/span>&lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="custom-header-by-dubbo-consumer-while-calls-rest-service">Custom Header By Dubbo Consumer while Calls REST Service&lt;/h3>
&lt;p>When Dubbo calls rest, it uses the method of converting the attachments of RpcContext to header.&lt;/p>
&lt;p>Therefore, you can set headers in the following ways:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-fallback" data-lang="fallback">&lt;span style="display:flex;">&lt;span> RpcContext.getContext().setAttachment(&amp;#34;header-key1&amp;#34;, &amp;#34;header-value1&amp;#34;);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> RpcContext.getContext().setAttachment(&amp;#34;header-key2&amp;#34;, &amp;#34;header-value2&amp;#34;);
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Then the headers will be looks like following:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-fallback" data-lang="fallback">&lt;span style="display:flex;">&lt;span> header-key1 = header-value1
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> header-key2 = header-value2
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="jax-rs-restrictions-in-dubbo">JAX-RS restrictions in Dubbo&lt;/h3>
&lt;p>The REST development in Dubbo is fully compatible with standard JAX-RS, but the features it supports are currently a subset of full JAX-RS, in part because it is limited to the specific architecture of Dubbo and Spring. The limitations of JAX-RS used in Dubbo include but are not limited to:&lt;/p>
&lt;ol>
&lt;li>Service implementation can only be singleton, and it can not support per-request scope and per-lookup scope&lt;/li>
&lt;li>It is not supported to inject into ServletConfig, ServletContext, HttpServletRequest, HttpServletResponse, etc. with the @Context annotation for the instance field of the service, but it can support the injection of service method parameters. However, for certain REST server implementations (see the previous section), injection of service method parameters is not supported.&lt;/li>
&lt;/ol>
&lt;h2 id="rest-faq">REST FAQ&lt;/h2>
&lt;hr>
&lt;h3 id="can-dubbo-rest-services-be-integrated-with-dubbo-registry-and-monitor">Can Dubbo REST services be integrated with Dubbo Registry and Monitor?&lt;/h3>
&lt;p>Yes, and it will integrate automatically. That is, all the REST services you develop in Dubbo are automatically registered to the Registry and Monitor, by which you can managed your services.
However, many of the service governance operations in the Registry can only be fully functional when the REST consumer is based on Dubbo. If the consumer side is non-Dubbo, it is naturally not managed by the Registry, so that many of the operations will not work for the consumer.&lt;/p>
&lt;h3 id="how-to-implement-load-balancing-and-failover-in-dubbo-rest">How to implement load balancing and failover in Dubbo REST?&lt;/h3>
&lt;p>If the consumer side of Dubbo REST is based on Dubbo, then Dubbo REST is basically the same as other Dubbo remote call protocols: Dubbo framework transparently performs load balancing, failover, etc. on the consumer side.
If the consumer side of Dubbo REST is non-Dubbo or even non-Java, it is better to configure the soft load balancing mechanism on the service provider. Currently, you can consider LVS, HAProxy, Nginx, and so on to achieve load balancing for HTTP requests.&lt;/p>
&lt;h3 id="can-overloaded-method-in-jax-rs-maps-to-the-same-url-address">Can overloaded method in JAX-RS maps to the same URL address?&lt;/h3>
&lt;p>&lt;a href="http://stackoverflow.com/questions/17196766/can-resteasy-choose-method-based-on-query-params">http://stackoverflow.com/questions/17196766/can-resteasy-choose-method-based-on-query-params&lt;/a>&lt;/p>
&lt;h3 id="can-a-post-method-in-jax-rs-receive-multiple-parameters">Can a POST method in JAX-RS receive multiple parameters?&lt;/h3>
&lt;p>&lt;a href="http://stackoverflow.com/questions/5553218/jax-rs-post-multiple-objects">http://stackoverflow.com/questions/5553218/jax-rs-post-multiple-objects&lt;/a>&lt;/p>
&lt;h2 id="the-shortcomings-of-dubbos-current-system-related-to-rest">The shortcomings of Dubbo&amp;rsquo;s current system (related to REST)&lt;/h2>
&lt;hr>
&lt;p>I think there are obviously a lot of deficiencies in Dubbo&amp;rsquo;s current system. Here are a few REST-related issues that affect users (not including internal implementation issues) for reference and comments, which can help prepare for the refactoring later.&lt;/p>
&lt;h3 id="invasiveness-of-rpccontext">Invasiveness of RpcContext&lt;/h3>
&lt;p>We have already mentioned the intrusiveness of RpcContext(See above). Because it uses a singleton to access context information, which is completely inconsistent with the general style of spring applications as well as not conducive to application extension and unit testing. In the future, we may inject an interface with dependency injection, and then use it to access the context information in ThreadLocal.&lt;/p>
&lt;h3 id="limitations-of-protocol-configuration">limitations of Protocol configuration&lt;/h3>
&lt;p>Dubbo supports multiple remote call methods, but all call methods are configured with &lt;a href="Dubbo:protocol/">Dubbo:protocol/&lt;/a>, for example:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;Dubbo:protocol&lt;/span> name=&lt;span style="color:#2aa198">&amp;#34;Dubbo&amp;#34;&lt;/span> port=&lt;span style="color:#2aa198">&amp;#34;9090&amp;#34;&lt;/span> server=&lt;span style="color:#2aa198">&amp;#34;netty&amp;#34;&lt;/span> client=&lt;span style="color:#2aa198">&amp;#34;netty&amp;#34;&lt;/span> codec=&lt;span style="color:#2aa198">&amp;#34;Dubbo&amp;#34;&lt;/span> serialization=&lt;span style="color:#2aa198">&amp;#34;hessian2&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> charset=&lt;span style="color:#2aa198">&amp;#34;UTF-8&amp;#34;&lt;/span> threadpool=&lt;span style="color:#2aa198">&amp;#34;fixed&amp;#34;&lt;/span> threads=&lt;span style="color:#2aa198">&amp;#34;100&amp;#34;&lt;/span> queues=&lt;span style="color:#2aa198">&amp;#34;0&amp;#34;&lt;/span> iothreads=&lt;span style="color:#2aa198">&amp;#34;9&amp;#34;&lt;/span> buffer=&lt;span style="color:#2aa198">&amp;#34;8192&amp;#34;&lt;/span> accepts=&lt;span style="color:#2aa198">&amp;#34;1000&amp;#34;&lt;/span> payload=&lt;span style="color:#2aa198">&amp;#34;8388608&amp;#34;&lt;/span>&lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Dubbo supports multiple remote call methods, but all call methods are configured with &lt;a href="Dubbo:protocol/">Dubbo:protocol/&lt;/a>, for example:
In fact, many of the above properties are uniquely held by the Dubbo RPC remote call method and many other remote call methods in Dubbo do not support server, client, codec, iothreads, accepts, payload, etc. (of course, some are not supported because of limited conditions, some have no need to be supported at all). This adds a lot of confusions to users when they use Dubbo, and they actually do not know that some attributes (such as performance tuning) will not work after adding them.&lt;/p>
&lt;p>On the other hand, various remote call methods often have a large number of unique configuration requirements, especially as we gradually add much richer and more advanced functions to each kind of remote call method, which cause the expands in &lt;protocol/> attributes inevitably (for example, we have added keepalive and extension two attributes in REST at the moment) and then lead to bloated &lt;protocol/> and user confusion.&lt;/p>
&lt;p>Of course, there is a way to expand &lt;protocol/> in Dubbo by using &lt;a href="Dubbo:parameter/">Dubbo:parameter/&lt;/a>, but this method is obviously very limited, the usage is complicated and the schema verification is lacking.
So that the best method is to set your own protocol elements for each remote call, such as &lt;protocol-Dubbo/>, &lt;protocol-rest/>, etc. Each element specifies its own attributes using XML Schema. (Of course, it is best to use common attributes between a variety of remote call methods)
In this way, a freer way can be used when doing the extension configuration mentioned above, so that it can be much clearer and more extensible (the following is just an example, of course there may be a better way):&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;Dubbo:protocol-rest&lt;/span> port=&lt;span style="color:#2aa198">&amp;#34;8080&amp;#34;&lt;/span>&lt;span style="color:#268bd2">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;Dubbo:extension&amp;gt;&lt;/span>someInterceptor&lt;span style="color:#268bd2">&amp;lt;/Dubbo:extension&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;Dubbo:extension&amp;gt;&lt;/span>someFilter&lt;span style="color:#268bd2">&amp;lt;/Dubbo:extension&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;Dubbo:extension&amp;gt;&lt;/span>someDynamicFeature&lt;span style="color:#268bd2">&amp;lt;/Dubbo:extension&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;Dubbo:extension&amp;gt;&lt;/span>someEntityProvider&lt;span style="color:#268bd2">&amp;lt;/Dubbo:extension&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;/Dubbo:protocol-rest&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="xml-naming-does-not-conform-to-the-spring-specification">XML naming does not conform to the spring specification&lt;/h3>
&lt;p>A lot of naming in XML configuration of Dubbo dose not conform to the spring specification, such as:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;Dubbo:protocol&lt;/span> name=&lt;span style="color:#2aa198">&amp;#34;Dubbo&amp;#34;&lt;/span> port=&lt;span style="color:#2aa198">&amp;#34;9090&amp;#34;&lt;/span> server=&lt;span style="color:#2aa198">&amp;#34;netty&amp;#34;&lt;/span> client=&lt;span style="color:#2aa198">&amp;#34;netty&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>codec=&lt;span style="color:#2aa198">&amp;#34;Dubbo&amp;#34;&lt;/span> serialization=&lt;span style="color:#2aa198">&amp;#34;hessian2&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> charset=&lt;span style="color:#2aa198">&amp;#34;UTF-8&amp;#34;&lt;/span> threadpool=&lt;span style="color:#2aa198">&amp;#34;fixed&amp;#34;&lt;/span> threads=&lt;span style="color:#2aa198">&amp;#34;100&amp;#34;&lt;/span> queues=&lt;span style="color:#2aa198">&amp;#34;0&amp;#34;&lt;/span> iothreads=&lt;span style="color:#2aa198">&amp;#34;9&amp;#34;&lt;/span> buffer=&lt;span style="color:#2aa198">&amp;#34;8192&amp;#34;&lt;/span> accepts=&lt;span style="color:#2aa198">&amp;#34;1000&amp;#34;&lt;/span> payload=&lt;span style="color:#2aa198">&amp;#34;8388608&amp;#34;&lt;/span>&lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The above threadpool should be changed to thread-pool, iothreads should be changed to io-threads, and words should be separated by &amp;ldquo;-&amp;rdquo;. While this may seem like a minor issue, it also involves readability, especially scalability, because sometimes we will inevitably use more words to describe XML elements and attributes.&lt;/p>
&lt;p>In fact, Dubbo itself also recommended to follow the naming convention of spring to XML.&lt;/p>
&lt;h2 id="best-practices-of-rest">Best practices of REST&lt;/h2>
&lt;hr>
&lt;p>TODO&lt;/p>
&lt;h2 id="performance-benchmark">Performance benchmark&lt;/h2>
&lt;hr>
&lt;h3 id="test-environment">Test Environment&lt;/h3>
&lt;p>Roughly as follows:&lt;/p>
&lt;ul>
&lt;li>4-core Intel(R) Xeon(R) CPU E5-2603 0 @ 1.80GHz&lt;/li>
&lt;li>8G memory&lt;/li>
&lt;li>The network between servers passes through a 100 Mbps switch&lt;/li>
&lt;li>CentOS 5&lt;/li>
&lt;li>JDK 7&lt;/li>
&lt;li>Tomcat 7&lt;/li>
&lt;li>JVM parameter -server -Xms1g -Xmx1g -XX:PermSize=64M -XX:+UseConcMarkSweepGC&lt;/li>
&lt;/ul>
&lt;h3 id="test-script">Test Script&lt;/h3>
&lt;p>Similar to Dubbo&amp;rsquo;s own benchmarks:
10 concurrent clients send requests continuously:
• Pass in nested complex objects (single data is small), do nothing and return
• Pass in a 50K string, do nothing and return (TODO: the result is not listed yet)
Excute a five-minute performance test. (Reference to Dubbo&amp;rsquo;s own test considerations: &amp;ldquo;Mainly consider the serialization and performance of network IO, so that the server side does not have any business logic. Take 10 to run simultaneously because of the consideration that the bottleneck can be hit first when the high CPU usage rate is reached by HTTP protocol under the high concurrency situation.&amp;rdquo;)&lt;/p>
&lt;h3 id="test-result">Test Result&lt;/h3>
&lt;p>The following results are mainly from the comparison between to the two remote call methods, REST and Dubbo RPC which are configured differently, for example:&lt;/p>
&lt;ul>
&lt;li>“REST: Jetty + XML + GZIP” means: Test REST, use jetty server and XML data format, and enable GZIP compression.&lt;/li>
&lt;li>“Dubbo: hessian2” means: test Dubbo RPC and use hessian2 serialization.&lt;/li>
&lt;/ul>
&lt;p>The results for complex objects are as follows (the smaller Response Time and the larger TPS, the better results):&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Remote Call Mode&lt;/th>
&lt;th>Average Response Time&lt;/th>
&lt;th>Average TPS(Num of transactions per second)&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>REST: Jetty + JSON&lt;/td>
&lt;td>7.806&lt;/td>
&lt;td>1280&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>REST: Jetty + JSON + GZIP&lt;/td>
&lt;td>TODO&lt;/td>
&lt;td>TODO&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>REST: Jetty + XML&lt;/td>
&lt;td>TODO&lt;/td>
&lt;td>TODO&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>REST: Jetty + XML + GZIP&lt;/td>
&lt;td>TODO&lt;/td>
&lt;td>TODO&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>REST: Tomcat + JSON&lt;/td>
&lt;td>2.082&lt;/td>
&lt;td>4796&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>REST: Netty + JSON&lt;/td>
&lt;td>2.182&lt;/td>
&lt;td>4576&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Dubbo: FST&lt;/td>
&lt;td>1.211&lt;/td>
&lt;td>8244&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Dubbo: kyro&lt;/td>
&lt;td>1.182&lt;/td>
&lt;td>8444&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Dubbo: Dubbo serialization&lt;/td>
&lt;td>1.43&lt;/td>
&lt;td>6982&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Dubbo: hessian2&lt;/td>
&lt;td>1.49&lt;/td>
&lt;td>6701&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Dubbo: fastjson&lt;/td>
&lt;td>1.572&lt;/td>
&lt;td>6352&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>Just a brief summary of the current results:&lt;/p>
&lt;ul>
&lt;li>Dubbo RPC (especially when based on efficient java serialization methods such as kryo and fst) has a significant advantage response time and throughput over REST. Dubbo RPC is preferred in the intranet Dubbo systems.&lt;/li>
&lt;li>When choosinf REST implementation, tomcat7 and netty are optimal (of course, the current versions of jetty and netty are lower) currently only considering performance. Tjws and sun http server performed extremely poorly in performance tests, with an average response time of more than 200ms and an average tps of only about 50 (to avoid affecting the picture effect, the results are not listed above).&lt;/li>
&lt;li>Performance of JSON data format is better than XML in REST (data is not listed above).&lt;/li>
&lt;li>Enabling GZIP in REST has little to do with complex objects with small data volume in the intranet, but performance has declined (data is not listed above).&lt;/li>
&lt;/ul>
&lt;h2 id="performance-optimization-recommendations">Performance Optimization Recommendations&lt;/h2>
&lt;p>If you deploy Dubbo REST to an external Tomcat and configure server=&amp;ldquo;servlet&amp;rdquo;, that is, enable external tomcat as the underlying implementation of rest server, it is best to add the following configuration to tomcat:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;Connector&lt;/span> port=&lt;span style="color:#2aa198">&amp;#34;8080&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>protocol=&lt;span style="color:#2aa198">&amp;#34;org.apache.coyote.http11.Http11NioProtocol&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> connectionTimeout=&lt;span style="color:#2aa198">&amp;#34;20000&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> redirectPort=&lt;span style="color:#2aa198">&amp;#34;8443&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> minSpareThreads=&lt;span style="color:#2aa198">&amp;#34;20&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> enableLookups=&lt;span style="color:#2aa198">&amp;#34;false&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> maxThreads=&lt;span style="color:#2aa198">&amp;#34;100&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> maxKeepAliveRequests=&lt;span style="color:#2aa198">&amp;#34;-1&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> keepAliveTimeout=&lt;span style="color:#2aa198">&amp;#34;60000&amp;#34;&lt;/span>&lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Especially the configuration maxKeepAliveRequests=&amp;quot;-1&amp;quot; ,which is mainly to ensure that tomcat always enables http long connection, in order to improve the performance of REST call. Note, however, that if the REST consumer side is not continuously call REST services, it is not always best to enable long connections all time. In addition, the way to always enable long connections is generally not suitable for ordinary webapps, but more suitable for such rpc-like scenarios. So that in order to get high performance, Dubbo REST applications and ordinary web applications are best not to be mixed deployment, but should use a separate instance in tomcat.&lt;/p>
&lt;h2 id="extended-discussion">##Extended discussion&lt;/h2>
&lt;h3 id="comparison-among-rest-thrift-protobuf-and-so-on">Comparison among Rest, Thrift, Protobuf and so on&lt;/h3>
&lt;p>TODO&lt;/p>
&lt;h3 id="comparison-between-rest-and-traditional-webservers">Comparison between REST and traditional Webservers&lt;/h3>
&lt;p>TODO&lt;/p>
&lt;h3 id="comparison-of-jax-rs-between-spring-mvc">Comparison of JAX-RS Between Spring MVC&lt;/h3>
&lt;p>A preliminary view from &lt;a href="http://www.infoq.com/cn/news/2014/10/Dubbox-open-source?utm_source=infoq&amp;amp;utm_medium=popular_links_homepage#theCommentsSection">http://www.infoq.com/cn/news/2014/10/Dubbox-open-source?utm_source=infoq&amp;amp;utm_medium=popular_links_homepage#theCommentsSection&lt;/a>&lt;/p>
&lt;blockquote>
&lt;p>Thank you, in fact, for jax-rs and Spring MVC, I do not have a deep look at the rest support of Spring MVC. I would like to give you some preliminary ideas. Please correct me:&lt;/p>
&lt;/blockquote>
&lt;blockquote>
&lt;p>Spring MVC also supports configuration using annotation, which actually looks very similar to jax-rs.&lt;/p>
&lt;/blockquote>
&lt;blockquote>
&lt;p>Personally, I think Spring MVC is better suited to restful services of web applications, such as being invoked by AJAX, or possibly outputting HTML or something like page jump processes in applications. Spring MVC can handle both normal web page requests and rest requests at the same time. But in general, the restful service is implemented in the presentation layer or the web layer.&lt;/p>
&lt;/blockquote>
&lt;blockquote>
&lt;p>But Jax-rs is more suitable for pure service-oriented applications, that is, the middle-tier services in traditional Java EE, for example, it can publish traditional EJB as restful services. In a Spring application, the bean that acts as a service in the Spring is directly published as a restful service. In general, the restful service is at the business layer, application layer, or facade layer. And MVC hierarchies and concepts are often of little value in such (back-end) applications.&lt;/p>
&lt;/blockquote>
&lt;blockquote>
&lt;p>Of course, some implementations of jax-rs, such as jersey, also try to include MVC to better accommodate the web applications described above, but not as well as Spring MVC.&lt;/p>
&lt;/blockquote>
&lt;blockquote>
&lt;p>In Dubbo applications, I think a lot of people prefer to publish a local Spring service bean (or manager) as a remote service directly and transparently, so that it is more straightforward to use JAX-RS here, and there is no need to introduce the MVC concept. Of course, we do not discuss whether transparent publishing of remote services is a best practice or whether to add facade things here first.&lt;/p>
&lt;/blockquote>
&lt;blockquote>
&lt;p>Of course, I know that many people use Spring MVC restful to call Dubbo (spring) service to publish restful services under the situation that Dubbo does not support rest now. It’s a good method also in my opinion, but if you do not modify Spring MVC and integrate it deeply with Dubbo, restful services cannot enjoy many advanced services such as registering to the Dubbo Registry, monitoring the number of calls, TPS, response time through the Dubbo Monitor, controlling the size of the thread pool and the maximum number of connections through the unified configuration of Dubbo, and controlling the service flow, authority and frequency through Dubbo unified mode like other remote call protocol such as webservices, Dubbo rpc, hessian and so on in Dubbo system. In addition, Spring MVC only works in server side and Spring restTemplate are usually used on consumer side. If restTemplate is not integrated with Dubbo, the service can be downgraded by Dubbo client automatically or manually. If the server and consumer are all Dubbo system, you cannot use unified routing and other functions in Dubbo if the Spring rest is not deeply integrated into Dubbo through interaction of Spring and rest.&lt;/p>
&lt;/blockquote>
&lt;blockquote>
&lt;p>Of course, I personally think that these things are not necessarily to be one or the other. I heard that Rod Johnson, the founder of spring usually says ‘the customer is always right,’ In fact, it is better to support both ways at the same time rather than discuss which way is better, so that originally I wrote in the document that we plan to support Spring rest annotation, but the feasibility is unknown.&lt;/p>
&lt;/blockquote>
&lt;h2 id="future">##Future&lt;/h2>
&lt;p>Functions may be supported later:&lt;/p>
&lt;ul>
&lt;li>Rest annotation for Spring MVC&lt;/li>
&lt;li>Safety System&lt;/li>
&lt;li>OAuth&lt;/li>
&lt;li>Asynchronous calls&lt;/li>
&lt;li>Gzip&lt;/li>
&lt;li>Payload maxsize&lt;/li>
&lt;/ul></description></item><item><title>Docs: Simple Monitor</title><link>https://dubbo.apache.org/en/docs/v2.7/user/simple-monitor/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/en/docs/v2.7/user/simple-monitor/</guid><description>
&lt;div class="alert alert-warning" role="alert">
&lt;h4 class="alert-heading">Warning&lt;/h4>
&lt;p>Monitor service is a standard Dubbo service,can be exported to the registry,also can be connected straightly.&lt;/p>
&lt;p>&lt;a href="https://dubbo.apache.org/en/docs/v2.7/admin/install/">Install the simple registry&lt;/a>&lt;/p>
&lt;/div>
&lt;ol start="0">
&lt;li>
&lt;p>export a simple monitor service to the registry: (If you use the installer, you don&amp;rsquo;t need to write this configuration yourself. if you implement the monitor service yourself,need it)&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;beans&lt;/span> xmlns=&lt;span style="color:#2aa198">&amp;#34;http://www.springframework.org/schema/beans&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>xmlns:xsi=&lt;span style="color:#2aa198">&amp;#34;http://www.w3.org/2001/XMLSchema-instance&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>xmlns:dubbo=&lt;span style="color:#2aa198">&amp;#34;http://dubbo.apache.org/schema/dubbo&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>xsi:schemaLocation=&lt;span style="color:#2aa198">&amp;#34;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd&amp;#34;&lt;/span>&lt;span style="color:#268bd2">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&amp;lt;!-- configuration of current application --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:application&lt;/span> name=&lt;span style="color:#2aa198">&amp;#34;simple-monitor&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&amp;lt;!-- connection address of the registry --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:registry&lt;/span> address=&lt;span style="color:#2aa198">&amp;#34;127.0.0.1:9090&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&amp;lt;!-- protool configuration of exposed services --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:protocol&lt;/span> port=&lt;span style="color:#2aa198">&amp;#34;7070&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&amp;lt;!-- configuration of certain exposed service --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:service&lt;/span> interface=&lt;span style="color:#2aa198">&amp;#34;org.apache.dubbo.monitor.MonitorService&amp;#34;&lt;/span> ref=&lt;span style="color:#2aa198">&amp;#34;monitorService&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;bean&lt;/span> id=&lt;span style="color:#2aa198">&amp;#34;monitorService&amp;#34;&lt;/span> class=&lt;span style="color:#2aa198">&amp;#34;org.apache.dubbo.monitor.simple.SimpleMonitorService&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;/beans&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;li>
&lt;p>Discovery the monitor service int the registry:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:monitor&lt;/span> protocol=&lt;span style="color:#2aa198">&amp;#34;registry&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>or&lt;/p>
&lt;blockquote>
&lt;p>dubbo.properties&lt;/p>
&lt;/blockquote>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>dubbo.monitor.protocol=registry
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;li>
&lt;p>Export a simple monitor service ,but don&amp;rsquo;t register it to th registry: (If you use the installer, you don&amp;rsquo;t need to write this configuration yourself. if you implement the monitor service yourself,need it)&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;beans&lt;/span> xmlns=&lt;span style="color:#2aa198">&amp;#34;http://www.springframework.org/schema/beans&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>xmlns:xsi=&lt;span style="color:#2aa198">&amp;#34;http://www.w3.org/2001/XMLSchema-instance&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>xmlns:dubbo=&lt;span style="color:#2aa198">&amp;#34;http://dubbo.apache.org/schema/dubbo&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>xsi:schemaLocation=&lt;span style="color:#2aa198">&amp;#34;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd&amp;#34;&lt;/span>&lt;span style="color:#268bd2">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&amp;lt;!-- configuration of current application --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:application&lt;/span> name=&lt;span style="color:#2aa198">&amp;#34;simple-monitor&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&amp;lt;!-- protool configuration of exposed service --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:protocol&lt;/span> port=&lt;span style="color:#2aa198">&amp;#34;7070&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&amp;lt;!-- configuration of exposed service --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:service&lt;/span> interface=&lt;span style="color:#2aa198">&amp;#34;org.apache.dubbo.monitor.MonitorService&amp;#34;&lt;/span> ref=&lt;span style="color:#2aa198">&amp;#34;monitorService&amp;#34;&lt;/span> registry=&lt;span style="color:#2aa198">&amp;#34;N/A&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;bean&lt;/span> id=&lt;span style="color:#2aa198">&amp;#34;monitorService&amp;#34;&lt;/span> class=&lt;span style="color:#2aa198">&amp;#34;org.apache.dubbo.monitor.simple.SimpleMonitorService&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;/beans&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;li>
&lt;p>connected to the monitor service straightly&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:monitor&lt;/span> address=&lt;span style="color:#2aa198">&amp;#34;dubbo://127.0.0.1:7070/org.apache.dubbo.monitor.MonitorService&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>or:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sh" data-lang="sh">&lt;span style="display:flex;">&lt;span>&amp;lt;dubbo:monitor &lt;span style="color:#268bd2">address&lt;/span>&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">&amp;#34;127.0.0.1:7070&amp;#34;&lt;/span> /&amp;gt;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>or:&lt;/p>
&lt;p>&lt;strong>dubbo.properties&lt;/strong>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sh" data-lang="sh">&lt;span style="display:flex;">&lt;span>dubbo.monitor.address&lt;span style="color:#719e07">=&lt;/span>127.0.0.1:7070
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;/ol></description></item><item><title>Docs: Other Languages</title><link>https://dubbo.apache.org/en/docs/v2.7/user/languages/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/en/docs/v2.7/user/languages/</guid><description/></item></channel></rss>