| <rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Apache Dubbo – 其他</title><link>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/others/</link><description>Recent content in 其他 on Apache Dubbo</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><atom:link href="https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/others/index.xml" rel="self" type="application/rss+xml"/><item><title>Overview: 自定义服务容器</title><link>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/others/service-container/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/others/service-container/</guid><description> |
| <h2 id="特性说明">特性说明</h2> |
| <p>Dubbo 的服务容器是一个 standalone 的启动程序,因为后台服务不需要 Tomcat 或 JBoss 等 Web 容器的功能,如果硬要用 Web 容器去加载服务提供方,增加复杂性,也浪费资源。所以服务通常不需要 Tomcat/JBoss 等 Web 容器的特性,没必要用 Web 容器去加载服务。</p> |
| <p>Dubbo 服务容器只是一个简单的 Main 方法,并加载一个简单的 Spring 容器,用于暴露服务。</p> |
| <p>服务容器的加载内容可以扩展,内置了 spring, jetty, log4j 等加载,可通过 <a href="../../../reference-manual/spi/description/container">容器扩展点</a> 进行扩展。配置配在 java 命令的 -D 参数或者 <code>dubbo.properties</code> 中。</p> |
| <h2 id="使用场景">使用场景</h2> |
| <p>web 容器主要是用来响应 http 请求以及静态页面的,Dubbo 服务提供方只是对外提供 dubbo 服务,用 web 容器不太适合,单独作为 dubbo 服务提供方,只需要通过一个 main 方法加载一个简单的 spring 容器将服务暴露。</p> |
| <h2 id="使用方式">使用方式</h2> |
| <h3 id="spring-container">Spring Container</h3> |
| <ul> |
| <li>自动加载 <code>META-INF/spring</code> 目录下的所有 Spring 配置。</li> |
| <li>配置 spring 配置加载位置:</li> |
| </ul> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>dubbo.spring.config=classpath*:META-INF/spring/*.xml |
| </span></span></code></pre></div><h3 id="jetty-container">Jetty Container</h3> |
| <ul> |
| <li>启动一个内嵌 Jetty,用于汇报状态。</li> |
| <li>配置: |
| <ul> |
| <li><code>dubbo.jetty.port=8080</code>:配置 jetty 启动端口</li> |
| <li><code>dubbo.jetty.directory=/foo/bar</code>:配置可通过 jetty 直接访问的目录,用于存放静态文件</li> |
| <li><code>dubbo.jetty.page=log,status,system</code>:配置显示的页面,缺省加载所有页面</li> |
| </ul> |
| </li> |
| </ul> |
| <h3 id="log4j-container">Log4j Container</h3> |
| <ul> |
| <li>自动配置 log4j 的配置,在多进程启动时,自动给日志文件按进程分目录。</li> |
| <li>配置: |
| <ul> |
| <li><code>dubbo.log4j.file=/foo/bar.log</code>:配置日志文件路径</li> |
| <li><code>dubbo.log4j.level=WARN</code>:配置日志级别</li> |
| <li><code>dubbo.log4j.subdirectory=20880</code>:配置日志子目录,用于多进程启动,避免冲突</li> |
| </ul> |
| </li> |
| </ul> |
| <h3 id="容器加载说明">容器加载说明</h3> |
| <p>缺省只加载 spring</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>java org.apache.dubbo.container.Main |
| </span></span></code></pre></div><p>通过 main 函数参数传入要加载的容器</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>java org.apache.dubbo.container.Main spring jetty log4j |
| </span></span></code></pre></div><p>通过 JVM 启动参数传入要加载的容器</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>java org.apache.dubbo.container.Main -Ddubbo.container<span style="color:#719e07">=</span>spring,jetty,log4j |
| </span></span></code></pre></div><p>通过 classpath 下的 <code>dubbo.properties</code> 配置传入要加载的容器</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>dubbo.container=spring,jetty,log4j |
| </span></span></code></pre></div></description></item><item><title>Overview: 优雅停机</title><link>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/others/graceful-shutdown/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/others/graceful-shutdown/</guid><description> |
| <h2 id="特性说明">特性说明</h2> |
| <p>优雅停机是指服务实例能安全平稳的停止,对进行中的业务不产生影响。 |
| 一个Dubbo服务可能既作为服务提供者,又是服务消费者,当服务停止时:</p> |
| <ol> |
| <li>消费者不会再请求已停止的服务实例</li> |
| <li>该服务实例正在处理的请求能正常处理完成</li> |
| </ol> |
| <h2 id="使用场景">使用场景</h2> |
| <ol> |
| <li>通过 <code>kill PID</code> 停止服务</li> |
| <li>通过 SpringBoot Actuator 的 <code>/shutdown</code> 停止服务</li> |
| </ol> |
| <blockquote> |
| <p>Dubbo 3.0 及以上版本支持不同类型的Java应用,包括 SpringBoot 应用、 Spring 应用、非 Spring 应用。</p> |
| </blockquote> |
| <h2 id="使用方式">使用方式</h2> |
| <p>设置优雅停机超时时间,缺省超时时间是 10 秒,如果超时则强制关闭。 |
| 该参数可在 dubbo.properties 文件里配置,例如:配置为 30 秒。</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-properties" data-lang="properties"><span style="display:flex;"><span><span style="color:#586e75"># 停止服务等待时间,单位:毫秒</span> |
| </span></span><span style="display:flex;"><span>dubbo.service.shutdown.wait<span style="color:#719e07">=</span><span style="color:#2aa198">30000</span> |
| </span></span></code></pre></div> |
| <div class="alert alert-primary" role="alert"> |
| <h4 class="alert-heading">注意事项</h4> |
| <ol> |
| <li> |
| <p>Dubbo 是通过 JDK 的 ShutdownHook 来完成优雅停机的,所以如果用户使用 <code>kill -9 PID</code> 等强制关闭指令,是不会执行优雅停机的,只有通过 <code>kill PID</code> 时,才会执行。</p> |
| </li> |
| <li> |
| <p>验证是否执行了 Dubbo 的 ShutdownHook 可在日志文件中查找关键字:<code>Run shutdown hook now.</code></p> |
| </li> |
| <li> |
| <p>如果使用了 Spring,请升级 4.2 及以上版本,建议使用 5 以上版本</p> |
| </li> |
| <li> |
| <p>如果使用了 SpringBoot,Dubbo 的 ShutdownHook 会在 SpringBoot 的 ShutdownHook 之前执行, |
| 如果使用 SpringBoot 2.3及以上版本,建议配合 SpringBoot 的优雅停机使用,在配置文件 applicaion.yml 中配置:</p> |
| </li> |
| </ol> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yml" data-lang="yml"><span style="display:flex;"><span><span style="color:#268bd2">server</span>: |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">shutdown</span>: graceful |
| </span></span></code></pre></div><ol start="5"> |
| <li>如果 ShutdownHook 不能生效,可根据具体场景自行调用:</li> |
| </ol> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span>ApplicationModel<span style="color:#719e07">.</span>defaultModel<span style="color:#719e07">().</span>destroy<span style="color:#719e07">();</span> |
| </span></span></code></pre></div> |
| </div></description></item><item><title>Overview: 主机地址自定义暴露</title><link>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/others/set-host/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/others/set-host/</guid><description> |
| <h2 id="特性说明">特性说明</h2> |
| <p>在 Dubbo 中, Provider 启动时主要做两个事情</p> |
| <ul> |
| <li>一是启动 server</li> |
| <li>二是向注册中心注册服务。启动 server 时需要绑定 socket,向注册中心注册服务时也需要发送 socket 唯一标识服务地址。</li> |
| </ul> |
| <ol> |
| <li><code>dubbo</code> 中不设置 <code>host</code> 时默认 <code>host</code> 是什么?</li> |
| <li>那在 <code>dubbo</code> 中如何指定服务的 <code>host</code>,我们是否可以用 hostname 或 domain 代替 IP 地址作为 <code>host</code>?</li> |
| <li>在使用 docker 时,有时需要设置端口映射,此时,启动 server 时绑定的 socket 和向注册中心注册的 socket 使用不同的端口号,此时又该如何设置?</li> |
| </ol> |
| <h2 id="使用场景">使用场景</h2> |
| <p>应用程序包含多个服务每个服务定制地址,外部客户端通过定制的地址访问服务。</p> |
| <p>应用程序同一服务的多个版本每个版本的服务定制地址,外部客户端通过定制的地址访问相应版本的服务。</p> |
| <p>应用程序多个地区部署服务每个地区定制地址,外部客户端通过定制的地址访问相应地区的相应服务。</p> |
| <h2 id="使用方式">使用方式</h2> |
| <h3 id="不设置-host-时默认-host">不设置 host 时默认 host</h3> |
| <p>一般的 dubbo 协议配置如下:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span> ... |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;dubbo:protocol</span> name=<span style="color:#2aa198">&#34;dubbo&#34;</span> port=<span style="color:#2aa198">&#34;20890&#34;</span> <span style="color:#268bd2">/&gt;</span> |
| </span></span><span style="display:flex;"><span> ... |
| </span></span></code></pre></div><p>可以看到,只配置了端口号,没有配置 host,此时设置的 host 又是什么呢?</p> |
| <p>查看代码发现,在 <code>org.apache.dubbo.config.ServiceConfig#findConfigedHosts()</code> 中,通过 <code>InetAddress.getLocalHost().getHostAddress()</code> 获取默认 host。其返回值如下:</p> |
| <ol> |
| <li>未联网时,返回 127.0.0.1</li> |
| <li>在阿里云服务器中,返回私有地址,如: 172.18.46.234</li> |
| <li>在本机测试时,返回公有地址,如: 30.5.10.11</li> |
| </ol> |
| <h3 id="指定服务的-socket">指定服务的 socket</h3> |
| <p>除此之外,可以通过 <code>dubbo.protocol</code> 或 <code>dubbo.provider </code>的 <code>host</code> 属性对 <code>host</code> 进行配置,支持IP地址和域名,如下:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span> ... |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;dubbo:protocol</span> name=<span style="color:#2aa198">&#34;dubbo&#34;</span> port=<span style="color:#2aa198">&#34;20890&#34;</span> host=<span style="color:#2aa198">&#34;www.example.com&#34;</span><span style="color:#268bd2">/&gt;</span> |
| </span></span><span style="display:flex;"><span> ... |
| </span></span></code></pre></div><h3 id="socket-使用不同的端口号">socket 使用不同的端口号</h3> |
| <p>见 <a href="https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-docker">dubbo 通过环境变量设置 host</a></p> |
| <p>有些部署场景需要动态指定服务注册的地址,如 docker bridge 网络模式下要指定注册宿主机 ip 以实现外网通信。dubbo 提供了两对启动阶段的系统属性,用于设置对外通信的ip、port地址。</p> |
| <ul> |
| <li><strong>DUBBO_IP_TO_REGISTRY</strong>:注册到注册中心的 ip 地址</li> |
| <li><strong>DUBBO_PORT_TO_REGISTRY</strong>:注册到注册中心的 port 端口</li> |
| <li><strong>DUBBO_IP_TO_BIND</strong>:监听 ip 地址</li> |
| <li><strong>DUBBO_PORT_TO_BIND</strong>:监听 port 端口</li> |
| </ul> |
| <p>以上四个配置项均为可选项,如不配置 dubbo 会自动获取 ip 与端口,请根据具体的部署场景灵活选择配置。 |
| dubbo 支持多协议,如果一个应用同时暴露多个不同协议服务,且需要为每个服务单独指定 ip 或 port,请分别在以上属性前加协议前缀。 如:</p> |
| <ul> |
| <li><strong>HESSIAN_DUBBO_PORT_TO_BIND</strong>:hessian 协议绑定的 port</li> |
| <li><strong>DUBBO_DUBBO_PORT_TO_BIND</strong>:dubbo 协议绑定的 port</li> |
| <li><strong>HESSIAN_DUBBO_IP_TO_REGISTRY</strong>:hessian 协议注册的 ip</li> |
| <li><strong>DUBBO_DUBBO_IP_TO_REGISTRY</strong>:dubbo 协议注册的 ip</li> |
| </ul> |
| <p>PORT_TO_REGISTRY 或 IP_TO_REGISTRY 不会用作默认 PORT_TO_BIND 或 IP_TO_BIND,但是反过来是成立的。如:</p> |
| <ul> |
| <li>设置 <code>PORT_TO_REGISTRY=20881</code> 和 <code>IP_TO_REGISTRY=30.5.97.6</code>,则 <code>PORT_TO_BIND</code> 和 <code>IP_TO_BIND</code> 不受影响</li> |
| <li>设置 <code>PORT_TO_BIND=20881</code> 和 <code>IP_TO_BIND=30.5.97.6</code>,则默认 <code>PORT_TO_REGISTRY=20881</code> 且 <code>IP_TO_REGISTRY=30.5.97.6</code></li> |
| </ul> |
| <div class="alert alert-primary" role="alert"> |
| <h4 class="alert-heading">总结</h4> |
| <ol> |
| <li>可以通过<code>dubbo.protocol</code>或<code>dubbo.provider</code>的<code>host</code>属性对<code>host</code>进行配置,支持IP地址和域名.但此时注册到注册中心的IP地址和监听IP地址是同一个值</li> |
| <li>为了解决在虚拟环境或局域网内consumer无法与provider通信的问题,可以通过环境变量分别设置注册到注册中心的IP地址和监听IP地址,其优先级高于<code>dubbo.protocol</code>或<code>dubbo.provider</code>的<code>host</code>配置</li> |
| </ol> |
| <p>参考一:<a href="https://github.com/apache/dubbo/issues/2043">Proposal: support hostname or domain in service discovery.</a></p> |
| <p>参考二:<a href="https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-docker">dubbo通过环境变量设置host</a></p> |
| </div></description></item><item><title>Overview: 日志框架适配及运行时管理</title><link>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/others/logger-management/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/others/logger-management/</guid><description> |
| <h2 id="特性说明">特性说明</h2> |
| <p>日志框架适配,自 <code>2.2.1</code> 开始,dubbo 开始内置 log4j、slf4j、jcl、jdk 这些日志框架的适配。</p> |
| <p>日志框架运行时管理,自 <code>3.0.10</code> 开始,dubbo-qos 运行时管控支持查询日志配置以及动态修改使用的日志框架和日志级别。</p> |
| <blockquote> |
| <p>通过 dubbo-qos 修改的日志配置不进行持久化存储,在应用重启后将会失效。</p> |
| </blockquote> |
| <h2 id="使用场景">使用场景</h2> |
| <p>应用程序日志: 收集和存储分布式服务的应用程序日志,支持多种日志格式,包括文本、JSON、XML 和二进制,提供了过滤、聚合和分析日志数据,用于解决分布式应用程序的问题,监控服务的性能。</p> |
| <p>运行时管理: 管理分布式服务的运行时,提供设置阈值和在满足某些条件时采取纠正措施,确保服务保持稳定并高效运行实时检测和响应性能问题。</p> |
| <h2 id="使用方式">使用方式</h2> |
| <h3 id="日志框架适配">日志框架适配</h3> |
| <p>可以通过以下方式显式配置日志输出策略</p> |
| <ol> |
| <li>命令行</li> |
| </ol> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>java -Ddubbo.application.logger<span style="color:#719e07">=</span>log4j |
| </span></span></code></pre></div><ol start="2"> |
| <li><code>dubbo.properties</code> 中指定</li> |
| </ol> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>dubbo.application.logger=log4j |
| </span></span></code></pre></div><ol start="3"> |
| <li><code>dubbo.xml</code> 中配置</li> |
| </ol> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span><span style="color:#268bd2">&lt;dubbo:application</span> logger=<span style="color:#2aa198">&#34;log4j&#34;</span> <span style="color:#268bd2">/&gt;</span> |
| </span></span></code></pre></div><p>自定义扩展可以参考 <a href="../../../reference-manual/spi/description/logger-adapter">日志适配扩展</a></p> |
| <h3 id="日志框架运行时管理">日志框架运行时管理</h3> |
| <ol> |
| <li>查询日志配置 |
| 命令:<code>loggerInfo</code></li> |
| </ol> |
| <p><strong>示例</strong></p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>&gt; telnet 127.0.0.1 <span style="color:#2aa198">22222</span> |
| </span></span><span style="display:flex;"><span>&gt; loggerInfo |
| </span></span></code></pre></div><p><strong>输出</strong></p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>Trying 127.0.0.1... |
| </span></span><span style="display:flex;"><span>Connected to localhost. |
| </span></span><span style="display:flex;"><span>Escape character is &#39;^]&#39;. |
| </span></span><span style="display:flex;"><span> ___ __ __ ___ ___ ____ |
| </span></span><span style="display:flex;"><span> / _ \ / / / // _ ) / _ ) / __ \ |
| </span></span><span style="display:flex;"><span> / // // /_/ // _ |/ _ |/ /_/ / |
| </span></span><span style="display:flex;"><span>/____/ \____//____//____/ \____/ |
| </span></span><span style="display:flex;"><span>dubbo&gt;loggerInfo |
| </span></span><span style="display:flex;"><span>Available logger adapters: [jcl, jdk, log4j, slf4j]. Current Adapter: [log4j]. Log level: INFO |
| </span></span></code></pre></div><ol start="2"> |
| <li>修改日志级别 |
| 命令:<code>switchLogLevel {level}</code></li> |
| </ol> |
| <p>level: <code>ALL</code>, <code>TRACE</code>, <code>DEBUG</code>, <code>INFO</code>, <code>WARN</code>, <code>ERROR</code>, <code>OFF</code></p> |
| <p><strong>示例</strong></p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>&gt; telnet 127.0.0.1 <span style="color:#2aa198">22222</span> |
| </span></span><span style="display:flex;"><span>&gt; switchLogLevel WARN |
| </span></span></code></pre></div><p><strong>输出</strong></p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>Trying 127.0.0.1... |
| </span></span><span style="display:flex;"><span>Connected to localhost. |
| </span></span><span style="display:flex;"><span>Escape character is &#39;^]&#39;. |
| </span></span><span style="display:flex;"><span> ___ __ __ ___ ___ ____ |
| </span></span><span style="display:flex;"><span> / _ \ / / / // _ ) / _ ) / __ \ |
| </span></span><span style="display:flex;"><span> / // // /_/ // _ |/ _ |/ /_/ / |
| </span></span><span style="display:flex;"><span>/____/ \____//____//____/ \____/ |
| </span></span><span style="display:flex;"><span>dubbo&gt;loggerInfo |
| </span></span><span style="display:flex;"><span>Available logger adapters: [jcl, jdk, log4j, slf4j]. Current Adapter: [log4j]. Log level: INFO |
| </span></span><span style="display:flex;"><span>dubbo&gt;switchLogLevel WARN |
| </span></span><span style="display:flex;"><span>OK |
| </span></span><span style="display:flex;"><span>dubbo&gt;loggerInfo |
| </span></span><span style="display:flex;"><span>Available logger adapters: [jcl, jdk, log4j, slf4j]. Current Adapter: [log4j]. Log level: WARN``` |
| </span></span></code></pre></div><ol start="3"> |
| <li>修改日志输出框架 |
| 命令:<code>switchLogger {loggerAdapterName}</code></li> |
| </ol> |
| <p>loggerAdapterName: <code>slf4j</code>, <code>jcl</code>, <code>log4j</code>, <code>jdk</code>, <code>log4j2</code></p> |
| <p><strong>示例</strong></p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>&gt; telnet 127.0.0.1 <span style="color:#2aa198">22222</span> |
| </span></span><span style="display:flex;"><span>&gt; switchLogger slf4j |
| </span></span></code></pre></div><p><strong>输出</strong></p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>Trying 127.0.0.1... |
| </span></span><span style="display:flex;"><span>Connected to localhost. |
| </span></span><span style="display:flex;"><span>Escape character is &#39;^]&#39;. |
| </span></span><span style="display:flex;"><span> ___ __ __ ___ ___ ____ |
| </span></span><span style="display:flex;"><span> / _ \ / / / // _ ) / _ ) / __ \ |
| </span></span><span style="display:flex;"><span> / // // /_/ // _ |/ _ |/ /_/ / |
| </span></span><span style="display:flex;"><span>/____/ \____//____//____/ \____/ |
| </span></span><span style="display:flex;"><span>dubbo&gt;loggerInfo |
| </span></span><span style="display:flex;"><span>Available logger adapters: [jcl, slf4j, log4j, jdk]. Current Adapter: [log4j]. Log level: INFO |
| </span></span><span style="display:flex;"><span>dubbo&gt;switchLogger slf4j |
| </span></span><span style="display:flex;"><span>OK |
| </span></span><span style="display:flex;"><span>dubbo&gt;loggerInfo |
| </span></span><span style="display:flex;"><span>Available logger adapters: [jcl, slf4j, log4j, jdk]. Current Adapter: [slf4j]. Log level: INFO |
| </span></span></code></pre></div></description></item><item><title>Overview: Kubernetes 生命周期探针</title><link>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/others/dubbo-kubernetes-probe/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/others/dubbo-kubernetes-probe/</guid><description> |
| <h2 id="特性说明">特性说明</h2> |
| <p><a href="https://kubernetes.io/zh/docs/concepts/workloads/pods/pod-lifecycle/">Pod 的生命周期</a> 与服务调度息息相关,通过对 Kubernetes 官方探针的实现,能够使 Dubbo3 乃至整个应用的生命周期与 Pod 的生命周期,在 Pod 的整个生命周期中,影响到 Pod 的就只有健康检查这一部分, 我们可以通过配置 liveness probe(存活探针)和 readiness probe(可读性探针)来影响容器的生命周期。</p> |
| <p>通过 Dubbo3 的 SPI 机制,在内部实现多种“探针”,基于 Dubbo3 QOS 运维模块的 HTTP 服务,使容器探针能够获取到应用内对应探针的状态。另外,SPI 的实现机制也利于用户自行拓展内部“探针”,使整个应用的生命周期更有效的进行管控。</p> |
| <p><strong>三种探针对应的 SPI 接口</strong></p> |
| <ul> |
| <li>livenessProbe: <code>org.apache.dubbo.qos.probe.LivenessProbe</code></li> |
| <li>readinessProbe: <code>org.apache.dubbo.qos.probe.ReadinessProbe</code></li> |
| <li>startupProbe: <code>org.apache.dubbo.qos.probe.StartupProbe</code></li> |
| </ul> |
| <p>接口将自动获取当前应用所有 SPI 的实现,对应接口的 SPI 实现均成功就绪则接口返回成功。</p> |
| <p>Dubbo3 SPI 更多扩展的介绍见 <a href="https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/">Dubbo SPI扩展</a></p> |
| <h2 id="使用场景">使用场景</h2> |
| <p><code>liveness probe</code> 来确定你的应用程序是否正在运行,查看是否存活。</p> |
| <p><code>readiness probe</code> 来确定容器是否已经就绪可以接收流量过来,是否准备就绪,是否可以开始工作。</p> |
| <p><code>startup probe</code> 来确定容器内的应用程序是否已启动,如果提供了启动探测则禁用所有其他探测,直到它成功为止,如果启动探测失败则杀死容器,容器将服从其重启策略。如果容器没有提供启动探测,则默认状态为成功。</p> |
| <h2 id="使用方式">使用方式</h2> |
| <h3 id="存活检测">存活检测</h3> |
| <p>对于 livenessProbe 存活检测,由于 Dubbo3 框架本身无法获取到应用的存活状态,因此本接口无默认实现,且默认返回成功。开发者可以根据 SPI 定义对此 SPI 接口进行拓展,从应用层次对是否存活进行判断。</p> |
| <p>关于 <a href="../../../reference-manual/spi/description/liveness/">liveness 存活探针</a> 扩展示例</p> |
| <h3 id="就绪检测">就绪检测</h3> |
| <p>对于 readinessProbe 就绪检测,目前 Dubbo3 默认提供了两个检测维度,一是对 Dubbo3 服务自身是否启停做判断,另外是对所有服务是否存在已注册接口,如果所有服务均已从注册中心下线(可以通过 QOS 运维进行操作)将返回未就绪的状态。</p> |
| <p>关于 <a href="../../../reference-manual/spi/description/readiness/">readiness 就绪探针</a> 扩展示例</p> |
| <h3 id="启动检测">启动检测</h3> |
| <p>对于 startupProbe 启动检测,目前 Dubbo3 默认提供了一个检测维度,即是在所有启动流程(接口暴露、注册中心写入等)均结束后返回已就绪状态。</p> |
| <p>关于 <a href="../../../reference-manual/spi/description/startup/">startup 启动探针</a> 扩展示例</p> |
| <h3 id="参考示例">参考示例</h3> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#268bd2">livenessProbe</span>: |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">httpGet</span>: |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">path</span>: /live |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">port</span>: <span style="color:#2aa198">22222</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">initialDelaySeconds</span>: <span style="color:#2aa198">5</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">periodSeconds</span>: <span style="color:#2aa198">5</span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">readinessProbe</span>: |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">httpGet</span>: |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">path</span>: /ready |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">port</span>: <span style="color:#2aa198">22222</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">initialDelaySeconds</span>: <span style="color:#2aa198">5</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">periodSeconds</span>: <span style="color:#2aa198">5</span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">startupProbe</span>: |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">httpGet</span>: |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">path</span>: /startup |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">port</span>: <span style="color:#2aa198">22222</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">failureThreshold</span>: <span style="color:#2aa198">30</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">periodSeconds</span>: <span style="color:#2aa198">10</span> |
| </span></span></code></pre></div><blockquote> |
| <p>QOS 当计算节点检测到内存压力时,kuberentes 会 BestEffort -&gt; Burstable -&gt; Guaranteed 依次驱逐 Pod。</p> |
| </blockquote> |
| <p>目前三种探针均有对应的接口,路径为 QOS 中的命令,端口信息请根据 QOS 配置进行对应修改(默认端口为 22222)。其他参数请参考 <a href="https://kubernetes.io/zh/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/">Kubernetes官方文档说明</a>。</p></description></item><item><title>Overview: Dubbo 部署 Docker 环境</title><link>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/others/docker/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/others/docker/</guid><description> |
| <h2 id="特性说明">特性说明</h2> |
| <p>一些部署场景需要动态地指定服务注册地址。例如,docker bridge网络模式需要为外部网络通信指定一个注册主机IP。Dubbo在启动阶段提供了两对系统属性,用于设置外部通信的IP和端口地址。</p> |
| <ul> |
| <li>DUBBO_IP_TO_REGISTRY &mdash; 注册到注册中心的IP地址</li> |
| <li>DUBBO_PORT_TO_REGISTRY &mdash; 注册到注册中心的端口</li> |
| <li>DUBBO_IP_TO_BIND &mdash; 侦听IP地址</li> |
| <li>DUBBO_PORT_TO_BIND &mdash; 侦听端口</li> |
| </ul> |
| <blockquote> |
| <ol> |
| <li>以上四个配置是可选的。如果没有配置,Dubbo会自动获得IP和端口。请根据部署情况,灵活选择。</li> |
| <li>Dubbo支持多协议. <strong>如果一个应用程序同时暴露了多个不同的协议服务,并且需要为每个服务分别指定IP或端口。请在上述属性前分别添加协议前缀。</strong></li> |
| </ol> |
| <ul> |
| <li>HESSIAN_DUBBO_PORT_TO_BIND hessian 协议绑定端口</li> |
| <li>DUBBO_DUBBO_PORT_TO_BIND dubbo 协议绑定端口</li> |
| <li>HESSIAN_DUBBO_IP_TO_REGISTRY hessian 协议注册的IP</li> |
| <li>DUBBO_DUBBO_IP_TO_REGISTRY dubbo 协议注册的IP</li> |
| </ul> |
| <ol start="3"> |
| <li><code>PORT_TO_REGISTRY</code>或<code>IP_TO_REGISTRY</code>不会被用作默认的<code>PORT_TO_BIND</code>或<code>IP_TO_BIND</code>,但相反的是 true。</li> |
| </ol> |
| <ul> |
| <li>如果设置<code>PORT_TO_REGISTRY=20881</code> <code>IP_TO_REGISTRY=30.5.97.6</code>,那么 <code>PORT_TO_BIND</code> <code>IP_TO_BIND</code>不会受到影响。</li> |
| <li>如果设置<code>PORT_TO_BIND=20881</code> <code>IP_TO_BIND=30.5.97.6</code>,那么 <code>PORT_TO_REGISTRY=20881</code> <code>IP_TO_REGISTRY=30.5.97.6</code> 默认情况下。</li> |
| </ul> |
| </blockquote> |
| <h2 id="使用场景">使用场景</h2> |
| <p>提供隔离的环境,从而确保在开发和部署过程中服务不会受到彼此的影响,对于微服务的开发和部署有很大帮助。</p> |
| <h2 id="使用方式">使用方式</h2> |
| <p><a href="https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-docker">dubbo-docker-sample</a> 本地操作过程:</p> |
| <ol> |
| <li>克隆项目到本地</li> |
| </ol> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>git clone git@github.com:dubbo/dubbo-docker-sample.git |
| </span></span><span style="display:flex;"><span><span style="color:#b58900">cd</span> dubbo-docker-sample |
| </span></span></code></pre></div><ol start="2"> |
| <li>包本地的maven</li> |
| </ol> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>mvn clean install |
| </span></span></code></pre></div><ol start="3"> |
| <li>通过docker build建立一个镜像</li> |
| </ol> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>docker build --no-cache -t dubbo-docker-sample . |
| </span></span></code></pre></div><ol start="4"> |
| <li>构建镜像</li> |
| </ol> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>FROM openjdk:8-jdk-alpine |
| </span></span><span style="display:flex;"><span>ADD target/dubbo-docker-sample-0.0.1-SNAPSHOT.jar app.jar |
| </span></span><span style="display:flex;"><span>ENV <span style="color:#268bd2">JAVA_OPTS</span><span style="color:#719e07">=</span><span style="color:#2aa198">&#34;&#34;</span> |
| </span></span><span style="display:flex;"><span>ENTRYPOINT <span style="color:#b58900">exec</span> java <span style="color:#268bd2">$JAVA_OPTS</span> -jar /app.jar |
| </span></span></code></pre></div><ol start="5"> |
| <li>从镜像中创建和运行容器</li> |
| </ol> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#586e75"># 由于我们使用zk注册中心,我们先启动zk容器</span> |
| </span></span><span style="display:flex;"><span>docker run --name zkserver --restart always -d zookeeper:3.4.9 |
| </span></span></code></pre></div><div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>docker run -e <span style="color:#268bd2">DUBBO_IP_TO_REGISTRY</span><span style="color:#719e07">=</span>30.5.97.6 -e <span style="color:#268bd2">DUBBO_PORT_TO_REGISTRY</span><span style="color:#719e07">=</span><span style="color:#2aa198">20881</span> -p 30.5.97.6:20881:20880 --link zkserver:zkserver -it --rm dubbo-docker-sample |
| </span></span></code></pre></div><blockquote> |
| <p>假设主机IP是 30.5.97.6. |
| 通过环境变量设置提供商注册的IP地址和注册中心的端口 <code>DUBBO_IP_TO_REGISTRY=30.5.97.6</code> <code>DUBBO_PORT_TO_REGISTRY=20881</code> |
| 通过以下方式实现端口映射<code>-p 30.5.97.6:20881:20880</code>, 其中20880是由dubbo自动选择的监听端口。没有监控IP的配置,所以它将监听0.0.0.0(所有IP)。 |
| 启动后,提供者的注册地址是30.5.97.6:20881,而容器的监听地址是:0.0.0.0:20880。 </p> |
| </blockquote> |
| <ol start="6"> |
| <li>测试从另一个主机或容器中执行</li> |
| </ol> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>telnet 30.5.97.6 <span style="color:#2aa198">20881</span> |
| </span></span><span style="display:flex;"><span>ls |
| </span></span><span style="display:flex;"><span>invoke org.apache.dubbo.test.docker.DemoService.hello<span style="color:#719e07">(</span><span style="color:#2aa198">&#34;world&#34;</span><span style="color:#719e07">)</span> |
| </span></span></code></pre></div></description></item></channel></rss> |