diff --git a/.github/workflows/build_and_deploy_history.yml b/.github/workflows/build_and_deploy_history.yml index c25fd94c3a78..8a91fed44c46 100644 --- a/.github/workflows/build_and_deploy_history.yml +++ b/.github/workflows/build_and_deploy_history.yml @@ -23,7 +23,7 @@ jobs: - name: Setup Hugo uses: peaceiris/actions-hugo@v2 with: - hugo-version: 'latest' + hugo-version: '0.121.2' extended: true - name: Build env: diff --git a/.github/workflows/link_check.yml b/.github/workflows/link_check.yml index a80e74a76ee5..9a56600953f5 100644 --- a/.github/workflows/link_check.yml +++ b/.github/workflows/link_check.yml @@ -25,7 +25,7 @@ jobs: - name: Setup Hugo uses: peaceiris/actions-hugo@v2 with: - hugo-version: '0.122.0' + hugo-version: '0.121.2' extended: true - name: Build env: diff --git a/.htmltest.yml b/.htmltest.yml index 44b93ede5a54..bd5fb65df811 100644 --- a/.htmltest.yml +++ b/.htmltest.yml @@ -1,6 +1,6 @@ DirectoryPath: public -IgnoreAltMissing: false -IgnoreAltEmpty: false +IgnoreAltMissing: true +IgnoreAltEmpty: true IgnoreInternalEmptyHash: true IgnoreDirectoryMissingTrailingSlash: true IgnoreCanonicalBrokenLinks: false diff --git a/assets/scss/_base.scss b/assets/scss/_base.scss index dc8a3b87e98e..bf146fbf548d 100755 --- a/assets/scss/_base.scss +++ b/assets/scss/_base.scss @@ -149,7 +149,7 @@ main { // HERO .header-hero { background-image: url(/imgs/texture.png); - background-color: $blue; + background-color: $gray; text-align: center; padding-left: 0; padding-right: 0; @@ -181,7 +181,7 @@ main { } .header-hero { - background-color: $blue; + background-color: $gray; h5 { margin: 20px 0; diff --git a/assets/scss/_buttons.scss b/assets/scss/_buttons.scss new file mode 100644 index 000000000000..2139b5b4ca9c --- /dev/null +++ b/assets/scss/_buttons.scss @@ -0,0 +1,15 @@ +// Buttons + +@if $enable-rounded { + .btn { + border-radius: 1rem; + + &-lg { + border-radius: 2rem; + } + + &-sm { + border-radius: 1rem; + } + } +} diff --git a/assets/scss/_case-studies.scss b/assets/scss/_case-studies.scss index 4f4486412752..52eea8acf945 100755 --- a/assets/scss/_case-studies.scss +++ b/assets/scss/_case-studies.scss @@ -66,7 +66,7 @@ h2 { } body footer { - background-color: #585858 !important; + background-color: #F4F4F6 !important; } .section1 { diff --git a/assets/scss/_custom.scss b/assets/scss/_custom.scss index 88b5c91c4882..7158c8b8bda8 100755 --- a/assets/scss/_custom.scss +++ b/assets/scss/_custom.scss @@ -3,6 +3,7 @@ $announcement-size-adjustment: 8px; /* GLOBAL */ .td-main { .row { + --bs-gutter-x: 4rem; margin: 0; } @@ -24,6 +25,10 @@ $announcement-size-adjustment: 8px; .ui-widget-content a { color: $blue; } + + a { + text-decoration: none; + } } .footer-margin-0{ @@ -106,17 +111,18 @@ body.td-404 main .error-details { .td-navbar { position: fixed !important; width: 100%; - padding-bottom: 1rem !important; + height: 40px; background: transparent !important; transition: 0.3s; + padding: 1rem; .navbar-brand { - position: absolute; - width: 45px; - height: 44px; + // position: absolute; + width: 96px; + height: 20px; background-repeat: no-repeat; background-size: contain; - background-image: url("/imgs/favicon.png"); + background-image: url("/imgs/nav_logo2.png"); } #hamburger { @@ -135,9 +141,11 @@ body.td-404 main .error-details { } } + + .td-navbar-nav-scroll { overflow: visible !important; - display: none; + // display: none; .navbar-nav { overflow: visible !important; @@ -146,6 +154,7 @@ body.td-404 main .error-details { flex-direction: row; flex-wrap: wrap; justify-content: space-evenly; + padding-bottom: 0px!important; .nav-item { position: relative; @@ -154,7 +163,7 @@ body.td-404 main .error-details { .active::after { position: absolute; width: 100%; - height: 2px; + height: 0px; content: ""; bottom: -4px; left: 0; @@ -163,21 +172,22 @@ body.td-404 main .error-details { } } + @media only screen and (min-width: 768px) { - display: block; - margin-top: 3.5rem !important; + display: flex!important; + align-items: center!important; } - @media only screen and (min-width: 1075px) { - margin-top: 1rem !important; - } } + // Flip-Nav .flip-nav .td-navbar { - background-color: white !important; - // box-shadow: 0 1px 2px $medium-grey; - border: 1px solid #ddd; + // background-color: #EBECEF !important; + .dropdown { + min-width: 0px; + + } .navbar-nav { .nav-item { &.show .nav-link, @@ -194,6 +204,24 @@ body.td-404 main .error-details { color: $medium-grey; } } + .nav-link { + font-size: 14px; + font-weight: 400; + color: #597371; + &:hover { + color:#49615f; + } + } + } + .nav-item-line ::after{ + content:""; + position: absolute; + top: 50%; + transform: translateY(-50%); + left: 100%; + width: 1px; + height: 16px; + background-color: #8FA8A6; } } @@ -659,7 +687,7 @@ body.td-documentation { margin-bottom: 0px; // for padding-top see _size.scss - padding-bottom: calc(max(2em, 2rem)); + padding-bottom: calc(max(1em, 1rem)); max-width: calc(min(1200px - 8em, 80vw)); } @@ -687,7 +715,7 @@ body.td-documentation { @media (min-width: 992px) { #announcement aside { // more specific .announcement-main { - padding-top: calc(max(8em, 8rem)); + padding-top: calc(max(6em, 6rem)); } } } @@ -860,10 +888,27 @@ div.alert > em.javascript-required { margin: calc(max(4em, ( 8vh + 4em ) / 2)) 0 0.25em 0; } -#td-sidebar-menu{ - overflow: auto; - white-space: nowrap; +#docsearch { + .DocSearch-Button { + background: #DDDEE4; + padding: 0 10px !important; + } + .DocSearch-Button-Container{ + width: 15px; + } + .DocSearch-Button-Placeholder{ + font-size: 12px; + display: none; + } + .DocSearch-Button-Keys{ + display: none; + } +} + +#language .btn-language { + width: 156px; + height: 40px; + margin-right: 16px; + margin-bottom: 12px; + border-radius: 24px; } -.td-page-meta a{ - display: inline-block !important; -} \ No newline at end of file diff --git a/assets/scss/_skin.scss b/assets/scss/_skin.scss index 32c94b9dc521..4d5a1bc81031 100755 --- a/assets/scss/_skin.scss +++ b/assets/scss/_skin.scss @@ -3,3 +3,4 @@ $light-grey: #f7f7f7; $dark-grey: #303030; $medium-grey: #4c4c4c; $white: #ffffff; +$gray: #EBECEF; diff --git a/assets/scss/main.scss b/assets/scss/main.scss index 1674155188fb..82efa2e46e85 100644 --- a/assets/scss/main.scss +++ b/assets/scss/main.scss @@ -1,9 +1,11 @@ -@import "support/functions"; +@import "../vendor/bootstrap/scss/functions"; +@import "_variables_forward"; @import "variables_project"; @import "variables"; @import "support/mixins"; @import "../vendor/bootstrap/scss/bootstrap"; +@import "support/bootstrap_vers_test"; @import "../vendor/Font-Awesome/scss/fontawesome.scss"; @import "../vendor/Font-Awesome/scss/solid.scss"; @@ -11,6 +13,7 @@ @import "support/utilities"; @import "colors"; +@import "table"; @import "boxes"; @import "blog"; @import "code"; @@ -18,7 +21,6 @@ @import "sidebar-tree"; @import "sidebar-toc"; @import "buttons"; -@import "breadcrumb"; @import "alerts"; @import "content"; @import "search"; @@ -27,6 +29,9 @@ @import "section-index"; @import "pageinfo"; @import "taxonomy"; +@import "drawio"; +@import "shortcodes"; +@import "swagger"; @if $td-enable-google-fonts { @import url("/css/open-sans.css"); @@ -98,4 +103,4 @@ footer { @import "tablet"; @import "desktop"; @import "reset"; -@import "size"; \ No newline at end of file +@import "size"; diff --git a/cn_config.toml b/cn_config.toml index 00198e97de0c..8fd6d8df1617 100644 --- a/cn_config.toml +++ b/cn_config.toml @@ -55,7 +55,7 @@ defaultContentLanguageInSubdir = false [languages.en] title = "Apache Dubbo" description = "Apache Dubbo Official Website" -languageName = "English" +languageName = "EN" contentDir = "content/en" # Weight used for sorting. weight = 1 @@ -208,6 +208,26 @@ url = "mailto:dev-subscribe@dubbo.apache.org" icon = "fa fa-envelope" desc = "Discuss development issues around the project" + +[params.ecosystem] +navLabel = "生态" + [params.ecosystem.navOptions] + [[params.ecosystem.navOptions.items]] + name = "Launch A Project" + url = "/zh-cn/blog" + [[params.ecosystem.navOptions.items]] + name = "可视化控制台" + url = "/zh-cn/download" + [[params.ecosystem.navOptions.items]] + name = "商城系统" + url = "/option-3" + [[params.ecosystem.navOptions.items]] + name = "Benchmark" + url = "/option-3" + [[params.ecosystem.navOptions.items]] + name = "Proxyless Mesh" + url = "/option-3" + [sitemap] changefreq = "monthly" filename = "sitemap.xml" diff --git a/config.toml b/config.toml index 52ca0c53ec57..e7464afad884 100644 --- a/config.toml +++ b/config.toml @@ -55,7 +55,7 @@ defaultContentLanguageInSubdir = false [languages.en] title = "Apache Dubbo" description = "Apache Dubbo Official Website" -languageName = "English" +languageName = "EN" contentDir = "content/en" # Weight used for sorting. weight = 1 @@ -68,6 +68,81 @@ contentDir = "content/zh-cn" #time_format_default = "02.01.2006" #time_format_blog = "02.01.2006" + [languages.en.params.community] + navLabel = "COMMUNITY" + weight = 2 + [[languages.en.params.community.navOptions.items]] + name = "News" + url = "/en/blog/news/" + [[languages.en.params.community.navOptions.items]] + name = "Security Notices" + url = "/en/overview/notices/" + [[languages.en.params.community.navOptions.items]] + name = "Contributor's Guide" + url = "/zh-cn/contact/" +# [[languages.en.params.community.navOptions.items]] +# name = "Meet The Team" +# url = "" + + # Weight used for sorting. + weight = 2 + [languages.zh-cn.params.community] + navLabel = "联系社区" + weight = 2 + [[languages.zh-cn.params.community.navOptions.items]] + name = "新闻" + url = "/zh-cn/blog/news/" + [[languages.zh-cn.params.community.navOptions.items]] + name = "安全公告" + url = "/zh-cn/overview/notices/" + [[languages.zh-cn.params.community.navOptions.items]] + name = "贡献者指南" + url = "/zh-cn/contact/" +# [[languages.zh-cn.params.community.navOptions.items]] +# name = "认识团队" +# url = "" + + + + [languages.en.params.ecosystem] + navLabel = "ECOSYSTEM" + weight = 2 + [[languages.en.params.ecosystem.navOptions.items]] + name = "Code Generator" + url = "https://start.dubbo.apache.org/" + [[languages.en.params.ecosystem.navOptions.items]] + name = "Visualizable Console" + url = "/zh-cn/overview/mannual/control-plane/" +# [[languages.en.params.ecosystem.navOptions.items]] +# name = "Benchmarking" +# url = "http://47.251.95.138:3000/public-dashboards/b75030ae3d0f402ca06b6826de3b590b?orgId=1" + [[languages.en.params.ecosystem.navOptions.items]] + name = "Proxyless Mesh" + url = "/zh-cn/overview/what/core-features/service-mesh/" + [[languages.en.params.ecosystem.navOptions.items]] + name = "More Demos" + url = "https://github.com/apache/dubbo-samples" + + + [languages.zh-cn.params.ecosystem] + navLabel = "生态" + weight = 2 + [[languages.zh-cn.params.ecosystem.navOptions.items]] + name = "代码生成" + url = "https://start.dubbo.apache.org/" + [[languages.zh-cn.params.ecosystem.navOptions.items]] + name = "可视化控制台" + url = "/zh-cn/overview/mannual/control-plane/" +# [[languages.zh-cn.params.ecosystem.navOptions.items]] +# name = "商城系统" +# url = "http://47.251.95.138:3000/public-dashboards/b75030ae3d0f402ca06b6826de3b590b?orgId=1" + [[languages.zh-cn.params.ecosystem.navOptions.items]] + name = "无代理网格" + url = "/zh-cn/overview/what/core-features/service-mesh/" + [[languages.zh-cn.params.ecosystem.navOptions.items]] + name = "更多样例" + url = "https://github.com/apache/dubbo-samples" + [markup] [markup.goldmark] [markup.goldmark.renderer] @@ -97,11 +172,7 @@ algolia_docsearch = true offlineSearch = false -[[menu.main]] - name = "Initializer" - weight = 50 - url = "https://start.dubbo.apache.org/bootstrap.html" - post = "" + #[[menu.main]] # name = "Admin" # weight = 60 @@ -205,6 +276,8 @@ url = "mailto:dev-subscribe@dubbo.apache.org" icon = "fa fa-envelope" desc = "Discuss development issues around the project" + + [sitemap] changefreq = "monthly" filename = "sitemap.xml" diff --git a/content/en/_index.html b/content/en/_index.html index 292cd6a73b65..11956139966c 100644 --- a/content/en/_index.html +++ b/content/en/_index.html @@ -4,99 +4,34 @@ +++ {{< blocks/cover title="Apache Dubbo" image_anchor="top" height="min" color="secondary" >}} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
Get Started!
- - Java - - - Go - - - Rust - - - Node.js - - - Python - - - More... - - -
{{< /blocks/cover >}} {{% blocks/lead color="white" height="min" id="whyDubbo" %}}

Why Dubbo?

- - - - - - {{% /blocks/lead %}} {{< blocks/section id="oceanNodes" >}} {{% blocks/feature image="framework" url="./overview/what/advantages/usability/" %}} -#### [Easy To Use](#), Let Developers Focus On Real Business +#### [Easy To Use](./overview/what/advantages/usability/), Let Developers Focus On Real Business Unified microservice development paradigm with multi-language SDK support. Supporting any protocol from HTTP/2, gRPC, REST, Thrift, to TCP. {{% /blocks/feature %}} {{% blocks/feature image="governance" icon="fas fa-share-alt" url="./overview/what/advantages/traffic-management/" %}} -#### [Service Governance](#), Monitor and Control Cluster In Real-time +#### [Service Governance](./overview/what/advantages/traffic-management/), Monitor and Control Cluster In Real-time Built-in traffic management policies such as service discovery, load balancing, and routing. Rich ecosystem with tracing, circuit break, transaction, logging, metrics, service mesh, and visualized console integrations. {{% /blocks/feature %}} {{% blocks/feature image="performance" icon="fa fa-share-alt" title="Mesh Solution" url="./overview/what/advantages/performance/" %}} -#### [High Performance](#),Designed For Scale +#### [High Performance](./overview/what/advantages/performance/),Designed For Scale Making the Alibaba Global Shopping Festival possible by supporting millions of instances and trillions of calls every year, it's designed as low-latency, high-throughput, and high-scalability in the first place. {{% /blocks/feature %}} {{% blocks/feature image="production" icon="fa fa-share-alt" title="production" url="./overview/what/advantages/extensibility/" %}} -#### [Production Ready](#), Proven Production-stable For Years +#### [Production Ready](./overview/what/advantages/extensibility/), Proven Production-stable For Years Dubbo users has achieved full industry coverage: Commercial Bank of China, Ctrip, Haier, Kingdee, Cloud Vendors like Alibaba Cloud, Tencent Cloud, Huawei Cloud, etc. {{% /blocks/feature %}} @@ -124,59 +59,3 @@

Use-case: Apache Dubbo In Eleme, Alibaba

{{< /blocks/section >}} {{< blocks/dubbo-features >}} - -
-

Follow Us

- -

Subscribe to one or more of the following channels to receive project updates, keep connection with community developers.

- -
-
- - Wechat - - Wechat Channel -

Apache Dubbo

-
-
- - Dingtalk - - DingTalk Channel -

Online community meetings or Bi-weekly!

-
-
- - Twitter - - Twitter ▶ -

#apachedubbo

-

Real-time announcements of blog posts, events, news, ideas.

-
- -
- - GitHub - - GitHub ▶ -

All the project and issue tracking, plus of course code.

-
-
-
- - - - - - - - - - - - - - - - - diff --git a/content/en/blog/_index.md b/content/en/blog/_index.md index 6da132d2497c..e46032b196eb 100644 --- a/content/en/blog/_index.md +++ b/content/en/blog/_index.md @@ -1,6 +1,6 @@ --- title: "Apache Dubbo Blog" -linkTitle: "Blog" +linkTitle: "BLOG" menu: main: weight: 30 diff --git a/content/en/docs3-v2/_index.md b/content/en/docs3-v2/_index.md index d96137280d9e..11f11b8ffcf9 100755 --- a/content/en/docs3-v2/_index.md +++ b/content/en/docs3-v2/_index.md @@ -3,7 +3,7 @@ type: docs title: "SDK Manual" linkTitle: "SDK Manual" hide_summary: true -menu: - main: - weight: 21 +# menu: +# main: +# weight: 21 --- diff --git a/content/en/docs3-v2/java-sdk/advanced-features-and-usage/observability/kubernetes-probes.md b/content/en/docs3-v2/java-sdk/advanced-features-and-usage/observability/kubernetes-probes.md index 0018d215cdaa..9a677e95711c 100644 --- a/content/en/docs3-v2/java-sdk/advanced-features-and-usage/observability/kubernetes-probes.md +++ b/content/en/docs3-v2/java-sdk/advanced-features-and-usage/observability/kubernetes-probes.md @@ -5,4 +5,4 @@ linkTitle: "Kubernetes Probes" weight: 5 no_list: true hide_summary: true ---- \ No newline at end of file +--- diff --git a/content/en/docs3-v2/java-sdk/advanced-features-and-usage/others/dubbo-kubernetes-probe.md b/content/en/docs3-v2/java-sdk/advanced-features-and-usage/others/dubbo-kubernetes-probe.md index 9b612bb8a0a4..838ec3ec36c7 100644 --- a/content/en/docs3-v2/java-sdk/advanced-features-and-usage/others/dubbo-kubernetes-probe.md +++ b/content/en/docs3-v2/java-sdk/advanced-features-and-usage/others/dubbo-kubernetes-probe.md @@ -31,18 +31,18 @@ For an introduction to more extensions of Dubbo3 SPI, see [Dubbo SPI Extensions] For the livenessProbe liveness detection, since the Dubbo3 framework itself cannot obtain the liveness status of the application, this interface has no default implementation and returns success by default. Developers can expand this SPI interface according to the SPI definition, and judge whether it is alive or not from the application level. -About [liveness liveness probe](../../../reference-manual/spi/description/liveness/) extension example +About [liveness liveness probe](/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/liveness/) extension example ### Readiness check For the readinessProbe readiness detection, Dubbo3 currently provides two detection dimensions by default. One is to judge whether the Dubbo3 service itself is started or stopped, and the other is to check whether all services have registered interfaces. If all services have been offline from the registration center (you can Operate via QOS Operations) will return Not Ready. -About the [readiness readiness probe](../../../reference-manual/spi/description/readiness/) extended example +About the [readiness readiness probe](/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/readiness/) extended example ### Start detection For startupProbe startup detection, Dubbo3 currently provides a detection dimension by default, which is to return to the ready state after all startup processes (interface exposure, registration center writing, etc.) are completed. -About the [startup startup probe](../../../reference-manual/spi/description/startup/) extended example +About the [startup startup probe](/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/startup/) extended example ### Reference example ```yaml @@ -67,4 +67,4 @@ startupProbe: ``` > QOS When the computing node detects memory pressure, kuberentes will BestEffort -> Burstable -> Guaranteed to evict Pods in sequence. -At present, all three probes have corresponding interfaces, and the path is the command in QOS. Please modify the port information according to the QOS configuration (the default port is 22222). For other parameters, please refer to [Kubernetes official documentation](https://kubernetes.io/zh/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/). \ No newline at end of file +At present, all three probes have corresponding interfaces, and the path is the command in QOS. Please modify the port information according to the QOS configuration (the default port is 22222). For other parameters, please refer to [Kubernetes official documentation](https://kubernetes.io/zh/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/). diff --git a/content/en/docs3-v2/java-sdk/advanced-features-and-usage/others/logger-howto.md b/content/en/docs3-v2/java-sdk/advanced-features-and-usage/others/logger-howto.md index 95c901a009d0..ffb035af7b75 100644 --- a/content/en/docs3-v2/java-sdk/advanced-features-and-usage/others/logger-howto.md +++ b/content/en/docs3-v2/java-sdk/advanced-features-and-usage/others/logger-howto.md @@ -10,7 +10,7 @@ weight: 7 ## Feature Description -Prior to dubbo 3.3.0-beta.3, dubbo and dubbo-samples were using a mix of log4j and logback, leading to frequent conflicts and errors due to some modules lacking log configuration. Therefore, after 3.3.0-beta.3, the logging components have been upgraded to log4j2 for simplicity and reduced maintenance costs. This document explains how to configure and use the logging framework to avoid conflicts caused by indirectly introducing multiple logging frameworks. +Prior to dubbo 3.3.0, dubbo and dubbo-samples were using a mix of log4j and logback, leading to frequent conflicts and errors due to some modules lacking log configuration. Therefore, after 3.3.0-beta.3, the logging components have been upgraded to log4j2 for simplicity and reduced maintenance costs. This document explains how to configure and use the logging framework to avoid conflicts caused by indirectly introducing multiple logging frameworks. ## How To Use diff --git a/content/en/docs3-v2/java-sdk/advanced-features-and-usage/others/logger-management.md b/content/en/docs3-v2/java-sdk/advanced-features-and-usage/others/logger-management.md index 3e664f9a3bae..cbceac3e78d5 100644 --- a/content/en/docs3-v2/java-sdk/advanced-features-and-usage/others/logger-management.md +++ b/content/en/docs3-v2/java-sdk/advanced-features-and-usage/others/logger-management.md @@ -35,7 +35,7 @@ dubbo.application.logger=log4j ``` -For custom extensions, please refer to [Log Adapter Extension](../../../reference-manual/spi/description/logger-adapter) +For custom extensions, please refer to [Log Adapter Extension](/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/logger-adapter) ## Logging framework runtime management ### 1. Query log configuration @@ -117,4 +117,4 @@ dubbo>switchLogger slf4j OK dubbo>loggerInfo Available logger adapters: [jcl, slf4j, log4j, jdk]. Current Adapter: [slf4j]. Log level: INFO -``` \ No newline at end of file +``` diff --git a/content/en/docs3-v2/java-sdk/advanced-features-and-usage/others/service-container.md b/content/en/docs3-v2/java-sdk/advanced-features-and-usage/others/service-container.md index 724749dae7af..a2df989b7bab 100644 --- a/content/en/docs3-v2/java-sdk/advanced-features-and-usage/others/service-container.md +++ b/content/en/docs3-v2/java-sdk/advanced-features-and-usage/others/service-container.md @@ -11,7 +11,7 @@ The service container of Dubbo 3 is a standalone startup program, because the ba The Dubbo3 service container is just a simple Main method and loads a simple Spring container for exposing services. -The loading content of the service container can be extended, and spring, jetty, log4j, etc. are built-in, and can be extended through [container extension point](../../../reference-manual/spi/description/container). The configuration is configured in the -D parameter of the java command or `dubbo.properties`. +The loading content of the service container can be extended, and spring, jetty, log4j, etc. are built-in, and can be extended through [container extension point](/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/container). The configuration is configured in the -D parameter of the java command or `dubbo.properties`. ## scenes to be used The web container is mainly used to respond to http requests and static pages. The Dubbo service provider only provides dubbo services externally. It is not suitable to use the web container. As a dubbo service provider alone, it only needs to load a simple spring container through a main method Expose the service. @@ -57,4 +57,4 @@ java org.apache.dubbo.container.Main -Ddubbo.container=spring,jetty,log4j Pass in the container to be loaded through `dubbo.properties` configuration under the classpath ```fallback dubbo.container=spring,jetty,log4j -``` \ No newline at end of file +``` diff --git a/content/en/docs3-v2/java-sdk/advanced-features-and-usage/performance/loadbalance.md b/content/en/docs3-v2/java-sdk/advanced-features-and-usage/performance/loadbalance.md index e56624afc648..349b3828b05a 100644 --- a/content/en/docs3-v2/java-sdk/advanced-features-and-usage/performance/loadbalance.md +++ b/content/en/docs3-v2/java-sdk/advanced-features-and-usage/performance/loadbalance.md @@ -10,7 +10,7 @@ When cluster load balancing, Dubbo provides a variety of balancing strategies, t In terms of specific implementation, Dubbo provides client load balancing, that is, the Consumer uses the load balancing algorithm to determine which Provider instance to submit the request to. -You can expand the load balancing strategy by yourself, see: [Load Balance Extension](../../../reference-manual/spi/description/load-balance) +You can expand the load balancing strategy by yourself, see: [Load Balance Extension](/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/load-balance) ## load balancing strategy Currently Dubbo has the following built-in load balancing algorithms, which users can directly configure and use: @@ -102,4 +102,4 @@ Response time here = the average response time of a provider within the window t -``` \ No newline at end of file +``` diff --git a/content/en/docs3-v2/java-sdk/advanced-features-and-usage/performance/profiler.md b/content/en/docs3-v2/java-sdk/advanced-features-and-usage/performance/profiler.md index f61faea1a520..1f39dfb489b3 100644 --- a/content/en/docs3-v2/java-sdk/advanced-features-and-usage/performance/profiler.md +++ b/content/en/docs3-v2/java-sdk/advanced-features-and-usage/performance/profiler.md @@ -20,7 +20,7 @@ Scenarios that need to collect and analyze the precise time consumption of Dubbo ## How to use -`simple profiler` is automatically enabled by default, and for requests whose processing time exceeds 3/4 of the timeout time, the slow call information will be printed out through the log. If you need to enable the `detail profiler` mode or modify the timeout alarm ratio, you can refer to the [performance sampling command](../../../reference-manual/qos/profiler/) document. +`simple profiler` is automatically enabled by default, and for requests whose processing time exceeds 3/4 of the timeout time, the slow call information will be printed out through the log. If you need to enable the `detail profiler` mode or modify the timeout alarm ratio, you can refer to the [performance sampling command](/zh-cn/overview/mannual/java-sdk/reference-manual/qos/profiler/) document. ### output example @@ -186,4 +186,4 @@ Start time: 285965612316294 +-[ Offset: 1.558545ms; Usage: 804.276436ms, 99% ] Receive request. Server biz impl invoke begin., dubbo version: 3.0.10-SNAPSHOT, current host: xx.xx.xx.xx ``` -Note: If the log is empty due to the mismatch of the log framework, you can refer to [Log Framework Adaptation and Runtime Management](../../others/logger-management/) to dynamically modify the log output framework. \ No newline at end of file +Note: If the log is empty due to the mismatch of the log framework, you can refer to [Log Framework Adaptation and Runtime Management](../../others/logger-management/) to dynamically modify the log output framework. diff --git a/content/en/docs3-v2/java-sdk/advanced-features-and-usage/performance/result-cache.md b/content/en/docs3-v2/java-sdk/advanced-features-and-usage/performance/result-cache.md index 208b13ef2643..068bcbc34bfa 100644 --- a/content/en/docs3-v2/java-sdk/advanced-features-and-usage/performance/result-cache.md +++ b/content/en/docs3-v2/java-sdk/advanced-features-and-usage/performance/result-cache.md @@ -13,7 +13,7 @@ description: "Speed up access by caching results" * `threadlocal` The current thread cache, such as a page rendering, uses many portals, and each portal needs to check user information. Through thread caching, this redundant access can be reduced. * `jcache` integrates with [JSR107](http://jcp.org/en/jsr/detail?id=107%27) to bridge various cache implementations. -Cache Type Extensible [Cache Extensions](../../../reference-manual/spi/description/cache) +Cache Type Extensible [Cache Extensions](/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/cache) About [sample code](https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-cache) @@ -33,4 +33,4 @@ or: -``` \ No newline at end of file +``` diff --git a/content/en/docs3-v2/java-sdk/advanced-features-and-usage/performance/router-snapshot.md b/content/en/docs3-v2/java-sdk/advanced-features-and-usage/performance/router-snapshot.md index f82f1b76a39d..9d294101c72b 100644 --- a/content/en/docs3-v2/java-sdk/advanced-features-and-usage/performance/router-snapshot.md +++ b/content/en/docs3-v2/java-sdk/advanced-features-and-usage/performance/router-snapshot.md @@ -17,7 +17,7 @@ Many of Dubbo's traffic management capabilities are implemented based on Router. When Dubbo receives the address change, it will push the address information to all `Routers`, and these `Routers` can calculate the routing packets in advance at this stage and cache them to avoid the need to traverse all provider calculations when calling grouping parameters. The `StateRouter` introduced in Dubbo 3 provides the ability to obtain the status of each route in real time through the qos command tool. -The operation and maintenance personnel can obtain the status of the route through the `getRouterSnapshot` command. For specific commands, please refer to the [getRouterSnapshot command](../../../reference-manual/qos/router-snapshot/#getroutersnapshot-command) document. +The operation and maintenance personnel can obtain the status of the route through the `getRouterSnapshot` command. For specific commands, please refer to the [getRouterSnapshot command](/zh-cn/overview/mannual/java-sdk/reference-manual/qos/router-snapshot/#getroutersnapshot-command) document. **Note: This feature only supports `StateRoute`, and `StateRouter` needs to implement the `doBuildSnapshot` interface based on `AbstractStateRouter`. ** @@ -76,4 +76,4 @@ dubbo> ``` #### Notice: -If the log is empty due to the mismatch of the log framework, you can refer to [Log Framework Adaptation and Runtime Management](../../others/logger-management/) to dynamically modify the log output framework. \ No newline at end of file +If the log is empty due to the mismatch of the log framework, you can refer to [Log Framework Adaptation and Runtime Management](../../others/logger-management/) to dynamically modify the log output framework. diff --git a/content/en/docs3-v2/java-sdk/advanced-features-and-usage/service/context.md b/content/en/docs3-v2/java-sdk/advanced-features-and-usage/service/context.md index 87271baf416e..b84121f0ace9 100644 --- a/content/en/docs3-v2/java-sdk/advanced-features-and-usage/service/context.md +++ b/content/en/docs3-v2/java-sdk/advanced-features-and-usage/service/context.md @@ -6,7 +6,7 @@ weight: 6 description: "Store the environment information required in the current calling process through the context" --- ## Feature description -The context stores the environment information needed in the current calling process. All configuration information will be converted to URL parameters, see the **corresponding URL parameters** column in [schema configuration reference manual](../../../reference-manual/config/properties/). +The context stores the environment information needed in the current calling process. All configuration information will be converted to URL parameters, see the **corresponding URL parameters** column in [schema configuration reference manual](/zh-cn/overview/mannual/java-sdk/reference-manual/config/properties//). RpcContext is a temporary state recorder for ThreadLocal. When RPC requests are received or RPC requests are initiated, the state of RpcContext will change. For example: A tunes B, B then tunes C, then on machine B, before B tunes C, RpcContext records the information of A's tune to B, after B tunes C, RpcContext records the information of B's tune to C. @@ -46,4 +46,4 @@ public class XxxServiceImpl implements XxxService { boolean isProviderSide = RpcContext.getServiceContext().isProviderSide(); } } -``` \ No newline at end of file +``` diff --git a/content/en/docs3-v2/java-sdk/advanced-features-and-usage/service/fault-tolerent-strategy.md b/content/en/docs3-v2/java-sdk/advanced-features-and-usage/service/fault-tolerent-strategy.md index 05bd79f3ba80..e8169c44d409 100644 --- a/content/en/docs3-v2/java-sdk/advanced-features-and-usage/service/fault-tolerent-strategy.md +++ b/content/en/docs3-v2/java-sdk/advanced-features-and-usage/service/fault-tolerent-strategy.md @@ -20,7 +20,7 @@ Each node relationship: ## Cluster fault tolerance mode -You can expand the cluster fault-tolerant strategy by yourself, see: [Cluster Expansion](../../../reference-manual/spi/description/cluster/) +You can expand the cluster fault-tolerant strategy by yourself, see: [Cluster Expansion](/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/cluster/) ### Failover Cluster @@ -134,4 +134,4 @@ or ```xml -``` \ No newline at end of file +``` diff --git a/content/en/docs3-v2/java-sdk/advanced-features-and-usage/service/group-merger.md b/content/en/docs3-v2/java-sdk/advanced-features-and-usage/service/group-merger.md index 3c9772ace082..968b01a6c3ce 100644 --- a/content/en/docs3-v2/java-sdk/advanced-features-and-usage/service/group-merger.md +++ b/content/en/docs3-v2/java-sdk/advanced-features-and-usage/service/group-merger.md @@ -48,7 +48,7 @@ One method does not combine results, others combine results ``` ### Specify merge strategy -Specify the merge strategy, the default is to automatically match according to the return value type, if there are two combiners of the same type, you need to specify the name of the combiner [Merge result extension](../../../reference-manual/spi/ description/merger) +Specify the merge strategy, the default is to automatically match according to the return value type, if there are two combiners of the same type, you need to specify the name of the combiner [Merge result extension](/zh-cn/overview/mannual/java-sdk/reference-manual/spi/ description/merger) ```xml @@ -66,4 +66,4 @@ Specify the merge method to merge the specified method that returns the result o ``` #### hint: -Supported since `2.1.0` version \ No newline at end of file +Supported since `2.1.0` version diff --git a/content/en/docs3-v2/java-sdk/advanced-features-and-usage/service/multi-registry.md b/content/en/docs3-v2/java-sdk/advanced-features-and-usage/service/multi-registry.md index f5464bf998dc..7f3d0ec1583a 100644 --- a/content/en/docs3-v2/java-sdk/advanced-features-and-usage/service/multi-registry.md +++ b/content/en/docs3-v2/java-sdk/advanced-features-and-usage/service/multi-registry.md @@ -84,4 +84,4 @@ If only the test environment temporarily needs to connect to two different regis ``` -[^1]: You can extend the registry by yourself, see: [Registry Extension](../../../reference-manual/spi/description/registry) \ No newline at end of file +[^1]: You can extend the registry by yourself, see: [Registry Extension](/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/registry) diff --git a/content/en/docs3-v2/java-sdk/advanced-features-and-usage/service/parameter-validation.md b/content/en/docs3-v2/java-sdk/advanced-features-and-usage/service/parameter-validation.md index 04dfb2414803..b32956df1aa7 100644 --- a/content/en/docs3-v2/java-sdk/advanced-features-and-usage/service/parameter-validation.md +++ b/content/en/docs3-v2/java-sdk/advanced-features-and-usage/service/parameter-validation.md @@ -193,4 +193,4 @@ public class ValidationConsumer { } ``` -> **The validation method can be extended, see [Validation Extension](../../../reference-manual/spi/description/validation) in the developer manual for the extension method** \ No newline at end of file +> **The validation method can be extended, see [Validation Extension](/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/validation) in the developer manual for the extension method** diff --git a/content/en/docs3-v2/java-sdk/faq/0/1.md b/content/en/docs3-v2/java-sdk/faq/0/1.md index c2d3a7982be6..c6726dcefb9a 100644 --- a/content/en/docs3-v2/java-sdk/faq/0/1.md +++ b/content/en/docs3-v2/java-sdk/faq/0/1.md @@ -19,4 +19,4 @@ By default, the number of business threads on the Dubbo server is 200. If the nu > The FAQ page of this error code refers to ["Dubbo Common Errors and Solutions"](https://github.com/StabilityMan/StabilityGuide/blob/master/docs/diagnosis/plugin/rpc/%E7%B3%BB%E7%BB%9F%E7%A8%B3%E5%AE%9A%E6%80%A7%E2%80%94%E2%80%94Dubbo%E5%B8%B8%E8%A7%81%E9%94%99%E8%AF%AF%E5%8F%8A%E8%A7%A3%E5%86%B3%E6%96%B9%E6%B3%95.md). -Articles cited are compiled under license [CC-BY-4.0](http://creativecommons.org/licenses/by/4.0/). Thanks to the original author here. \ No newline at end of file +Articles cited are compiled under license [CC-BY-4.0](http://creativecommons.org/licenses/by/4.0/). Thanks to the original author here. diff --git a/content/en/docs3-v2/java-sdk/faq/0/13.md b/content/en/docs3-v2/java-sdk/faq/0/13.md index 27d0ebd2b3b9..80f394792cd4 100644 --- a/content/en/docs3-v2/java-sdk/faq/0/13.md +++ b/content/en/docs3-v2/java-sdk/faq/0/13.md @@ -12,6 +12,6 @@ An error occurred during the push process of the indicator data, the pushed serv ### Troubleshooting and resolution steps -Please refer to the configuration item reference manual[configuration item reference manual](/en/docs3-v2/java-sdk/reference-manual/config/properties/#metrics). +Please refer to the configuration item reference manual[configuration item reference manual](/en/docs3-v2/java-sdk/reference-manual/config/properties/). -

\ No newline at end of file +

diff --git a/content/en/docs3-v2/java-sdk/faq/0/2.md b/content/en/docs3-v2/java-sdk/faq/0/2.md index db74f760a3cf..90b7d0fc07df 100644 --- a/content/en/docs3-v2/java-sdk/faq/0/2.md +++ b/content/en/docs3-v2/java-sdk/faq/0/2.md @@ -9,6 +9,6 @@ weight: 2 This hint means that the value configured by the user does not match the data type required by the attribute itself. For example, the `dubbo.comsumer.threads` attribute can only accept numeric attributes, but the value entered by the user is mixed with letters. ### Troubleshooting and resolution steps -According to the [Configuration Item Reference Manual](../../../reference-manual/config/properties), find the wrong configuration item, check the type specified by the item, and check whether there is a type inconsistency. +According to the [Configuration Item Reference Manual](/zh-cn/overview/mannual/java-sdk/reference-manual/config/properties/), find the wrong configuration item, check the type specified by the item, and check whether there is a type inconsistency. -

\ No newline at end of file +

diff --git a/content/en/docs3-v2/java-sdk/faq/1/12.md b/content/en/docs3-v2/java-sdk/faq/1/12.md index c2b858900999..793be1778810 100644 --- a/content/en/docs3-v2/java-sdk/faq/1/12.md +++ b/content/en/docs3-v2/java-sdk/faq/1/12.md @@ -12,4 +12,4 @@ During the process of destroying the `unexport` of `Registryprotocol`, the `getR ### Troubleshooting and resolution steps > see also -[Configuration item reference manual](../../../reference-manual/config/properties) \ No newline at end of file +[Configuration item reference manual](/zh-cn/overview/mannual/java-sdk/reference-manual/config/properties/) diff --git a/content/en/docs3-v2/java-sdk/faq/1/14.md b/content/en/docs3-v2/java-sdk/faq/1/14.md index 5188e6e4d444..7bbb3b7af609 100644 --- a/content/en/docs3-v2/java-sdk/faq/1/14.md +++ b/content/en/docs3-v2/java-sdk/faq/1/14.md @@ -12,4 +12,4 @@ Please check whether the content or format of the dynamic configuration file is ### See also -> [Configuration Reference Manual](../../../reference-manual/config/properties) \ No newline at end of file +> [Configuration Reference Manual](/zh-cn/overview/mannual/java-sdk/reference-manual/config/properties/) diff --git a/content/en/docs3-v2/java-sdk/faq/1/17.md b/content/en/docs3-v2/java-sdk/faq/1/17.md index e89c456f07df..e625f0cfc874 100644 --- a/content/en/docs3-v2/java-sdk/faq/1/17.md +++ b/content/en/docs3-v2/java-sdk/faq/1/17.md @@ -13,6 +13,6 @@ It may be that there is a problem with the parameter configuration of metadata, 2. Check whether the `metadataServicePort` port number conflicts. If the ports configured by Provider and Consumer are in conflict at the same time, a 1-17 error will be generated. ## see also -[Configuration item reference manual](../../../reference-manual/config/properties) +[Configuration item reference manual](/zh-cn/overview/mannual/java-sdk/reference-manual/config/properties/) -

\ No newline at end of file +

diff --git a/content/en/docs3-v2/java-sdk/faq/1/18.md b/content/en/docs3-v2/java-sdk/faq/1/18.md index ad70f24f74c6..b81501e92489 100644 --- a/content/en/docs3-v2/java-sdk/faq/1/18.md +++ b/content/en/docs3-v2/java-sdk/faq/1/18.md @@ -13,6 +13,6 @@ It may be that `metadataType` is in local mode, and `metadataServicePort` is con 2. Check whether the configuration of `metadataServicePort` on the Provider side is correct, and pay special attention to whether there is any conflict with other application ports. ## see also -[Configuration item reference manual](../../../reference-manual/config/properties) +[Configuration item reference manual](/zh-cn/overview/mannual/java-sdk/reference-manual/config/properties/) -

\ No newline at end of file +

diff --git a/content/en/docs3-v2/java-sdk/faq/1/3.md b/content/en/docs3-v2/java-sdk/faq/1/3.md index 9f5491e21777..bd71505ee1ff 100644 --- a/content/en/docs3-v2/java-sdk/faq/1/3.md +++ b/content/en/docs3-v2/java-sdk/faq/1/3.md @@ -10,4 +10,4 @@ When `FrameworkExecutorRepository` is destroyed, calling `CacheableFailbackRegis ### Troubleshooting and resolution steps -> See also the [Configuration Items Reference Manual](../../../reference-manual/config/properties) \ No newline at end of file +> See also the [Configuration Items Reference Manual](/zh-cn/overview/mannual/java-sdk/reference-manual/config/properties/) diff --git a/content/en/docs3-v2/java-sdk/faq/1/4.md b/content/en/docs3-v2/java-sdk/faq/1/4.md index e2f200cc84ab..2288b3210e38 100644 --- a/content/en/docs3-v2/java-sdk/faq/1/4.md +++ b/content/en/docs3-v2/java-sdk/faq/1/4.md @@ -15,4 +15,4 @@ weight: 4 3. Check whether `enable-empty-protection` of the registration center is true (the default is true). > see also -[Configuration item reference manual](../../../reference-manual/config/properties) \ No newline at end of file +[Configuration item reference manual](/zh-cn/overview/mannual/java-sdk/reference-manual/config/properties/) diff --git a/content/en/docs3-v2/java-sdk/faq/1/8.md b/content/en/docs3-v2/java-sdk/faq/1/8.md index 20f1150bc3ac..98b866944ff3 100644 --- a/content/en/docs3-v2/java-sdk/faq/1/8.md +++ b/content/en/docs3-v2/java-sdk/faq/1/8.md @@ -15,4 +15,4 @@ weight: 8 3. Check whether the provider’s registry-related parameters such as `registry` `config-center` `metadata-report` are configured correctly. > see also -[Configuration item reference manual](../../../reference-manual/config/properties) \ No newline at end of file +[Configuration item reference manual](/zh-cn/overview/mannual/java-sdk/reference-manual/config/properties/) diff --git a/content/en/docs3-v2/java-sdk/reference-manual/protocol/http.md b/content/en/docs3-v2/java-sdk/reference-manual/protocol/http.md index 53433653774f..bb943f4e0e39 100644 --- a/content/en/docs3-v2/java-sdk/reference-manual/protocol/http.md +++ b/content/en/docs3-v2/java-sdk/reference-manual/protocol/http.md @@ -6,6 +6,11 @@ weight: 6 --- +{{% alert title="Note" color="warning" %}} +Since Dubbo 3.3, the rest protocol has been moved to the extensions library, with the triple protocol now providing more comprehensive support for Rest. For details refer to [Triple Rest User Manual](../../tripe-rest-manual/). +If you wish to continue using the original rest protocol, please include the corresponding [dubbo-spi-extensions](https://github.com/apache/dubbo-spi-extensions/tree/master/dubbo-rpc-extensions/dubbo-rpc-rest) dependency. +{{% /alert %}} + ## Feature description HTTP form-based remote invocation protocol, implemented by Spring's HttpInvoker, supported by versions above `2.3.0`. diff --git a/content/en/docs3-v2/java-sdk/reference-manual/protocol/rest.md b/content/en/docs3-v2/java-sdk/reference-manual/protocol/rest.md index e20537a33ba7..d9acddd826a2 100644 --- a/content/en/docs3-v2/java-sdk/reference-manual/protocol/rest.md +++ b/content/en/docs3-v2/java-sdk/reference-manual/protocol/rest.md @@ -5,6 +5,11 @@ linkTitle: "Rest protocol" weight: 4 --- +{{% alert title="Note" color="warning" %}} +Since Dubbo 3.3, the rest protocol has been moved to the extensions library, with the triple protocol now providing more comprehensive support for Rest. For details refer to [Triple Rest User Manual](../../tripe-rest-manual/). +If you wish to continue using the original rest protocol, please include the corresponding [dubbo-spi-extensions](https://github.com/apache/dubbo-spi-extensions/tree/master/dubbo-rpc-extensions/dubbo-rpc-rest) dependency. +{{% /alert %}} + Support for REST calls based on the standard Java REST API - JAX-RS 2.0 (short for Java API for RESTful Web Services) ### Quick Start diff --git a/content/en/docs3-v2/java-sdk/reference-manual/protocol/tripe-3.3.md b/content/en/docs3-v2/java-sdk/reference-manual/protocol/tripe-3.3.md new file mode 100644 index 000000000000..d87aa6e3de69 --- /dev/null +++ b/content/en/docs3-v2/java-sdk/reference-manual/protocol/tripe-3.3.md @@ -0,0 +1,282 @@ +--- +type: docs +title: "Tripe 3.3 New Features" +linkTitle: "Tripe 3.3 New Features" +weight: 13 +--- + + + +## New Rest Support + +### Rest Features + +Since Dubbo 3.3, the Triple protocol reuses the existing HTTP stack to fully support RESTful service exports. Without the need for generic or gateway protocol conversion, users can +directly access backend Triple protocol services via HTTP in a decentralized manner. Additionally, it offers extensive annotation and SPI extension support for advanced REST usage, +such as path customization, output format customization, and exception handling. Key features include: + +- **Triple Protocol Integration** + Reuses the existing Triple HTTP stack, allowing support for HTTP/1, HTTP/2, and HTTP/3 without additional configuration or new ports. +- **Decentralization** + Exposes Rest APIs directly, eliminating dependency on gateway applications for traffic forwarding, thus improving performance and reducing stability risks caused by gateways. + Security concerns can be addressed through internal application extensions, a practice verified in Taobao’s MTOP. +- **Support for Existing Servlet Infrastructure** + Supports Servlet API and Filter, allowing users to reuse existing security components based on the Servlet API. Integrating OAuth and Spring Security is as simple as implementing + a Servlet Filter. +- **Multiple Dialects** + Considering that most users are accustomed to using SpringMVC or JAX-RS for REST API development, Triple Rest allows continued use of these methods for service definitions and + supports most extensions and exception handling mechanisms (with over 80% of the original framework’s functionality). For lightweight users, the Basic dialect is available, and + Triple’s out-of-the-box REST capabilities are based on this dialect. +- **High Extensibility** + Offers more than 20 extension points, enabling users to easily create custom dialects and flexibly customize parameter retrieval, type conversion, error handling, and other + logic. +- **Out-of-the-Box** + REST capabilities are available out of the box; simply enable the Triple protocol to have direct REST access to services. +- **High-Performance Routing** + The routing component uses an + optimized [Radix Tree](https://github.com/apache/dubbo/blob/3.3/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/mapping/RadixTree.java) and Zero + Copy technology to improve routing performance. +- **Seamless OpenAPI Integration (TBD)** + Upcoming OpenAPI integration will allow for out-of-the-box OpenAPI Schema export. With the Swagger dependency, a Web UI can be used for service testing. Using the OpenAPI Schema, + API tools like [Postman](https://www.postman.com/) and [Apifox](https://apifox.com/) can manage and test APIs, and the OpenAPI ecosystem can facilitate cross-language calls. + Future enhancements will support a Schema First approach, allowing frontend teams to define OpenAPI collaboratively, generate call code and mocks based on OpenAPI, and enable + backend development using stubs generated from OpenAPI, greatly improving collaboration efficiency. + + + +### Example + + + +###### Sample Code + +```java +package org.apache.dubbo.rest.demo; + +import org.apache.dubbo.remoting.http12.rest.Mapping; +import org.apache.dubbo.remoting.http12.rest.Param; + +// Service Interface +public interface DemoService { + String hello(String name); + + @Mapping(path = "/hi", method = HttpMethods.POST) + String hello(User user, @Param(value = "c", type = ParamType.Header) int count); +} + +// Service Implementation +@DubboService +public class DemoServiceImpl implements DemoService { + @Override + public String hello(String name) { + return "Hello " + name; + } + + @Override + public String hello(User user, int count) { + return "Hello " + user.getTitle() + ". " + user.getName() + ", " + count; + } +} + +// Model +@Data +public class User { + private String title; + private String name; +} +``` + + + +###### Download and Run Example + +```bash +# Get the example code +git clone --depth=1 https://github.com/apache/dubbo-samples.git +cd dubbo-samples/2-advanced/dubbo-samples-triple-rest/dubbo-samples-triple-rest-basic +# Run +mvn spring-boot:run +``` + + + +###### Curl Test + +```bash +curl -v "http://127.0.0.1:8081/org.apache.dubbo.rest.demo.DemoService/hello?name=world" +# Output +#> GET /org.apache.dubbo.rest.demo.DemoService/hello?name=world HTTP/1.1 +#> +#< HTTP/1.1 200 OK +#< content-type: application/json +#< content-length: 13 +#< +#"Hello world" +# +# Explanation +# The output shows "Hello world", with quotes because the default content-type is application/json. +# This example shows that Triple exports services to the /{serviceInterface}/{methodName} path by default, supporting parameter passing via URL. + +curl -v -H "c: 3" -d 'name=Yang' "http://127.0.0.1:8081/org.apache.dubbo.rest.demo.DemoService/hi.txt?title=Mr" +# Output +#> POST /org.apache.dubbo.rest.demo.DemoService/hi.txt?title=Mr HTTP/1.1 +#> c: 3 +#> Content-Length: 9 +#> Content-Type: application/x-www-form-urlencoded +#> +#< HTTP/1.1 200 OK +#< content-type: text/plain +#< content-length: 17 +#< +#Hello Mr. Yang, 3 +# +# Explanation +# The output shows "Hello Mr. Yang, 3", without quotes because the output was specified as text/plain by using the txt suffix. +# This example shows how to customize paths using the Mapping annotation and customize parameter sources using the Param annotation, supporting parameter passing via post body or URL. +``` + + + +### Documentation + +Please visit the user manual: [Triple Rest Manual](../triple-rest-manual/) + + +## Support for Servlet Integration + +In version 3.3, you can reuse existing Spring Boot servlet listening ports to handle HTTP traffic, eliminating the need for Netty to listen on new ports. This simplifies deployment +and reduces maintenance costs. By reducing reliance on external ports, it helps to easily pass through enterprise firewalls and gateways, simplifying network deployment and +enhancing the maintainability and security of enterprise applications. + + +### Example + + + +###### Download and Run Example + +```bash +# Get the sample code +git clone --depth=1 https://github.com/apache/dubbo-samples.git +cd dubbo-samples/2-advanced/dubbo-samples-triple-servlet +# Run directly +mvn spring-boot:run +``` + + + +###### Curl Test + +```shell +curl --http2-prior-knowledge -v 'http://localhost:50052/org.apache.dubbo.demo.GreeterService/sayHelloAsync?request=world' +# Output +#* [HTTP/2] [1] OPENED stream for http://localhost:50052/org.apache.dubbo.demo.GreeterService/sayHelloAsync?request=world +#* [HTTP/2] [1] [:method: GET] +#* [HTTP/2] [1] [:scheme: http] +#* [HTTP/2] [1] [:authority: localhost:50052] +#* [HTTP/2] [1] [:path: /org.apache.dubbo.demo.GreeterService/sayHelloAsync?request=world] +#> +#* Request completely sent off +#< HTTP/2 200 +#< content-type: application/json +#< date: Sun, 25 Aug 2024 03:38:12 GMT +#< +#"Hello world" +``` + + + +### Documentation + +Please +visit: [how-to-enable-servlet-support-for-triple](https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-triple-servlet#how-to-enable-servlet-support-for-triple) +to learn how to configure and enable servlet support. + + +## Support for HTTP/3 Protocol + + + +### HTTP/3 Features + +In version 3.3, Triple implements support for the HTTP/3 protocol, allowing RPC and REST requests to be transmitted via HTTP/3. Using HTTP/3 offers the following benefits: + +- **Enhanced Performance** + With HTTP/3 support, the use of the QUIC protocol reduces latency and accelerates request-response times. This significantly boosts overall service + performance, especially in high-latency or complex network environments. +- **Improved Reliability** + HTTP/3 leverages multiplexing and connection migration to avoid head-of-line blocking, maintaining stable connections even under poor network conditions + and ensuring reliable service delivery. +- **Increased Security** + HTTP/3 enforces TLS 1.3 encryption, providing a more secure communication channel compared to the optional encryption in traditional HTTP/2. +- **Better Adaptation to Weak Networks** + In scenarios with high packet loss or unstable bandwidth, HTTP/3 maintains high connection quality and service performance, improving + outcomes in weak network environments. + +Since HTTP/3 is based on the QUIC protocol (UDP), it might be blocked by firewalls or gateways. To mitigate this, Triple has implemented HTTP/3 negotiation capabilities and enabled +it by default. Connections are initially established via HTTP/2, and if the server responds with an [Alt-Svc](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Alt-Svc) +header indicating HTTP/3 support, the client will automatically switch to HTTP/3. + + +### Example + + + +###### Download and Run Example + +```bash +# Get the sample code +git clone --depth=1 https://github.com/apache/dubbo-samples.git +cd dubbo-samples/2-advanced/dubbo-samples-triple-http3 +# Run directly +mvn spring-boot:run +``` + + + +###### Testing with Curl + +Note that Curl must be upgraded to a version that supports HTTP/3. Refer to: [https://curl.se/docs/http3.html](https://curl.se/docs/http3.html). + +```shell + +curl --http3 -vk 'https://localhost:50052/org.apache.dubbo.demo.GreeterService/sayHelloAsync?request=world' +# Output +#* QUIC cipher selection: TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_CCM_SHA256 +#* Skipped certificate verification +#* using HTTP/3 +#* [HTTP/3] [0] OPENED stream for https://localhost:50052/org.apache.dubbo.demo.GreeterService/sayHelloAsync?request=world +#* [HTTP/3] [0] [:method: GET] +#* [HTTP/3] [0] [:scheme: https] +#* [HTTP/3] [0] [:authority: localhost:50052] +#* [HTTP/3] [0] [:path: /org.apache.dubbo.demo.GreeterService/sayHelloAsync?request=world] +#> +#* Request completely sent off +#< HTTP/3 200 +#< content-type: application/json +#< +#"Hello world" +``` + + + +### Performance Comparison + +#### Impact of Packet Loss on QPS + +![http3-qps.jpg](/imgs/v3/manual/java/protocol/http3-qps.jpg) + +#### Impact of Packet Loss on RT + +![http3-rt.jpg](/imgs/v3/manual/java/protocol/http3-rt.jpg) + + + +### Architecture Diagram + +![http3-arch.jpg](/imgs/v3/manual/java/protocol/http3-arch.jpg) + +### Documentation + +For information on how to configure and enable HTTP/3 support, please +visit: [how-to-enable-http3-support-for-triple](https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-triple-http3#how-to-enable-http3-support-for-triple). diff --git a/content/en/docs3-v2/java-sdk/reference-manual/protocol/tripe-rest-manual.md b/content/en/docs3-v2/java-sdk/reference-manual/protocol/tripe-rest-manual.md new file mode 100644 index 000000000000..d7fd5125944b --- /dev/null +++ b/content/en/docs3-v2/java-sdk/reference-manual/protocol/tripe-rest-manual.md @@ -0,0 +1,984 @@ +--- +linkTitle: Triple Rest User Manual +title: Triple Rest User Manual +type: docs +weight: 14 +--- + +{{% alert title="Note" color="warning" %}} +Since Dubbo 3.3, the original Rest protocol has been moved to the Extensions library, and the Triple protocol now provides more comprehensive support for Rest. To continue using +the original Rest protocol, you can add the corresponding [dubbo-spi-extensions](https://github.com/apache/dubbo-spi-extensions/tree/master/dubbo-rpc-extensions/dubbo-rpc-rest) +library dependency. +{{% /alert %}} + +## Introduction + +Since Dubbo 3.3, the Triple protocol reuses the existing HTTP stack to fully support RESTful service exports. Without the need for generic or gateway protocol conversion, users can +directly access backend Triple protocol services via HTTP in a decentralized manner. Additionally, it offers extensive annotation and SPI extension support for advanced REST usage, +such as path customization, output format customization, and exception handling. Key features include: + +- **Triple Protocol Integration** + Reuses the existing Triple HTTP stack, allowing support for HTTP/1, HTTP/2, and HTTP/3 without additional configuration or new ports. +- **Decentralization** + Exposes Rest APIs directly, eliminating dependency on gateway applications for traffic forwarding, thus improving performance and reducing stability risks caused by gateways. + Security concerns can be addressed through internal application extensions, a practice verified in Taobao’s MTOP. +- **Support for Existing Servlet Infrastructure** + Supports Servlet API and Filter, allowing users to reuse existing security components based on the Servlet API. Integrating OAuth and Spring Security is as simple as implementing + a Servlet Filter. +- **Multiple Dialects** + Considering that most users are accustomed to using SpringMVC or JAX-RS for REST API development, Triple Rest allows continued use of these methods for service definitions and + supports most extensions and exception handling mechanisms (with over 80% of the original framework’s functionality). For lightweight users, the Basic dialect is available, and + Triple’s out-of-the-box REST capabilities are based on this dialect. +- **High Extensibility** + Offers more than 20 extension points, enabling users to easily create custom dialects and flexibly customize parameter retrieval, type conversion, error handling, and other + logic. +- **Out-of-the-Box** + REST capabilities are available out of the box; simply enable the Triple protocol to have direct REST access to services. +- **High-Performance Routing** + The routing component uses an + optimized [Radix Tree](https://github.com/apache/dubbo/blob/3.3/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/mapping/RadixTree.java) and Zero + Copy technology to improve routing performance. +- **Seamless OpenAPI Integration (TBD)** + Upcoming OpenAPI integration will allow for out-of-the-box OpenAPI Schema export. With the Swagger dependency, a Web UI can be used for service testing. Using the OpenAPI Schema, + API tools like [Postman](https://www.postman.com/) and [Apifox](https://apifox.com/) can manage and test APIs, and the OpenAPI ecosystem can facilitate cross-language calls. + Future enhancements will support a Schema First approach, allowing frontend teams to define OpenAPI collaboratively, generate call code and mocks based on OpenAPI, and enable + backend development using stubs generated from OpenAPI, greatly improving collaboration efficiency. + + +## Quick Start + +Let's explore Triple Rest with a simple example. You can directly download the existing sample project to get started quickly. Assume you have Java, Maven, and Git installed. + +### Download and Run the Example + +```bash +# Get the sample code +git clone --depth=1 https://github.com/apache/dubbo-samples.git +cd dubbo-samples/2-advanced/dubbo-samples-triple-rest/dubbo-samples-triple-rest-basic +# Run directly +mvn spring-boot:run +# Or package and run +mvn clean package -DskipTests +java -jar target/dubbo-samples-triple-rest-basic-1.0.0-SNAPSHOT.jar +``` + +Alternatively, you can import the project into your IDE and directly execute `org.apache.dubbo.rest.demo.BasicRestApplication#main` to run it. You can also debug by setting +breakpoints to deeply understand the principles. + +### Example Code + +```java +// Service Interface +package org.apache.dubbo.rest.demo; + +import org.apache.dubbo.remoting.http12.rest.Mapping; +import org.apache.dubbo.remoting.http12.rest.Param; + +public interface DemoService { + String hello(String name); + + @Mapping(path = "/hi", method = HttpMethods.POST) + String hello(User user, @Param(value = "c", type = ParamType.Header) int count); +} + +// Service Implementation +@DubboService +public class DemoServiceImpl implements DemoService { + @Override + public String hello(String name) { + return "Hello " + name; + } + + @Override + public String hello(User user, int count) { + return "Hello " + user.getTitle() + ". " + user.getName() + ", " + count; + } +} + +// Model +@Data +public class User { + private String title; + private String name; +} +``` + + + +### Test the Basic Service + +```bash +curl -v "http://127.0.0.1:8081/org.apache.dubbo.rest.demo.DemoService/hello?name=world" +# Output: +#> GET /org.apache.dubbo.rest.demo.DemoService/hello?name=world HTTP/1.1 +#> Host: 127.0.0.1:8081 +#> User-Agent: curl/8.7.1 +#> Accept: */* +#> +#* Request completely sent off +#< HTTP/1.1 200 OK +#< content-type: application/json +#< alt-svc: h2=":8081" +#< content-length: 13 +#< +#"Hello world" +``` + +Explanation:
You see the output `"Hello world"`. The quotes are because the default content-type is `application/json`. This example demonstrates how Triple exports services +to the `/{serviceInterface}/{methodName}` path by default and supports passing parameters via URL. + + +### Test the Advanced Service + +```bash +curl -v -H "c: 3" -d 'name=Yang' "http://127.0.0.1:8081/org.apache.dubbo.rest.demo.DemoService/hi.txt?title=Mr" +# Output: +#> POST /org.apache.dubbo.rest.demo.DemoService/hi.txt?title=Mr HTTP/1.1 +#> Host: 127.0.0.1:8081 +#> User-Agent: curl/8.7.1 +#> Accept: */* +#> c: 3 +#> Content-Length: 9 +#> Content-Type: application/x-www-form-urlencoded +#> +#* upload completely sent off: 9 bytes +#< HTTP/1.1 200 OK +#< content-type: text/plain +#< alt-svc: h2=":8081" +#< content-length: 17 +#< +#Hello Mr. Yang, 3 +``` + +Explanation:
The output `"Hello Mr. Yang, 3"` has no quotes because the `.txt` suffix was specified to request `text/plain` output. This example shows how to customize paths +using the `Mapping` annotation, customize parameter sources with the `Param` annotation, and pass parameters via post body or URL. For more details, see +the [Basic Usage Guide](#GdlnC) + + +### Observe Logs + +Enable debug logging to understand the rest startup and request response process: + +```yaml +logging: + level: + "org.apache.dubbo.rpc.protocol.tri": debug + "org.apache.dubbo.remoting": debug +``` + +Once enabled, you can observe the Rest mapping registration and request process: + +``` +# Register mapping +DEBUG o.a.d.r.p.t.TripleProtocol : [DUBBO] Register triple grpc mapping: 'org.apache.dubbo.rest.demo.DemoService' -> invoker[tri://192.168.2.216:8081/org.apache.dubbo.rest.demo.DemoService] + INFO .r.p.t.r.m.DefaultRequestMappingRegistry : [DUBBO] BasicRequestMappingResolver resolving rest mappings for ServiceMeta{interface=org.apache.dubbo.rest.demo.DemoService, service=DemoServiceImpl@2a8f6e6} at url [tri://192.168.2.216:8081/org.apache.dubbo.rest.demo.DemoService] +DEBUG .r.p.t.r.m.DefaultRequestMappingRegistry : [DUBBO] Register rest mapping: '/org.apache.dubbo.rest.demo.DemoService/hi' -> mapping=RequestMapping{name='DemoServiceImpl#hello', path=PathCondition{paths=[org.apache.dubbo.rest.demo.DemoService/hi]}, methods=MethodsCondition{methods=[POST]}}, method=MethodMeta{method=org.apache.dubbo.rest.demo.DemoService.hello(User, int), service=DemoServiceImpl@2a8f6e6} +DEBUG .r.p.t.r.m.DefaultRequestMappingRegistry : [DUBBO] Register rest mapping: '/org.apache.dubbo.rest.demo.DemoService/hello' -> mapping=RequestMapping{name='DemoServiceImpl#hello~S', path=PathCondition{paths=[org.apache.dubbo.rest.demo.DemoService/hello]}}, method=MethodMeta{method=org.apache.dubbo.rest.demo.DemoService.hello(String), service=DemoServiceImpl@2a8f6e6} + INFO .r.p.t.r.m.DefaultRequestMappingRegistry : [DUBBO] Registered 2 REST mappings for service [DemoServiceImpl@44627686] at url [tri://192.168.2.216:8081/org.apache.dubbo.rest.demo.DemoService] in 11ms + +# 请求响应 +DEBUG .a.d.r.p.t.r.m.RestRequestHandlerMapping : [DUBBO] Received http request: DefaultHttpRequest{method='POST', uri='/org.apache.dubbo.rest.demo.DemoService/hi.txt?title=Mr', contentType='application/x-www-form-urlencoded'} +DEBUG .r.p.t.r.m.DefaultRequestMappingRegistry : [DUBBO] Matched rest mapping=RequestMapping{name='DemoServiceImpl#hello', path=PathCondition{paths=[/org.apache.dubbo.rest.demo.DemoService/hi]}, methods=MethodsCondition{methods=[POST]}}, method=MethodMeta{method=org.apache.dubbo.rest.demo.DemoService.hello(User, int), service=DemoServiceImpl@2a8f6e6} +DEBUG .a.d.r.p.t.r.m.RestRequestHandlerMapping : [DUBBO] Content-type negotiate result: request='application/x-www-form-urlencoded', response='text/plain' +DEBUG .d.r.h.AbstractServerHttpChannelObserver : [DUBBO] Http response body is: '"Hello Mr. Yang, 3"' +DEBUG .d.r.h.AbstractServerHttpChannelObserver : [DUBBO] Http response headers sent: {:status=[200], content-type=[text/plain], alt-svc=[h2=":8081"], content-length=[17]} +``` + + + +## General Features + + + +### Path Mapping + +The Triple protocol is compatible with both SpringMVC and JAX-RS mapping methods. For more information, refer to: + +- [Spring Mapping Requests](https://docs.spring.io/spring-framework/reference/web/webmvc/mvc-controller/ann-requestmapping.html#mvc-ann-requestmapping-uri-templates) +- [Spring PathPattern](https://docs.spring.io/spring-framework/docs/6.1.12/javadoc-api/org/springframework/web/util/pattern/PathPattern.html) +- [Spring AntPathMatcher](https://docs.spring.io/spring-framework/docs/6.1.12/javadoc-api/org/springframework/util/AntPathMatcher.html) +- [JAX-RS Path and regular expression mappings](https://docs.jboss.org/resteasy/docs/6.2.7.Final/userguide/html/ch04.html) + +You can also customize path mapping by implementing the SPI `org.apache.dubbo.rpc.protocol.tri.rest.mapping.RequestMappingResolver`. + + +#### Supported Patterns + +1. `books`: A string constant matching a fixed segment. +2. `?`: Matches a single character. +3. `*`: Matches zero or more characters within a path segment. +4. `**`: Matches zero or more path segments until the end of the path. +5. `{spring}`: Matches a path segment and captures it as a variable named "spring." +6. `{spring:[a-z]+}`: Uses a regular expression `[a-z]+` to match a path segment and captures it as a variable named "spring." +7. `{*spring}`: Matches zero or more path segments until the end of the path and captures them as a variable named "spring." `{*}` without a variable name indicates that no + capturing is done. + + +#### Examples (from Spring Documentation) + +- `/pages/t?st.html`: Matches `/pages/test.html` and `/pages/tXst.html`, but not `/pages/toast.html`. +- `/resources/*.png`: Matches all `.png` files in the `resources` directory. +- `com/**/test.jsp`: Matches all `test.jsp` files under the `com` path. +- `org/springframework/**/*.jsp`: Matches all `.jsp` files under the `org/springframework` path. +- `/resources/**`: Matches all files under the `/resources/` path, including `/resources/image.png` and `/resources/css/spring.css`. +- `/resources/{*path}`: Matches all files under `/resources/` as well as `/resources` itself, capturing the relative path as the variable "path." For example, + `/resources/image.png` would map to "path" → "/image.png", and `/resources/css/spring.css` would map to "path" → "/css/spring.css". +- `/resources/{filename:\\w+}.dat`: Matches `/resources/spring.dat` and assigns the value "spring" to the `filename` variable. +- `/{name:[a-z-]+}-{version:\\d\\.\\d\\.\\d}{ext:\\.[a-z]+}`: Matches `/example-2.1.5.html`, with `name` as `example`, `version` as `2.1.5`, and `ext` as `.html`. + +Tip: If you do not want the regular expression to span multiple segments, use `{name:[^/]+}`. + + +#### Full Mapping Process + +The detailed matching logic is implemented in the following +code: [DefaultRequestMappingRegistry.java](https://github.com/apache/dubbo/blob/dubbo-3.3.0-beta.5/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/mapping/DefaultRequestMappingRegistry.java#L196), [RequestMapping.java](https://github.com/apache/dubbo/blob/dubbo-3.3.0-beta.5/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/mapping/RequestMapping.java#L127). + +1. Normalize the path using `PathUtils.normalize` to remove indirect paths such as `/one/../` or `/one/./`, ensuring the path starts with `/`. +2. Check if the HTTP method matches. +3. Check if the path matches. +4. Check if the parameter matches (not supported by JAX-RS). +5. Check if the header matches. +6. Check if the content type matches (Consumes). +7. Check if the accept header matches (Produces). +8. Check if `serviceGroup` and `serviceVersion` match. +9. Check if the method signature matches. +10. If no match is found, retry after removing the trailing `/` if trailing slash matching is enabled. +11. If no match is found, retry after removing the extension if extension matching is enabled. +12. If the last path segment contains `~`, retry with method signature matching enabled. +13. If no candidates remain, return `null`. +14. If one candidate remains, return it. +15. If multiple candidates remain, sort them. +16. Compare the first and second candidates. +17. If the result is inconclusive, throw an exception. +18. If the first candidate wins, return it. + + +#### Handling Path Conflicts + +Unlike Spring, which raises an error and prevents startup when paths are identical, Triple Rest focuses on out-of-the-box usage. To avoid disrupting existing services, it logs a +warning by default. At runtime, if it cannot determine the highest priority mapping, an error will be thrown. + + + +### Parameter Types + +Supported parameter types vary by dialect. Please refer to the specific dialect's guide for more details. You can also customize parameter resolution by implementing the SPI +`org.apache.dubbo.rpc.protocol.tri.rest.argument.ArgumentResolver`. + +#### Common Parameter Types + +| Name | Description | Basic Annotation | SpringMVC Annotation | JAX-RS Annotation | Array or Collection Handling | Map Handling | +|----------------|-------------------------|-----------------------------|----------------------|-------------------|-----------------------------------------------|----------------------------------| +| Param | Query or Form parameter | @Param | @RequestParam | - | Multi-value | Map of all parameters | +| Query | URL parameter | - | - | @QueryParam | Multi-value | Map of all Query parameters | +| Form | Form parameter | - | - | @FormParam | Multi-value | Map of all Form parameters | +| Header | HTTP header | @Param(type=Header) | @RequestHeader | @HeaderParam | Multi-value | Map of all Headers | +| Cookie | Cookie value | @Param(type=Cookie) | @CookieValue | @CookieParam | Multi-value | Map of all Cookies | +| Attribute | Request attribute | @Param(type=Attribute) | @RequestAttribute | - | Multi-value | Map of all Attributes | +| Part | Multipart file | @Param(type=Part) | @RequestHeader | @HeaderParam | Multi-value | Map of all Parts | +| Body | Request body | @Param(type=Body) | @RequestBody | @Body | Attempts to parse as array or collection | Attempts to parse as target type | +| PathVariable | Path variable | @Param(type=PathVariable) | @PathVariable | @PathParam | Single-value array or collection | Single-value Map | +| MatrixVariable | Matrix variable | @Param(type=MatrixVariable) | @MatrixVariable | @MatrixParam | Multi-value | Single-value Map | +| Bean | Java Bean | No annotation needed | @ModelAttribute | @BeanParam | Attempts to parse as Bean array or collection | - | + + + +#### Special Parameter Types + +| Type | Description | Activation Condition | +|-------------------------------------------------|--------------------------------|--------------------------| +| `org.apache.dubbo.remoting.http12.HttpRequest` | HttpRequest object | Activated by default | +| `org.apache.dubbo.remoting.http12.HttpResponse` | HttpResponse object | Activated by default | +| `org.apache.dubbo.remoting.http12.HttpMethods` | HTTP request method | Activated by default | +| `java.util.Locale` | Request Locale | Activated by default | +| `java.io.InputStream` | Request InputStream | Activated by default | +| `java.io.OutputStream` | Response OutputStream | Activated by default | +| `javax.servlet.http.HttpServletRequest` | Servlet HttpRequest object | Requires Servlet API jar | +| `javax.servlet.http.HttpServletResponse` | Servlet HttpResponse object | Same as above | +| `javax.servlet.http.HttpSession` | Servlet HttpSession object | Same as above | +| `javax.servlet.http.Cookie` | Servlet Cookie object | Same as above | +| `java.io.Reader` | Servlet Request Reader object | Same as above | +| `java.io.Writer` | Servlet Response Writer object | Same as above | + + + +#### Parameters without Annotations + +The handling varies by dialect; refer to the specific dialect's guide. + + +#### Accessing HTTP Input and Output Parameters without Annotations + +You can use `RpcContext` to retrieve them: + +```java +// Dubbo http req/resp +HttpRequest request = RpcContext.getServiceContext().getRequest(HttpRequest.class); +HttpResponse response = RpcContext.getServiceContext().getRequest(HttpResponse.class); +// Servlet http req/resp +HttpServletRequest request = RpcContext.getServiceContext().getRequest(HttpServletRequest.class); +HttpServletResponse response = RpcContext.getServiceContext().getRequest(HttpServletResponse.class); +``` + +After obtaining the request, you can access some built-in attributes through `attribute`. +See: [RestConstants.java](https://github.com/apache/dubbo/blob/dubbo-3.3.0-beta.5/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/RestConstants.java#L40) + + +### Parameter Type Conversion + +By default, most parameter type conversions from `String` to target types are supported, including: + +- JDK built-in types (e.g., basic types, date, `Optional`, etc.) +- Array types +- Collection types +- Map types + +Generic types, including complex nesting, are fully supported. For implementation details, refer +to: [GeneralTypeConverter.java](https://github.com/apache/dubbo/blob/dubbo-3.3.0-beta.5/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/argument/GeneralTypeConverter.java). +Custom parameter type conversion can also be achieved by implementing SPI `org.apache.dubbo.rpc.protocol.tri.rest.argument.ArgumentConverter`. + +| Source Type | Target Type | Description | Default Value | +|-------------|-------------------------|----------------------------------|---------------| +| `String` | `double` | Converts to a double | 0.0d | +| `String` | `float` | Converts to a float | 0.0f | +| `String` | `long` | Converts to a long | 0L | +| `String` | `int` | Converts to an integer | 0 | +| `String` | `short` | Converts to a short | 0 | +| `String` | `char` | Converts to a character | 0 | +| `String` | `byte` | Converts to a byte | 0 | +| `String` | `boolean` | Converts to a boolean | false | +| `String` | `BigInteger` | Converts to a BigInteger | null | +| `String` | `BigDecimal` | Converts to a BigDecimal | null | +| `String` | `Date` | Converts to a Date | null | +| `String` | `Calendar` | Converts to a Calendar | null | +| `String` | `Timestamp` | Converts to a Timestamp | null | +| `String` | `Instant` | Converts to an Instant | null | +| `String` | `ZonedDateTime` | Converts to a ZonedDateTime | null | +| `String` | `LocalDate` | Converts to a LocalDate | null | +| `String` | `LocalTime` | Converts to a LocalTime | null | +| `String` | `LocalDateTime` | Converts to a LocalDateTime | null | +| `String` | `ZoneId` | Converts to a ZoneId | null | +| `String` | `TimeZone` | Converts to a TimeZone | null | +| `String` | `File` | Converts to a File | null | +| `String` | `Path` | Converts to a Path | null | +| `String` | `Charset` | Converts to a Charset | null | +| `String` | `InetAddress` | Converts to an InetAddress | null | +| `String` | `URI` | Converts to a URI | null | +| `String` | `URL` | Converts to a URL | null | +| `String` | `UUID` | Converts to a UUID | null | +| `String` | `Locale` | Converts to a Locale | null | +| `String` | `Currency` | Converts to a Currency | null | +| `String` | `Pattern` | Converts to a Pattern | null | +| `String` | `Class` | Converts to a Class | null | +| `String` | `byte[]` | Converts to a byte array | null | +| `String` | `char[]` | Converts to a char array | null | +| `String` | `OptionalInt` | Converts to an OptionalInt | null | +| `String` | `OptionalLong` | Converts to an OptionalLong | null | +| `String` | `OptionalDouble` | Converts to an OptionalDouble | null | +| `String` | `Enum class` | Enum.valueOf | null | +| `String` | `Array` or `Collection` | Split by comma | null | +| `String` | `Specified class` | Try JSON String to Object | null | +| `String` | `Specified class` | Try construct with single String | null | +| `String` | `Specified class` | Try call static method `valueOf` | null | + + + +### Supported Content-Types + +By default, the following Content-Types are supported with corresponding encoding and decoding capabilities. Extension is available by implementing SPI +`org.apache.dubbo.remoting.http12.message.(HttpMessageDecoderFactory|HttpMessageEncoderFactory)`. + +| Media Type | Description | +|-------------------------------------|----------------------------| +| `application/json` | JSON format | +| `application/xml` | XML format | +| `application/yaml` | YAML format | +| `application/octet-stream` | Binary data | +| `application/grpc` | gRPC format | +| `application/grpc+proto` | gRPC with Protocol Buffers | +| `application/x-www-form-urlencoded` | URL-encoded form data | +| `multipart/form-data` | Form data with file upload | +| `text/json` | JSON format as text | +| `text/xml` | XML format as text | +| `text/yaml` | YAML format as text | +| `text/css` | CSS format | +| `text/javascript` | JavaScript format as text | +| `text/html` | HTML format | +| `text/plain` | Plain text | + + + +### Content Negotiation + +Supports comprehensive content negotiation to determine the output Content-Type based on mapping or input. The process is as follows: + +1. Try to read the mediaType specified by Mapping, retrieve the list of mediaTypes specified by Produces, and match wildcard to appropriate Media Type. For example, Spring's: + `@RequestMapping(produces = "application/json")` +2. Try to find mediaType using the Accept header, parse the request's `Accept` header, and match wildcard to appropriate Media Type. For example: `Accept: application/json` +3. Try to find mediaType using the format parameter, read the format parameter value, and match it to an appropriate Media Type. For example `/hello?format=yml` +4. Try to find mediaType using the request path extension, match the extension to an appropriate Media Type. For example `/hello.txt` +5. Try to use the request's Content-Type header as Media Type (excluding two form types). For example `Content-Type: application/json` +6. Default to `application/json` + + + +### CORS Support + +Provides full CORS support, enabled by configuring global parameters. Default behavior is consistent with SpringMVC. Fine-grained configuration is also supported through +`@CrossOrigin` in SpringMVC. For supported CORS configuration items, refer to: [8.4 CORS Configuration](#NLQqj) + + +### Custom HTTP Output + +Custom HTTP output is required in many scenarios, such as 302 redirects or setting HTTP headers. Triple Rest offers the following generic solutions, with dialect-specific +approaches available in each dialect's user guide: + +- Set the return value to: `org.apache.dubbo.remoting.http12.HttpResult` and build using `HttpResult#builder`. +- Throw a Payload exception: `throws new org.apache.dubbo.remoting.http12.exception.HttpResultPayloadException(HttpResult)`. Example code: + +```java +throw new HttpResult.found("https://a.com"). + +toPayload(); +``` + +This exception avoids filling error stacks, has minimal performance impact, and does not require return value logic, making it recommended for customizing output. + +- Customize after obtaining HttpResponse. Example code: + +```java +HttpResponse response = RpcContext.getServiceContext().getRequest(HttpResponse.class); + +response. + +sendRedirect("https://a.com"); +response. + +setStatus(404); +response. + +outputStream(). + +write(data); +// It is recommended to commit after writing to avoid being modified by other extensions +response. + +commit(); +``` + +If only adding `http headers`, use this method. + + +### Custom JSON Serialization + +Multiple JSON frameworks are supported, including Jackson, fastjson2, fastjson, and gson. Please ensure that the corresponding jar dependencies have been imported before use. + +#### Specifying the JSON Framework to Use + +```properties +dubbo.protocol.triple.rest.json-framework=jackson +``` + +#### Customization through JsonUtil SPI + +You can customize JSON processing by implementing the SPI `org.apache.dubbo.common.json.JsonUtil`. For specific examples, you can refer to the existing implementations +in [org/apache/dubbo/common/json/impl](https://github.com/apache/dubbo/tree/3.3/dubbo-common/src/main/java/org/apache/dubbo/common/json/impl). It is recommended to extend an +existing implementation and override as needed. + + + +### Exception Handling + +Unhandled exceptions are ultimately converted to the `ErrorResponse` class and encoded for output: + +```java + +@Data +public class ErrorResponse { + /** + * HTTP status code + */ + private String status; + + /** + * Exception message + */ + private String message; +} +``` + +Note that for errors with status 500 and above, to avoid disclosing internal server information, the default message output is "Internal Server Error". To customize the message, +create an exception that extends `org.apache.dubbo.remoting.http12.exception.HttpStatusException` and override the `getDisplayMessage` method.
The following general methods +are available for customizing exception handling: + +- Refer to [9.2 Custom Exception Return Results](#zFD9A) for using SPI to customize global exception handling. +- Use Dubbo's Filter SPI to process and transform exceptions. To access the HTTP context, extend `org.apache.dubbo.rpc.protocol.tri.rest.filter.RestFilterAdapter`. +- Use SPI `org.apache.dubbo.rpc.protocol.tri.rest.filter.RestFilter` to transform exceptions, which is more lightweight and provides path matching configuration capabilities. + +Note that the latter two methods only intercept exceptions occurring in the invoke chain. If exceptions occur during path matching, only method 1 can handle them. + + +## Basic Usage Guide + +See +example: [dubbo-samples-triple-rest/dubbo-samples-triple-rest-basic](https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-triple-rest/dubbo-samples-triple-rest-basic) + + +### Path Mapping + +Basic, as an out-of-the-box REST mapping, will by default map methods to: `/{contextPath}/{serviceInterface}/{methodName}`, where `/{contextPath}` will be ignored if not +configured, resulting in: `/{serviceInterface}/{methodName}`.
Custom mappings are supported through the `org.apache.dubbo.remoting.http12.rest.Mapping` annotation. The +attribute descriptions are as follows: + +| Config Name | Description | Default Behavior | +|-------------|----------------------------------------------------------------------------------------|------------------------------------| +| `value` | Mapped URL paths, which can be one or more paths. | Empty array | +| `path` | Mapped URL paths, same as `value`, can be one or more paths. | Empty array | +| `method` | Supported HTTP methods list, such as `GET`, `POST`, etc. | Empty array (supports all methods) | +| `params` | List of parameters that must be included in the request. | Empty array | +| `headers` | List of headers that must be included in the request. | Empty array | +| `consumes` | Content types (Content-Type) for processing requests, which can be one or more types. | Empty array | +| `produces` | Content types (Content-Type) for generating responses, which can be one or more types. | Empty array | +| `enabled` | Whether to enable this mapping. | `true` (enabled) | + +- Attributes can be configured using placeholders: `@Mapping("${prefix}/hi")` +- To prevent a specific service or method from being exported as REST, set `@Mapping(enabled = false)` + + +### Parameter Types + +General parameters are discussed in: [3.2 Parameter Types](#kmCzf) + + + +#### Parameters Without Annotations + +Basic supports parameters without annotations through the +class: [FallbackArgumentResolver.java](https://github.com/apache/dubbo/blob/dubbo-3.3.0-beta.5/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/support/basic/FallbackArgumentResolver.java#L41). +The detailed processing flow is as follows:
![rest-arg.jpg](/imgs/v3/manual/java/protocol/rest-arg.jpg) + + +## SpringMVC Usage Guide + +See +example: [dubbo-samples-triple-rest/dubbo-samples-triple-rest-springmvc](https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-triple-rest/dubbo-samples-triple-rest-springmvc) + + +### Path Mapping + +Refer directly to the SpringMVC documentation, which supports most +features, [Mapping Requests :: Spring Framework](https://docs.spring.io/spring-framework/reference/web/webmvc/mvc-controller/ann-requestmapping.html#mvc-ann-requestmapping-uri-templates)
+Note that `@Controller` or `@RestController` annotations are not required; in addition to `@RequestMapping`, the new `@HttpExchange` is also supported. + + +### Parameter Types + + + +#### General Parameters + +See: [3.2 Parameter Types](#kmCzf) + + +#### Annotated Parameter Types + +See [3.2.1 Annotated Parameter Types](#dCgzz) + + +#### Special Parameter Types + +| Type | Description | Activation Condition | +|----------------------------------------------------------|-------------------------|-------------------------------| +| org.springframework.web.context.request.WebRequest | WebRequest object | SpringWeb dependency required | +| org.springframework.web.context.request.NativeWebRequest | NativeWebRequest object | Same as above | +| org.springframework.http.HttpEntity | Http entity | Same as above | +| org.springframework.http.HttpHeaders | Http headers | Same as above | +| org.springframework.util.MultiValueMap | Multi-value map | Same as above | + + + +#### Parameters Without Annotations + +- For basic types (as determined + by [TypeUtils#isSimpleProperty](https://github.com/apache/dubbo/blob/dubbo-3.3.0-beta.5/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/util/TypeUtils.java#L105)), + directly obtained from Parameter +- For non-basic types, + use [@ModelAttribute :: Spring Framework](https://docs.spring.io/spring-framework/reference/web/webmvc/mvc-controller/ann-methods/modelattrib-method-args.html) to bind complex + bean type parameters + + +### Parameter Type Conversion + +Prefer using Spring's `org.springframework.core.convert.ConversionService` to convert parameters. For Spring Boot applications, the default is `mvcConversionService`; otherwise, +use `org.springframework.core.convert.support.DefaultConversionService#getSharedInstance` to obtain the shared `ConversionService`.
If `ConversionService` does not support it, +it will fall back to general type conversion: [3.3 Parameter Type Conversion](#I56vX) + + +### Exception Handling + +In addition to supporting the methods mentioned in [3.8 Exception Handling](#XeDPr), Spring's `@ExceptionHandler` annotation method is also +supported, [Exceptions :: Spring Framework](https://docs.spring.io/spring-framework/reference/web/webmvc/mvc-controller/ann-exceptionhandler.html). Note that this method only +handles exceptions thrown during method calls; other exceptions cannot be captured. + + +### CORS Configuration + +In addition to supporting global CORS configuration as described in [8.4 CORS Configuration](#NLQqj), Spring's `@CrossOrigin` allows for fine-grained +configuration, [CORS :: Spring Framework](https://docs.spring.io/spring-framework/reference/web/webmvc-cors.html#mvc-cors-controller). + + +### Custom HTTP Output + +Supports the following Spring customization methods: + +1. Use `@ResponseStatus` annotation +2. Return `org.springframework.http.ResponseEntity` object + + +### Supported Extensions + +- org.springframework.web.servlet.HandlerInterceptor
Usage is similar to [7.1 Using Filter Extensions](#xCEi3) + + +## JAX-RS Usage Guide + +See +example: [dubbo-samples-triple-rest/dubbo-samples-triple-rest-jaxrs](https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-triple-rest/dubbo-samples-triple-rest-jaxrs) + + +### Path Mapping + +Services need to explicitly add the @Path annotation, and methods need to add request method annotations like @GET, @POST, @HEAD.
Refer directly to the Resteasy documentation, +which supports most features, [Chapter 4. Using @Path and @GET, @POST, etc.](https://docs.jboss.org/resteasy/docs/6.2.7.Final/userguide/html/ch04.html) + + +### Parameter Types + + + +#### General Parameters + +See: [3.2 Parameter Types](#kmCzf) + + +#### Annotation Type Parameters + +| Annotation | Parameter Location | Description | +|---------------|--------------------|----------------------------------------| +| @QueryParam | querystring | Parameters corresponding to ?a=a&b=b | +| @HeaderParam | header | | +| @PathParam | path | | +| @FormParam | form | body in key1=value2&key2=value2 format | +| No annotation | body | Not explicitly annotated | + + + +#### Special Type Parameters + +| Type | Description | Activation Condition | +|---------------------------------|-----------------|----------------------------| +| javax.ws.rs.core.Cookie | Cookie object | Requires Jax-rs dependency | +| javax.ws.rs.core.Form | Form object | Same as above | +| javax.ws.rs.core.HttpHeaders | Http headers | Same as above | +| javax.ws.rs.core.MediaType | Media type | Same as above | +| javax.ws.rs.core.MultivaluedMap | Multivalued Map | Same as above | +| javax.ws.rs.core.UriInfo | Uri information | Same as above | + + + +#### Non-Annotated Parameters + +- For basic types (as determined + by [TypeUtils#isSimpleProperty](https://github.com/apache/dubbo/blob/dubbo-3.3.0-beta.5/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/util/TypeUtils.java#L105)), + directly retrieved from Parameter +- For non-basic types, treated as request body to decode the object + + +### Parameter Type Conversion + +Custom parameter conversion can be extended via the following interfaces: + +``` +org.apache.dubbo.rpc.protocol.tri.rest.argument.ArgumentResolver +javax.ws.rs.ext.ParamConverterProvider +``` + + + +### Exception Handling + +Custom exception handling can be extended via the following interfaces: + +``` +javax.ws.rs.ext.ExceptionMapper +org.apache.dubbo.remoting.http12.ExceptionHandler +``` + + + +### CORS Configuration + +Supports [8.4 CORS Configuration](#NLQqj) global configuration + + +### Custom HTTP Output + +Supports the following JAX-RS customizations: + +- Returning `javax.ws.rs.core.Response` object + + +### Supported Extensions + +1. javax.ws.rs.container.ContainerRequestFilter
Request filter, allows pre-processing of requests before they reach the resource method. +2. javax.ws.rs.container.ContainerResponseFilter
Response filter, allows post-processing of responses after they leave the resource method. +3. javax.ws.rs.ext.ExceptionMapper
Exception mapper, maps thrown exceptions to HTTP responses. +4. javax.ws.rs.ext.ParamConverterProvider
Parameter converter, allows conversion of request parameters to resource method parameter types. +5. javax.ws.rs.ext.ReaderInterceptor
Reader interceptor, allows interception and handling when reading request entities. +6. javax.ws.rs.ext.WriterInterceptor
Writer interceptor, allows interception and handling when writing response entities. + + +## Servlet Usage Guide + +For both lower version javax and higher version jakarta servlet APIs, jakarta API has higher priority. Simply include the jar to use HttpServletRequest and HttpServletResponse as +parameters. + + +### Using Filter Extension + +Method 1: Implement `Filter` interface and `org.apache.dubbo.rpc.protocol.tri.rest.filter.RestExtension` interface, then register SPI + +```java +import org.apache.dubbo.rpc.protocol.tri.rest.filter.RestExtension; + +import javax.servlet.Filter; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; + +public class DemoFilter implements Filter, RestExtension { + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) { + chain.doFilter(request, response); + } + + @Override + public String[] getPatterns() { + return new String[]{"/demo/**", "!/demo/one"}; + } + + @Override + public int getPriority() { + return -200; + } +} +``` + +Method 2: Implement `Supplier` interface and `org.apache.dubbo.rpc.protocol.tri.rest.filter.RestExtension` interface, then register SPI + +```java +public class DemoFilter implements Supplier, RestExtension { + + private final Filter filter = new SsoFilter(); + + @Override + public Filter get() { + return filter; + } +} +``` + +This method is convenient for reusing existing Filters, and can even obtain Filter instances from Spring Context and register them + +```java +public class DemoFilter implements Supplier, RestExtension { + + private final Filter filter = new SsoFilter(); + + public DemoFilter(FrameworkModel frameworkModel) { + SpringExtensionInjector injector = SpringExtensionInjector.get(frameworkModel.defaultApplication()); + filter = injector.getInstance(SsoFilter.class, null); + } + + @Override + public Filter get() { + return filter; + } +} +``` + + + +### HttpSession Support + +Implement SPI `org.apache.dubbo.rpc.protocol.tri.rest.support.servlet.HttpSessionFactory` + + +### Unsupported Features + +- Wrapping request and response objects in Filter will not work due to the large number of filter types supported by Rest, leading to complex nesting and handling. +- `request.getRequestDispatcher` is not supported + + +### Security Configuration + +When Rest services open direct access to the public network, there are security risks of potential attacks. Therefore, before exposing services, it's necessary to thoroughly assess +the risks and choose appropriate authentication methods to ensure security. Triple provides various security authentication mechanisms, and users can also implement their own +extensions to perform security checks on access. + +#### Basic Authentication + +To enable Basic Authentication, modify the following configuration: + +```yaml +dubbo: + provider: + auth: true + authenticator: basic + username: admin + password: admin +``` + +Once enabled, all HTTP requests will require Basic Authentication to access. + +For RPC calls, you also need to configure the corresponding username and password on the consumer side: + +```yaml +dubbo: + consumer: + auth: true + authenticator: basic + username: admin + password: admin +``` + +With this configuration, communication between provider and consumer will use Basic Authentication to ensure security. Make sure to use strong passwords in production environments +and consider using HTTPS for encrypted transmission. + +### Authentication Extensions + +#### Implementing Custom Authenticator + +You can customize authentication by implementing the SPI `org.apache.dubbo.auth.spi.Authenticator`, and select the Authenticator to enable through the configuration +`dubbo.provider.authenticator`. + +#### Implementing HTTP Request Filtering + +You can customize HTTP filtering logic by implementing the SPI `org.apache.dubbo.rpc.HeaderFilter` or `org.apache.dubbo.rpc.protocol.tri.rest.filter.RestFilter`. + +## Global Parameter Configuration + + + +### Case Sensitivity + +Configuration Name: `dubbo.protocol.triple.rest.case-sensitive-match`
Whether path matching should be case-sensitive. If enabled, methods mapped to `/users` will not match +`/Users`
Default is `true` + + +### Trailing Slash Matching + +Configuration Name: `dubbo.protocol.triple.rest.trailing-slash-match`
Whether path matching should match paths with trailing slashes. If enabled, methods mapped to `/users` +will also match `/users/`
Default is `true` + + +### Suffix Matching + +Configuration Name: `dubbo.protocol.triple.rest.suffix-pattern-match`
Whether path matching uses suffix pattern matching (.*). If enabled, methods mapped to `/users` will also +match `/users.*`, with suffix content negotiation enabled, media types inferred from URL suffix, e.g., `.json` corresponds to `application/json`
Default is `true` + + +### CORS Configuration + +| Configuration Name | Description | Default Value | +|-----------------------------------------------------|----------------------------------------------------------------------------------------------------|------------------------------------------| +| `dubbo.protocol.triple.rest.cors.allowed-origins` | List of allowed origins for cross-origin requests, can be specific domains or `*` for all origins. | Not set (no origins allowed) | +| `dubbo.protocol.triple.rest.cors.allowed-methods` | List of allowed HTTP methods, e.g., `GET`, `POST`, `PUT`, `*` for all methods. | Not set (only `GET` and `HEAD`) | +| `dubbo.protocol.triple.rest.cors.allowed-headers` | List of allowed request headers in preflight requests, `*` for all headers. | Not set | +| `dubbo.protocol.triple.rest.cors.exposed-headers` | List of response headers exposed to clients, `*` for all headers. | Not set | +| `dubbo.protocol.triple.rest.cors.allow-credentials` | Whether user credentials are supported. | Not set (user credentials not supported) | +| `dubbo.protocol.triple.rest.cors.max-age` | Time (in seconds) that the client can cache the preflight request response. | Not set | + + + +## Advanced Usage Guide + + + +### Summary of Supported Extensions + +1. javax.servlet.Filter
Servlet API filter. +2. org.apache.dubbo.rpc.protocol.tri.rest.support.servlet.HttpSessionFactory
Supports HttpSession in Servlet API. +3. javax.ws.rs.container.ContainerRequestFilter
JAX-RS request filter, allows pre-processing of requests before they reach the resource method. +4. javax.ws.rs.container.ContainerResponseFilter
JAX-RS response filter, allows post-processing of responses after they leave the resource method. +5. javax.ws.rs.ext.ExceptionMapper
JAX-RS exception mapper, maps thrown exceptions to HTTP responses. +6. javax.ws.rs.ext.ParamConverterProvider
JAX-RS parameter converter, allows conversion of request parameters to resource method parameter types. +7. javax.ws.rs.ext.ReaderInterceptor
JAX-RS reader interceptor, allows interception and handling when reading request entities. +8. javax.ws.rs.ext.WriterInterceptor
JAX-RS writer interceptor, allows interception and handling when writing response entities. +9. org.springframework.web.servlet.HandlerInterceptor
Spring MVC handler interceptor. +10. org.apache.dubbo.remoting.http12.ExceptionHandler
Provides custom exception handling mechanism. +11. org.apache.dubbo.remoting.http12.message.HttpMessageAdapterFactory
Provides adaptation and conversion functions for HTTP messages. +12. org.apache.dubbo.remoting.http12.message.HttpMessageDecoderFactory
Provides HTTP message decoding functions. +13. org.apache.dubbo.remoting.http12.message.HttpMessageEncoderFactory
Provides HTTP message encoding functions. +14. org.apache.dubbo.rpc.HeaderFilter
Dubbo RPC header filter, allows filtering and handling of request and response headers. +15. org.apache.dubbo.rpc.protocol.tri.rest.filter.RestHeaderFilterAdapter
Header filter adapter providing access to HTTP input and output capabilities. +16. org.apache.dubbo.rpc.protocol.tri.rest.filter.RestFilterAdapter
Dubbo Filter REST adapter, providing access to HTTP input and output capabilities. +17. org.apache.dubbo.rpc.protocol.tri.route.RequestHandlerMapping
Provides request mapping capability in Dubbo Triple. +18. org.apache.dubbo.rpc.protocol.tri.rest.mapping.RequestMappingResolver
Resolves REST request mappings. +19. org.apache.dubbo.rpc.protocol.tri.rest.util.RestToolKit
Provides REST-related tools and utilities. +20. org.apache.dubbo.rpc.protocol.tri.rest.argument.ArgumentConverter
Provides argument type conversion functionality. +21. org.apache.dubbo.rpc.protocol.tri.rest.argument.ArgumentResolver
Provides argument resolution functionality. +22. org.apache.dubbo.rpc.protocol.tri.rest.filter.RestFilter
Provides filtering functionality for REST requests and responses. +23. org.apache.dubbo.rpc.protocol.tri.rest.filter.RestExtensionAdapter
RestExtension adapter providing mapping of existing filter interfaces to RestFilter interfaces. + + +### Custom Exception Handling + +Custom exception handling logic can be implemented via the SPI `org.apache.dubbo.remoting.http12.ExceptionHandler` + +```java +public interface ExceptionHandler { + /** + * Resolves the log level for a given throwable. + */ + default Level resolveLogLevel(E throwable) { + return null; + } + + /** + * Handle the exception and return a result. + */ + default T handle(E throwable, RequestMetadata metadata, MethodDescriptor descriptor) { + return null; + } +} +``` + +Implement SPI and specify the exception type E to handle + +- resolveLogLevel
Dubbo framework will log Rest handling exceptions, customize log level or ignore logs by implementing this method. +- handle
If the result is not null, it will be directly returned; customize output headers and status code by returning `org.apache.dubbo.remoting.http12.HttpResult`. + + +### Enable Debug Logging + +```yaml +logging: + level: + "org.apache.dubbo.rpc.protocol.tri": debug + "org.apache.dubbo.remoting": debug +``` + +Enable debug logging will output detailed startup logs and request/response logs for troubleshooting. + + +### Enable Verbose Output + +```yaml +dubbo: + protocol: + triple: + verbose: true +``` + +Enable verbose output will return internal error stack traces to the caller and output more error logs for troubleshooting. diff --git a/content/en/download/_index.md b/content/en/download/_index.md index 62ae4183996d..a85a11e6189b 100644 --- a/content/en/download/_index.md +++ b/content/en/download/_index.md @@ -3,7 +3,7 @@ aliases: - /en/release/ description: Download layout: basic -linkTitle: Download +linkTitle: DOWNLOAD menu: main: weight: 30 diff --git a/content/en/featured-background.jpg b/content/en/featured-background.jpg index f6a02b9113ea..d4bc6b77b851 100644 Binary files a/content/en/featured-background.jpg and b/content/en/featured-background.jpg differ diff --git a/content/en/overview/_index.md b/content/en/overview/_index.md index 368b04b18b37..15bab5c80153 100755 --- a/content/en/overview/_index.md +++ b/content/en/overview/_index.md @@ -1,7 +1,7 @@ --- type: docs title: "Overview" -linkTitle: "Overview" +linkTitle: "DOCS" no_list: true hide_summary: true menu: diff --git a/content/en/overview/demo/_index.md b/content/en/overview/demo/_index.md new file mode 100644 index 000000000000..df6c58e4d9e0 --- /dev/null +++ b/content/en/overview/demo/_index.md @@ -0,0 +1,6 @@ +--- +title: "Demo" +layout: "shortcodes/blocks/demo-en" +toc_hide: true +--- + {{< blocks/demo-en >}} diff --git a/content/zh-cn/_index.html b/content/zh-cn/_index.html index 21a7aabd411e..28d5ca266770 100644 --- a/content/zh-cn/_index.html +++ b/content/zh-cn/_index.html @@ -4,110 +4,14 @@ description = "Apache Dubbo 官网" aliases = ["/zh/"] +++ - -{{< blocks/cover title="Apache Dubbo" image_anchor="top" height="min" color="secondary" >}} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +{{< blocks/cover title="Apache Dubbo" image_anchor="top" height="min" color="white" >}} {{< /blocks/cover >}} - {{% blocks/lead color="white" height="min" id="whyDubbo" %}}

Why Dubbo?

- - - - - - {{% /blocks/lead %}} - - - - - - - - - - - - {{< blocks/section id="oceanNodes" >}} {{% blocks/feature image="framework" url="./overview/what/advantages/usability/" %}} #### [快速上手](./overview/what/advantages/usability/),让开发者专注业务开发 @@ -148,65 +52,9 @@

快速掌握基于 Apache Dubbo 的微服务开发与治理

- +
{{< /blocks/section >}} {{< blocks/dubbo-features >}} - -
-

关注社区

- -

请通过以下任一或多个渠道关注社区动态,与社区开发者保持密切沟通.

- -
-
- - Wechat - - 微信公众号 -

官方微信公众号(Apache Dubbo)

-
-
- - Dingtalk - - 钉钉群组 -

定期举办线上社区会议或开发者双周会

-
-
- - Twitter - - Twitter ▶ -

#apachedubbo

-

关于 Apache Dubbo 项目的国际社区动态与业界国际资讯

-
- -
- - GitHub - - GitHub ▶ -

找到对应语言实现或生态项目的 GitHub 地址,即刻参与 Dubbo 项目源码贡献

-
-
-
- - - - - - - - - - - - - - - - - diff --git a/content/zh-cn/blog/ web/_index.md b/content/zh-cn/blog/ web/_index.md new file mode 100644 index 000000000000..2a29d4c05e1c --- /dev/null +++ b/content/zh-cn/blog/ web/_index.md @@ -0,0 +1,9 @@ + +--- +title: "Web" +linkTitle: "Web" +weight: 32 +description: "使用 Javascript 开发运行在浏览器上的 Dubbo Web 应用" +--- + + diff --git a/content/zh-cn/blog/_index.md b/content/zh-cn/blog/_index.md index 18eb94a46725..decb5322eae0 100644 --- a/content/zh-cn/blog/_index.md +++ b/content/zh-cn/blog/_index.md @@ -3,7 +3,7 @@ title: "Apache Dubbo 博客" linkTitle: "博客" menu: main: - weight: 20 + weight: 3 --- diff --git a/content/zh-cn/blog/integration/dubbo-triple-with-apisix-gateway.md b/content/zh-cn/blog/integration/dubbo-triple-with-apisix-gateway.md new file mode 100644 index 000000000000..cb147591fbc8 --- /dev/null +++ b/content/zh-cn/blog/integration/dubbo-triple-with-apisix-gateway.md @@ -0,0 +1,154 @@ +--- +description: | + 本文为大家介绍了如何借助 Apache APISIX 实现 triple 协议代理,使用 nacos 作为注册中心。 +linkTitle: 使用 Apache APISIX 代理 Dubbo 服务(triple协议) +title: 使用 Apache APISIX 代理 Dubbo 服务(triple协议) +type: docs +date: 2024-04-22 +weight: 2 +--- + +关于如何用网关代理 triple 协议服务的原理介绍,请参见 [HTTP 网关接入](/zh-cn/overview/mannual/java-sdk/tasks/gateway/triple/) 一节文档。 + +本文我们使用 `Apache APISIX + triple 协议 + Nacos 注册中心` 的组合,演示如何使用 Apache APISIX 代理 Dubbo 服务。 + +## 示例应用说明 + +本示例完整源码与部署资源文件可查看 [dubbo-samples-gateway-triple-apisix](https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-gateway/dubbo-samples-gateway-apisix/dubbo-samples-gateway-apisix-triple),示例架构图如下: + + + +在该示例中定义并发布了一个 `org.apache.dubbo.samples.gateway.apisix.DemoService` 的 triple 服务,接口定义为: + +```java +public interface DemoService { + String sayHello(String name); +} +``` + +接口实现如下: + +```java +@DubboService +public class DemoServiceImpl implements DemoService { + @Override + public String sayHello(String name) { + return "Hello " + name; + } +} +``` + +Dubbo服务相关配置: + +```yaml +dubbo: + application: + name: gateway-apisix-triple + registry: + address: nacos://${nacos.address:127.0.0.1}:8848 + username: nacos + password: nacos + protocol: + name: tri + port: 50052 +``` + +## 部署应用 + +1. 在 [本地下载并启动 Nacos](/zh-cn/overview/reference/integrations/nacos/#本地下载) + +2. 运行以下命令,启动 Dubbo 应用。 + +下载源码: + +```shell +$ git clone -b main --depth 1 https://github.com/apache/dubbo-samples +$ cd dubbo-samples/2-advanced/dubbo-samples-gateway/dubbo-samples-gateway-apisix/dubbo-samples-gateway-apisix-triple +``` + +在 `dubbo-samples-gateway-apisix-triple` 目录,运行以下命令启动应用: + +```shell +$ mvn compile exec:java -Dexec.mainClass="org.apache.dubbo.samples.gateway.apisix.ProviderApplication" +``` + +运行以下命令,测试服务已经正常启动: + +```shell +curl \ + --header "Content-Type: application/json" \ + --data '["dubbo"]' \ + http://localhost:50052/org.apache.dubbo.samples.gateway.apisix.DemoService/sayHello/ +``` + +## 接入 APISIX 网关 + +本文档使用 Docker 安装 APISIX。确保本地先安装 [Docker](https://www.docker.com/) 和 [Docker Compose](https://docs.docker.com/compose/)。 + +首先,下载 [apisix-docker](https://github.com/apache/apisix-docker) 仓库。 + +```shell +$ git clone https://github.com/apache/apisix-docker.git +$ cd apisix-docker/example +``` + +由于本示例要接入到 Nacos 注册中心,因此需要修改 `apisix-docker/example` 目录下安装用的 `docker-compose.yaml`,添加如下 docker compose 配置内容: + +```yaml + nacos: + image: nacos/nacos-server:v2.1.1 + container_name: nacos-standalone + environment: + - PREFER_HOST_MODE=hostname + - MODE=standalone + ports: + - "8848:8848" + - "9848:9848" + networks: + apisix: +``` + +启动 APISIX 前,在 `conf/config.yaml` 文件中增加如下配置,[让 APISIX 连接到 Nacos 注册中心](https://apisix.apache.org/docs/apisix/discovery/nacos/#service-discovery-via-nacos): + +```yaml +discovery: + nacos: + host: + - "http://192.168.33.1:8848" +``` + +最后使用 `docker-compose` 启用 APISIX:`docker-compose -p docker-apisix up -d`。 + +### 配置服务源与路由 + +在 APISIX 中配置 Nacos upstream 及路由,即可实现后端实例地址自动发现(假设 APISIX 端口是 9080): + +```shell +curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -i -d ' +{ + "uri": "/org.apache.dubbo.samples.gateway.apisix.DemoService/sayHello/", + "upstream": { + "service_name": "gateway-apisix-triple", + "type": "roundrobin", + "discovery_type": "nacos" + } +}' +``` + +> 在上述命令中,请求头 X-API-KEY 是 Admin API 的访问 token,可以在 conf/config.yaml 文件中的 apisix.admin_key.key 查看。 + +### 验证服务调用 + +使用以下命令发送请求至需要配置的路由: + +```shell +curl -i http://127.0.0.1:9080/org.apache.dubbo.samples.gateway.apisix.DemoService/sayHello/ +``` + +### REST 模式 + +如果您觉得 `/org.apache.dubbo.samples.gateway.apisix.DemoService/sayHello/` 这样的 http 端口对于网关访问不够友好,可参考 [为 triple 协议发布 rest 风格 http 接口](/zh-cn/overview/mannual/java-sdk/tasks/gateway/triple/#rest-风格接口)。 + + + + diff --git a/content/zh-cn/blog/integration/how-to-proxy-dubbo-in-apache-apisix.md b/content/zh-cn/blog/integration/how-to-proxy-dubbo-in-apache-apisix.md index d624aba7ec1a..b715b624b50f 100644 --- a/content/zh-cn/blog/integration/how-to-proxy-dubbo-in-apache-apisix.md +++ b/content/zh-cn/blog/integration/how-to-proxy-dubbo-in-apache-apisix.md @@ -1,7 +1,7 @@ --- -title: "从原理到操作,让你在 Apache APISIX 中代理 Dubbo 服务更便捷" +title: "使用 Apache APISIX 代理 Dubbo 服务 (dubbo 协议)" linkTitle: "从原理到操作,让你在 Apache APISIX 中代理 Dubbo 服务更便捷" -date: 2022-01-18 +date: 2024-04-25 tags: ["网关", "生态", "Java"] description: > 本文为大家介绍了如何借助 Apache APISIX 实现 Dubbo Service 的代理,通过引入 dubbo-proxy 插件便可为 Dubbo 框架的后端系统构建更简单更高效的流量链路 @@ -10,32 +10,79 @@ aliases: - /zh/overview/what/gateway/higress/ --- -## 背景 +{{% alert title="注意" color="warning" %}} +本文仅适用于 dubbo 协议通信场景。如果您是 Dubbo3 用户,建议您使用 triple 协议,可参见 [使用 Apache APISIX 代理 Dubbo 服务(triple协议)](/zh-cn/blog/2024/04/22/使用-apache-apisix-代理-dubbo-服务triple协议/) 学习具体示例。 +{{% /alert %}} -[Apache Dubbo](/zh-cn/) 是由阿里巴巴开源并捐赠给 Apache 的微服务开发框架,它提供了 RPC 通信与微服务治理两大关键能力。不仅经过了阿里电商场景中海量流量的验证,也在国内的技术公司中被广泛落地。 - -在实际应用场景中,Apache Dubbo 一般会作为后端系统间 RPC 调用的实现框架,当需要提供 HTTP 接口给到前端时,会通过一个「胶水层」将 Dubbo Service 包装成 HTTP 接口,再交付到前端系统。 [Apache APISIX](https://apisix.apache.org/) 是 Apache 软件基金会的顶级开源项目,也是当前最活跃的开源网关项目。作为一个动态、实时、高性能的开源 API 网关,Apache APISIX 提供了负载均衡、动态上游、灰度发布、服务熔断、身份认证、可观测性等丰富的流量管理功能。 -得益于 Apache Dubbo 的应用场景优势,Apache APISIX 基于开源项目 tengine/mod_dubbo 模块为 Apache Dubbo 服务配备了HTTP 网关能力。通过 dubbo-proxy 插件,可以轻松地将 Dubbo Service 发布为 HTTP 服务。 +Apache APISIX 基于开源项目 tengine/mod_dubbo 模块为 Apache Dubbo 服务配备了HTTP 网关能力。通过 dubbo-proxy 插件,可以轻松地将 Dubbo Service 发布为 HTTP 服务。 ![架构图](/imgs/blog/apisix-plugin/1.png) -## 如何使用 -### 入门篇:安装使用 +## 入门篇 + +### 安装 APISIX + +本文档使用 Docker 安装 APISIX。确保本地先安装 [Docker](https://www.docker.com/) 和 [Docker Compose](https://docs.docker.com/compose/)。 + +首先,下载 [apisix-docker](https://github.com/apache/apisix-docker) 仓库。 + +```shell +$ git clone https://github.com/apache/apisix-docker.git +$ cd apisix-docker/example +``` + +由于本示例要接入到 Nacos 注册中心,因此 `apisix-docker/example` 目录下安装用的 `docker-compose.yaml`,添加如下内容: + +```yaml + nacos: + image: nacos/nacos-server:v2.1.1 + container_name: nacos-standalone + environment: + - PREFER_HOST_MODE=hostname + - MODE=standalone + ports: + - "8848:8848" + - "9848:9848" + networks: + apisix: +``` + +在 config.yaml 文件中增加 nacos 注册中心配置: + +```yaml +discovery: + nacos: + host: + - "http://192.168.33.1:8848" +``` + +在 config.yaml 文件中进行 dubbo-proxy 插件启用: + +```yaml +# Add this in config.yaml +plugins: + - ... # plugin you need + - dubbo-proxy +``` ->这里我们建议使用 Apache APISIX 2.11 版本镜像进行安装。该版本的 APISIX-Base 中已默认编译了 Dubbo 模块,可直接使用 `dubbo-proxy` 插件。 +> 如果你使用了 Apache APISIX 2.11 版本镜像,则可以省去 `dubbo-proxy` 配置环节,该版本的 APISIX-Base 中已默认编译了 Dubbo 模块,可直接使用。 -在接下来的操作中,我们将使用 [`dubbo-samples`](https://github.com/apache/dubbo-samples) 项目进行部分展示。该项目是一些使用 Apache Dubbo 实现的 Demo 应用,本文中我们采用其中的一个子模块作为 Dubbo Provider。 +最后,使用 `docker-compose` 启用 APISIX:`docker-compose -p docker-apisix up -d` + +### 示例说明 + +在接下来的操作中,我们将使用 [dubbo-samples-gateway-triple-apisix](https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-gateway/dubbo-samples-gateway-apisix/dubbo-samples-gateway-apisix-dubbo) 项目进行部分展示。 在进入正式操作前,我们先简单看下 Dubbo 接口的定义、配置以及相关实现。 #### 接口实现一览 ```java -public interface DemoService { +public interface ApisixService { /** * standard samples dubbo infterace demo @@ -48,20 +95,10 @@ public interface DemoService { 如上所示,Dubbo 接口的定义是固定的。即方法参数中 `Map` 表示 APISIX 传递给 Dubbo Provider 关于 HTTP request 的一些信息(如:header、body...)。而方法返回值的 `Map` 表示 Dubbo Provider 传递给 APISIX 要如何返回 HTTP response 的一些信息。 -接口信息配置好之后可通过 XML 配置方式发布 DemoService。 - -```xml - - - - - -``` - -通过上述配置后,Consumer 可通过 `org.apache.dubbo.samples.apisix.DemoService` 访问其中的`apisixDubbo` 方法。具体接口实现如下: +通过上述配置后,Consumer 可通过 `org.apache.dubbo.samples.gateway.apisix.dubbo.api.ApisixService` 访问其中的`apisixDubbo` 方法。具体接口实现如下: ```java -public class DemoServiceImpl implements DemoService { +public class ApisixServiceImpl implements ApisixService { @Override public Map apisixDubbo(Map httpRequestContext) { for (Map.Entry entry : httpRequestContext.entrySet()) { @@ -78,29 +115,33 @@ public class DemoServiceImpl implements DemoService { } ``` -上述代码中,`DemoServiceImpl` 会打印接收到的 `httpRequestContext`,并通过返回包含有指定 Key 的 Map 对象去描述该 Dubbo 请求的 HTTP 响应。 +上述代码中,`ApisixServiceImpl` 会打印接收到的 `httpRequestContext`,并通过返回包含有指定 Key 的 Map 对象去描述该 Dubbo 请求的 HTTP 响应。 -#### 操作步骤 +在 `dubbo-samples-gateway-apisix-dubbo` 目录,运行以下命令启动应用(或者选择使用 IDE 启动应用): -1. 启动 [`dubbo-samples`](https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-tengine#install-dubbo)。 -2. 在 `config.yaml` 文件中进行 `dubbo-proxy` 插件启用。 +```shell +$ git clone -b main --depth 1 https://github.com/apache/dubbo-samples +$ cd dubbo-samples/2-advanced/dubbo-samples-gateway/dubbo-samples-gateway-apisix/dubbo-samples-gateway-apisix-dubbo -```yaml -# Add this in config.yaml -plugins: - - ... # plugin you need - - dubbo-proxy +$ mvn compile exec:java -Dexec.mainClass="org.apache.dubbo.samples.gateway.apisix.dubbo.provider.ProviderApplication" ``` -3. 创建指向 Dubbo Provider 的 Upstream。 +启动 consumer 进程,验证服务正常启动,可以被调用: + +```shell +$ mvn compile exec:java -Dexec.mainClass="org.apache.dubbo.samples.gateway.apisix.dubbo.consumer.ConsumerApplication" +``` + +### 接入APISIX + +1. 创建指向 Dubbo 服务的 Upstream。 ```shell curl http://127.0.0.1:9180/apisix/admin/upstreams/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d ' { - "nodes": { - "127.0.0.1:20880": 1 - }, - "type": "roundrobin" + "service_name": "gateway-apisix-dubbo", + "type": "roundrobin", + "discovery_type": "nacos" }' ``` @@ -109,14 +150,12 @@ curl http://127.0.0.1:9180/apisix/admin/upstreams/1 -H 'X-API-KEY: edd1c9f03433 ```shell curl http://127.0.0.1:9180/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d ' { - "host": "example.org" "uris": [ "/demo" ], "plugins": { "dubbo-proxy": { - "service_name": "org.apache.dubbo.samples.apisix.DemoService", - "service_version": "0.0.0", + "service_name": "org.apache.dubbo.samples.gateway.apisix.dubbo.api.ApisixService", "method": "apisixDubbo" } }, @@ -171,7 +210,7 @@ Key = user-agent, Value = curl/7.80.0 这样就可以将 Apache APISIX 的 「HTTP to Dubbo」 能力进一步加强,并应用到所有已存在的 Dubbo Service 中。具体操作可参考下方: -1. 为已有项目增加一个 Dubbo Service 用来统一处理 HTTP to Dubbo 的转化。 +1. 为已有项目增加一个 Dubbo Service 用来统一处理 HTTP to Dubbo 的转化。方法定义如下: ```java public class DubboInvocationParameter { @@ -188,9 +227,12 @@ public class DubboInvocation { public interface HTTP2DubboService { Map invoke(Map context) throws Exception; } +``` +2. 提供服务实现并将其发布为标准的 Dubbo 服务。网关将所有流量都转发到这个服务,由这个服务在后端进程内完成调用转发。 -@Component +```java +@DubboService public class HTTP2DubboServiceImpl implements HTTP2DubboService { @Autowired @@ -216,12 +258,12 @@ public class HTTP2DubboServiceImpl implements HTTP2DubboService { } ``` -2. 通过如下命令请求来发起相关调用。 +3. 在 APISIX 中为 `HTTP2DubboService` 服务配置路由规则(此处省略)。接下来,就可以通过类似如下方式发起对后端 Dubbo 服务的调用了: ```shell curl http://127.0.0.1:9080/demo -H "Host: example.org" -X POST --data ' { - "service": "org.apache.dubbo.samples.apisix.DemoService", + "service": "org.apache.dubbo.samples.apisix.UserService", "method": "createUser", "parameters": [ { @@ -237,3 +279,5 @@ curl http://127.0.0.1:9080/demo -H "Host: example.org" -X POST --data ' 本文为大家介绍了如何借助 Apache APISIX 实现 Dubbo Service 的代理,通过引入 `dubbo-proxy` 插件便可为 Dubbo 框架的后端系统构建更简单更高效的流量链路。 希望通过上述操作步骤和用例场景分享,能为大家在相关场景的使用提供借鉴思路。更多关于 `dubbo-proxy` 插件的介绍与使用可参考[官方文档](https://apisix.apache.org/docs/apisix/plugins/dubbo-proxy/)。 + +关于这部分的更多示例,还可以参考 https://github.com/chickenlj/APISIX-Dubbo-Nacos diff --git a/content/zh-cn/blog/integration/how-to-proxy-dubbo-in-higress.md b/content/zh-cn/blog/integration/how-to-proxy-dubbo-in-higress.md index 5cf17a63ce7b..c20a2b324253 100644 --- a/content/zh-cn/blog/integration/how-to-proxy-dubbo-in-higress.md +++ b/content/zh-cn/blog/integration/how-to-proxy-dubbo-in-higress.md @@ -1,20 +1,25 @@ --- aliases: - /zh/overview/what/ecosystem/gateway/higress/ -description: "使用 Higress 作为 Dubbo 网关" +description: "使用 Higress 作为 Dubbo 网关,代理 dubbo 协议服务。" linkTitle: 如何通过 Higress 网关代理 Dubbo 服务 title: 如何通过 Higress 网关代理 Dubbo 服务 -date: 2023-04-01 +date: 2024-04-01 tags: ["网关", "生态"] --- +{{% alert title="注意" color="warning" %}} +本文仅适用于 dubbo 协议通信场景。如果您是 Dubbo3 用户,建议您使用 triple 协议,具体可参见 [使用 Apache APISIX 代理 Dubbo 服务(triple协议)](/zh-cn/overview/mannual/java-sdk/tasks/gateway/triple/) 学习具体示例。 +{{% /alert %}} -# Higress 对接 Dubbo 服务 Higress提供了从HTTP协议到Dubbo协议进行转换的功能,用户通过配置协议转换,可以将一个Dubbo服务以HTTP接口暴露出来,从而用HTTP请求实现对Dubbo接口的调用。本文将通过一个示例来介绍如何用Higress配置HTTP到Dubbo的协议转换。该示例会引导您轻松地部署一个Nacos server和一个Dubbo服务,然后通过Ingress将HTTP请求转发到注册在Nacos上的Dubbo服务,并通过Higress的协议转换能力完成对Dubbo服务的HTTP调用。 + + +以下是一个使用 `Higress + dubbo协议 + Nacos注册中心` 的完整示例:[dubbo-samples-gateway-higress-dubbo](https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-gateway/dubbo-samples-gateway-higress/dubbo-samples-gateway-higress-dubbo)。 + ## 前提条件 -1. Higress目前支持的Dubbo框架的版本为2.x。若您使用Dubbo3.0,要求使用dubbo协议(目前暂不支持Triple协议)。 -2. 已安装Higress,并开启了对Istio CRD的支持,参考[Higress安装部署文档](https://higress.io/zh-cn/docs/ops/deploy-by-helm)。 +1. 已安装Higress,并开启了对Istio CRD的支持,参考[Higress安装部署文档](https://higress.io/zh-cn/docs/ops/deploy-by-helm)。 ## 部署Nacos和Dubbo服务 @@ -65,7 +70,7 @@ spec: app: nacos-server type: ClusterIP ``` -在K8s集群中apply以下资源,以部署一个Dubbo服务,该Dubbo服务将注册到上述的Naocs中。 +在 K8s 集群中 apply 以下资源,以部署一个Dubbo服务,该 Dubbo 服务将注册到上述的 Naocs 中(你可以选择重新打包,我们接下来直接使用社区提前准备好的镜像包)。 ```yaml apiVersion: apps/v1 kind: Deployment @@ -91,59 +96,44 @@ spec: - name: DUBBO_REGISTRY_ADDRESS value: nacos-server.default.svc.cluster.local ``` -该Dubbo服务的代码可以在Nacos的[示例代码](https://github.com/nacos-group/nacos-examples/tree/master/nacos-dubbo-example)仓库中找到,其接口定义为: +该Dubbo服务的代码可以在 [dubbo-samples-gateway-higress-dubbo](https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-gateway/dubbo-samples-gateway-higress/dubbo-samples-gateway-higress-dubbo) 仓库中找到,其接口定义为: ```java -package com.alibaba.nacos.example.dubbo.service; +package org.apache.dubbo.samples.gateway.api; public interface DemoService { - String sayName(String name); + String sayHello(String name); } ``` 接口实现如下: ```java -package com.alibaba.nacos.example.dubbo.service; - -import com.alibaba.dubbo.config.annotation.Service; -import com.alibaba.dubbo.rpc.RpcContext; -import org.springframework.beans.factory.annotation.Value; - -/** - * Default {@link DemoService} - * https://nacos.io/zh-cn/docs/use-nacos-with-dubbo.html - * @since 2.6.5 - */ @Service(version = "${demo.service.version}", group = "${demo.service.group}") -public class DefaultService implements DemoService { - - @Value("${demo.service.name}") - private String serviceName; - - public String sayName(String name) { - RpcContext rpcContext = RpcContext.getContext(); - return String.format("Service [name :%s , port : %d] %s(\"%s\") : Hello,%s", - serviceName, - rpcContext.getLocalPort(), - rpcContext.getMethodName(), - name, - name); +public class DemoServiceImpl implements DemoService { + @Override + public String sayHello(String name) { + return "Hello " + name; } } ``` -在本示例中,该Dubbo服务的服务名为com.alibaba.nacos.example.dubbo.service.DemoService,服务版本为1.0.0,服务分组为dev。 +在本示例中,该Dubbo服务的服务名为 `org.apache.dubbo.samples.gateway.api.DemoService`,服务版本为 `1.0.0`,服务分组为 `dev`。 + +为了测试方便,我们可以通过运行以下命令来将我们部署在 K8S 集群中的 Naocs 服务映射到本地端口: -为了测试方便,我们可以通过运行以下命令来将我们部署在K8s集群中的Naocs服务映射到本地端口: ```bash kubectl port-forward svc/nacos-server 8848:8848 --address='0.0.0.0' ``` + 然后请求Nacos的服务发现接口,可以查看到我们Dubbo服务的元数据信息,从而对以上部署进行验证。 + ```bash -$curl -X GET 'http://127.0.0.1:8848/nacos/v1/ns/instance/list?serviceName=providers:com.alibaba.nacos.example.dubbo.service.DemoService:1.0.0:dev' +$ curl -X GET 'http://127.0.0.1:8848/nacos/v1/ns/instance/list?serviceName=providers:com.alibaba.nacos.example.dubbo.service.DemoService:1.0.0:dev' + {"name":"DEFAULT_GROUP@@providers:com.alibaba.nacos.example.dubbo.service.DemoService:1.0.0:dev","groupName":"DEFAULT_GROUP","clusters":"","cacheMillis":10000,"hosts":[{"ip":"10.244.0.58","port":20880,"weight":1.0,"healthy":true,"enabled":true,"ephemeral":true,"clusterName":"DEFAULT","serviceName":"DEFAULT_GROUP@@providers:com.alibaba.nacos.example.dubbo.service.DemoService:1.0.0:dev","metadata":{"side":"provider","release":"dubbo_demo","methods":"sayName","deprecated":"false","dubbo":"2.0.2","pid":"3034042","interface":"com.alibaba.nacos.example.dubbo.service.DemoService","service-name-mapping":"true","version":"1.0.0","generic":"false","revision":"dubbo_demo","path":"com.alibaba.nacos.example.dubbo.service.DemoService","protocol":"dubbo","metadata-type":"remote","application":"dubbo-provider-demo","background":"false","dynamic":"true","category":"providers","group":"dev","anyhost":"true","timestamp":"1680176973875"},"ipDeleteTimeout":30000,"instanceHeartBeatInterval":5000,"instanceHeartBeatTimeOut":15000}],"lastRefTime":1680178336936,"checksum":"","allIPs":false,"reachProtectionThreshold":false,"valid":true}% ``` ## 通过Ingress转发请求到Dubbo服务 -Higress可以通过McpBridge来对接Nacos作为服务来源,在K8s集群中apply以下资源来配置McpBridge +Higress 可以通过 McpBridge 来对接 Nacos 作为服务来源,在 K8s 集群中 apply 以下资源来配置 McpBridge + ```yaml apiVersion: networking.higress.io/v1 kind: McpBridge @@ -159,15 +149,17 @@ spec: port: 8848 type: nacos2 ``` + 通过McpBridge,我们可以直接从Nacos中发现Dubbo服务,并为其创建路由,而无需为每一个Dubbo服务创建service资源。 接下来我们创建如下Ingress,从而创建一条指向Dubbo服务的HTTP路由: + ```yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: - higress.io/destination: providers:com.alibaba.nacos.example.dubbo.service.DemoService:1.0.0:dev.DEFAULT-GROUP.public.nacos + higress.io/destination: gateway-higress-dubbo-provider.DEFAULT-GROUP.public.nacos name: demo namespace: higress-system spec: @@ -183,12 +175,24 @@ spec: path: /dubbo pathType: Prefix ``` -这样,path前缀为/dubbo的请求就会被路由到我们刚刚创建的Dubbo服务上。 + +这样,path前缀为 `/dubbo` 的请求就会被路由到我们刚刚创建的 Dubbo 服务上。 + + +{{% alert title="注意" color="info" %}} +以上 `higress.io/destination` 用来指定本路由的地址来源,它使用 `服务名称.服务分组.命名空间ID.nacos` 的固定格式,其中, +* `服务名称` 可以是应用名或者接口名,Dubbo3 建议直接配置应用名,只有使用接口级服务发现时配置接口名,其格式为完整 `nacos dataid`,如 `providers:{service-name}:{version}:{group}` +* `服务分组`,nacos 分组,未明确设置时,使用 `DEFAULT-GROUP` 即可。注意这里需要遵循 DNS 域名格式,因此服务分组中的下划线'_'被转换成了横杠'-' +* `命名空间ID`,nacos 命空间,未明确设置时,使用 `public` 即可 +* `nacos`,使用固定值 `nacos` 代表数据来源 +{{% /alert %}} ## 通过EnvoyFilter配置HTTP到Dubbo的协议转换规则 + 经过上述步骤,我们已经在K8s环境下部署了一套Naocs和Dubbo,并通过Ingress将path前缀为/dubbo的请求路由到我们配好的Dubbo服务上。但光是这样是无法正常通信的,因为Dubbo服务使用的是定制的Dubbo协议,无法天然与HTTP协议进行兼容。因此接下来我们将通过EnvoyFilter来配置HTTP到Dubbo的协议转换规则,从而实现用HTTP请求来调用Dubbo服务。 在K8s集群中apply以下资源,要注意的是,EnvoyFilter是属于Istio的CRD,因此需要参照前提条件中的第2点来开启Higress对Istio CRD的支持。 + ```yaml apiVersion: networking.istio.io/v1alpha3 kind: EnvoyFilter @@ -249,13 +253,13 @@ spec: path_matcher: match_http_method_spec: ALL_GET match_pattern: /dubbo/hello - name: com.alibaba.nacos.example.dubbo.service.DemoService + name: org.apache.dubbo.samples.gateway.api.DemoService version: 1.0.0 url_unescape_spec: ALL_CHARACTERS_EXCEPT_RESERVED - applyTo: CLUSTER match: cluster: - service: providers:com.alibaba.nacos.example.dubbo.service.DemoService:1.0.0:dev.DEFAULT-GROUP.public.nacos + service: gateway-higress-dubbo.DEFAULT-GROUP.public.nacos context: GATEWAY patch: operation: MERGE @@ -269,11 +273,14 @@ spec: 在以上EnvoyFilter中,我们配置了将path为/dubbo/hello的HTTP请求转发到Dubbo服务com.alibaba.nacos.example.dubbo.service.DemoService:1.0.0:dev中,并调用其sayName方法,而该方法的参数则通过HTTP url中的的query参数p来指定。 ## 请求验证 + 通过以上配置,我们就可以执行以下curl命令来调用这个dubbo服务了: ```bash $curl "localhost/dubbo/hello?p=abc" {"result":"Service [name :demoService , port : 20880] sayName(\"abc\") : Hello,abc"} ``` -## 配置参考 -EnvoyFilter的相关配置项参考[HTTP转Dubbo配置说明](https://higress.io/zh-cn/docs/user/dubbo-envoyfilter) \ No newline at end of file +## 参考资料 + +* EnvoyFilter的相关配置项参考[HTTP转Dubbo配置说明](https://higress.io/zh-cn/docs/user/dubbo-envoyfilter) +* 完整示例源码 [dubbo-samples-gateway-higress-dubbo](https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-gateway/dubbo-samples-gateway-higress/dubbo-samples-gateway-higress-dubbo) \ No newline at end of file diff --git a/content/zh-cn/blog/java/codeanalysis/multiple-protocols-on-one-port.md b/content/zh-cn/blog/java/codeanalysis/multiple-protocols-on-one-port.md new file mode 100644 index 000000000000..0e7e83f2503b --- /dev/null +++ b/content/zh-cn/blog/java/codeanalysis/multiple-protocols-on-one-port.md @@ -0,0 +1,135 @@ +--- +aliases: + - /zh/overview/tasks/protocols/multi-protocols/ + - /zh-cn/overview/tasks/protocols/multi-protocols/ +description: "" +linkTitle: 单端口多协议 +title: 发布使用不同协议的多个服务,通过单端口监听 +date: 2024-3-19 +author: 陈景明 +tags: ["源码解析", "协议"] +description: > + Dubbo3 框架支持在单个端口发布多个不同的协议,比如可以同时发布 dubbo、triple 协议,本文介绍 Dubbo 是如何实现单端口多协议发布的。 +--- + + +通过对protocol进行配置,dubbo3可以支持端口的协议复用。 +比如使用Triple协议启动端口复用后,可以在相同的端口上为服务增加 +Dubbo协议支持,以及Qos协议支持。这些协议的识别都是由一个统一的端口复用 +服务器进行处理的,可以用于服务的协议迁移,并且可以节约端口以及相关的资源,减少运维的复杂性。 + +![pu-server-image1](/imgs/blog/pu-server/pu-server-flow.png) + +- 在服务的创建阶段,通过从Config层获取到服务导出的协议配置从而创建不同的Protocol对象进行导出。在导出的过程 +中,如果不是第一次创建端口复用的Server,那么Exchanger会将Protcol层传递的数据保存到Server,用于后续处理该协议类型的消息。 + +- 当客户端的消息传递过来后,首先会通过Server传递给ProtocolDetector,如果完成了识别,那么就会标记该客户端为对应的协议。并通过WireProtocol配置对应的处理逻辑,最后交给ChannelOperator完成底层的IO框架和对应的Dubbo框架的处理逻辑的绑定。 + +- 以上的协议识别完成之后,Channel已经确定了如何处理远程的客户端消息,通过对应的ServerPipeline进行处理即可(在处理的过程中也会根据配置信息决定消息的处理线程)。 + +## 使用方式 +在同一主机上部署多个服务或需要通过负载均衡器访问多个服务。 + +## 参考用例 +[https://github.com/apache/dubbo-samples/tree/master/dubbo-samples-port-unification](https://github.com/apache/dubbo-samples/tree/master/3-extensions/protocol/dubbo-samples-port-unification) + + +## 配置方式 + +关于Dubbo支持的配置方式,可以参考[配置说明](/zh-cn/overview/mannual/java-sdk/reference-manual/config/) + +### 服务多协议导出 + +ext-protocol参数支持配置多个不同的协议,协议之间通过","进行分隔。 + +#### xml 配置 + +```xml + + + + + + +``` + +#### API 配置 + +```java +ProtocolConfig config = new ProtocolConfig(CommonConstants.TRIPLE, -1); + +config.setExtProtocol(CommonConstants.DUBBO+","); +``` + +#### yaml 配置 + +``` yaml +dubbo: + application: + name: dubbo-springboot-demo-provider + protocol: + name: tri + port: -1 + ext-protocol: dubbo, +``` + +#### properties 配置 +```properties +dubbo.protocol.name=tri +dubbo.protocol.ext-protocol=dubbo, +dubbo.protocol.port=20880 +``` + +### Qos接入 + +#### Qos模块导入 + +```xml + + org.apache.dubbo + dubbo-qos + +``` + +完成Qos模块的导入之后,相关的配置项可参考[Qos操作手册](/zh-cn/overview/mannual/java-sdk/reference-manual/qos/overview/)进行配置。 + +默认情况下,基于端口复用的Qos服务在模块导入后是启动的。 + +## 使用方式 + +### Qos使用 + +将Qos协议接入到端口复用的场景下,需要在建立连接之后,客户端先向服务端发送消息,对比将Qos协议通过单个端口提供服务,端口复用版的Qos协议在处理telnet连接的情况下需要用户执行一些操作,完成协议识别(二选一)。 + +1. 直接调用命令 + + 直接调用telnet支持的命令也可以完成识别,在用户不熟悉的情况下可以调用help指令完成识别 + + ![pu-server-image2](/imgs/blog/pu-server/qos-telnet-directcall.png) + +2. 发送telnet命令识别 + + 通过telnet命令建立连接之后,执行以下几个步骤: + + 1. 使用 crtl + "]" 进入到telnet交互界面(telnet默认的escape character) + 2. 调用 "send ayt" 向服务端发送特殊识别字段(为telnet协议的一个特殊字段) + 3. 回车完成消息发送并进入到dubbo的交互界面 + + ![pu-server-imgs3](/imgs/blog/pu-server/qos-telnet-sendayt.png) + + +### 服务引用 + +以[dubbo-samples-port-unification](https://github.com/apache/dubbo-samples/tree/master/3-extensions/protocol/dubbo-samples-port-unification)中的例子作为基础, 引用不同协议的服务和非端口复用情况下的配置是一致的,下面通过Consumer端的InvokerListener输出调用过程中的URL信息。 + +```java +ReferenceConfig reference = new ReferenceConfig<>(); +reference.setInterface(GreetingService.class); +reference.setListener("consumer"); +reference.setProtocol(this.protocol); +// reference.setProtocol(CommonConstants.DUBBO); +// reference.setProtocol(CommonConstants.TRIPLE); +``` + +![pu-server-imgs4](/imgs/blog/pu-server/reference-service.png) + diff --git a/content/zh-cn/blog/java/demos/dubbo-supporting-grpc-http2-and-protobuf.md b/content/zh-cn/blog/java/demos/dubbo-supporting-grpc-http2-and-protobuf.md index 4fba2d8bd7a0..59688dee84ed 100644 --- a/content/zh-cn/blog/java/demos/dubbo-supporting-grpc-http2-and-protobuf.md +++ b/content/zh-cn/blog/java/demos/dubbo-supporting-grpc-http2-and-protobuf.md @@ -228,7 +228,7 @@ pluginArtifact 指定了 Dubbo 定制版本的 Java Protobuf Compiler 插件, org.apache.dubbo:protoc-gen-dubbo-java:1.19.0-SNAPSHOT:exe:${os.detected.classifier} ``` -由于 `protoc-gen-dubbo-java` 支持 gRPC 和 Dubbo 两种协议,可生成的 stub 类型,默认值是 gRPC,关于 dubbo 协议的使用可参见 [使用 Protobuf 开发 Dubbo 服务](/zh-cn/overview/mannual/java-sdk/quick-start/idl/)。 +由于 `protoc-gen-dubbo-java` 支持 gRPC 和 Dubbo 两种协议,可生成的 stub 类型,默认值是 gRPC,关于 dubbo 协议的使用可参见 [使用 Protobuf 开发 Dubbo 服务](/zh-cn/overview/mannual/java-sdk/quick-start/)。 ```xml grpc @@ -515,7 +515,7 @@ default=org.apache.dubbo.samples.basic.comtomize.MyGrpcConfigurator **三、TLS 配置** -配置方式和 Dubbo 提供的通用的 [TLS 支持](/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/security/tls/)一致,具体请参见文档 +配置方式和 Dubbo 提供的通用的 [TLS 支持](/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/tls/)一致,具体请参见文档 diff --git a/content/zh-cn/blog/java/demos/hystrix.md b/content/zh-cn/blog/java/demos/hystrix.md new file mode 100644 index 000000000000..3551eace3753 --- /dev/null +++ b/content/zh-cn/blog/java/demos/hystrix.md @@ -0,0 +1,189 @@ +--- +aliases: + - /zh-cn/overview/what/ecosystem/rate-limit/hystrix/ + - /zh/overview/tasks/rate-limit/hystrix/ + - /zh-cn/overview/tasks/rate-limit/hystrix/ +description: "使用 Hystrix 对 Dubbo 服务进行熔断限流保护" +linkTitle: 待整合-Hystrix 熔断降级 +title: 使用 Hystrix 对 Dubbo 服务进行熔断限流保护 +tags: ["Java", "Hystrix", "限流降级"] +date: 2023-12-14 +--- + +## 背景 + +Hystrix 旨在通过控制那些访问远程系统、服务和第三方库的节点,从而对延迟和故障提供更强大的容错能力。Hystrix具备拥有回退机制和断路器功能的线程和信号隔离,请求缓存和请求打包,以及监控和配置等功能。 + +本文介绍在spring应用里,怎么把 Dubbo 和 Hystrix 结合起来使用。 + +- +- + +## Spring Boot应用 + +Demo 地址: + +### 生成dubbo集成spring boot的应用 + +对于不熟悉dubbo 集成spring boot应用的同学,可以在这里直接生成dubbo + spring boot的工程: + +### 配置spring-cloud-starter-netflix-hystrix + +spring boot官方提供了对hystrix的集成,直接在pom.xml里加入依赖: + +```xml + + org.springframework.cloud + spring-cloud-starter-netflix-hystrix + 1.4.4.RELEASE + +``` + +然后在Application类上增加`@EnableHystrix`来启用hystrix starter: + +```java +@SpringBootApplication +@EnableHystrix +public class ProviderApplication { +``` +### 配置Provider端 +在Dubbo的Provider上增加`@HystrixCommand`配置,这样子调用就会经过Hystrix代理。 +```java +@Service(version = "1.0.0") +public class HelloServiceImpl implements HelloService { + @HystrixCommand(commandProperties = { + @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"), + @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "2000") }) + @Override + public String sayHello(String name) { + // System.out.println("async provider received: " + name); + // return "annotation: hello, " + name; + throw new RuntimeException("Exception to show hystrix enabled."); + } +} +``` +### 配置Consumer端 +对于Consumer端,则可以增加一层method调用,并在method上配置`@HystrixCommand`。当调用出错时,会走到`fallbackMethod = "reliable"`的调用里。 +```java + @Reference(version = "1.0.0") + private HelloService demoService; + @HystrixCommand(fallbackMethod = "reliable") + public String doSayHello(String name) { + return demoService.sayHello(name); + } + public String reliable(String name) { + return "hystrix fallback value"; + } +``` +通过上面的配置,很简单地就完成了Spring Boot里Dubbo + Hystrix的集成。 +## 传统Spring Annotation应用 +Demo地址: +传统spring annotation应用的配置其实也很简单,和spring boot应用不同的是: +1. 显式配置Spring AOP支持:`@EnableAspectJAutoProxy` +2. 显式通过`@Configuration`配置`HystrixCommandAspect` Bean。 +```java + @Configuration + @EnableDubbo(scanBasePackages = "com.alibaba.dubbo.samples.annotation.action") + @PropertySource("classpath:/spring/dubbo-consumer.properties") + @ComponentScan(value = {"com.alibaba.dubbo.samples.annotation.action"}) + @EnableAspectJAutoProxy + static public class ConsumerConfiguration { + @Bean + public HystrixCommandAspect hystrixCommandAspect() { + return new HystrixCommandAspect(); + } + } +``` +## Hystrix集成Spring AOP原理 +在上面的例子里可以看到,Hystrix对Spring的集成是通过Spring AOP来实现的。下面简单分析下实现。 +```java +@Aspect +public class HystrixCommandAspect { + @Pointcut("@annotation(com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand)") + public void hystrixCommandAnnotationPointcut() { + } + @Pointcut("@annotation(com.netflix.hystrix.contrib.javanica.annotation.HystrixCollapser)") + public void hystrixCollapserAnnotationPointcut() { + } + @Around("hystrixCommandAnnotationPointcut() || hystrixCollapserAnnotationPointcut()") + public Object methodsAnnotatedWithHystrixCommand(final ProceedingJoinPoint joinPoint) throws Throwable { + Method method = getMethodFromTarget(joinPoint); + Validate.notNull(method, "failed to get method from joinPoint: %s", joinPoint); + if (method.isAnnotationPresent(HystrixCommand.class) && method.isAnnotationPresent(HystrixCollapser.class)) { + throw new IllegalStateException("method cannot be annotated with HystrixCommand and HystrixCollapser " + + "annotations at the same time"); + } + MetaHolderFactory metaHolderFactory = META_HOLDER_FACTORY_MAP.get(HystrixPointcutType.of(method)); + MetaHolder metaHolder = metaHolderFactory.create(joinPoint); + HystrixInvokable invokable = HystrixCommandFactory.getInstance().create(metaHolder); + ExecutionType executionType = metaHolder.isCollapserAnnotationPresent() ? + metaHolder.getCollapserExecutionType() : metaHolder.getExecutionType(); + Object result; + try { + if (!metaHolder.isObservable()) { + result = CommandExecutor.execute(invokable, executionType, metaHolder); + } else { + result = executeObservable(invokable, executionType, metaHolder); + } + } catch (HystrixBadRequestException e) { + throw e.getCause() != null ? e.getCause() : e; + } catch (HystrixRuntimeException e) { + throw hystrixRuntimeExceptionToThrowable(metaHolder, e); + } + return result; + } +``` +1. `HystrixCommandAspect`里定义了两个注解的AspectJ Pointcut:`@HystrixCommand`, `@HystrixCollapser`。所有带这两个注解的spring bean都会经过AOP处理 +2. 在`@Around` AOP处理函数里,可以看到Hystrix会创建出`HystrixInvokable`,再通过`CommandExecutor`来执行 +## spring-cloud-starter-netflix-hystrix的代码分析 +1. `@EnableHystrix` 引入了`@EnableCircuitBreaker`,`@EnableCircuitBreaker`引入了`EnableCircuitBreakerImportSelector` + ```java + @EnableCircuitBreaker + public @interface EnableHystrix { + } + + @Import(EnableCircuitBreakerImportSelector.class) + public @interface EnableCircuitBreaker { + } + ``` +2. `EnableCircuitBreakerImportSelector`继承了`SpringFactoryImportSelector`,使spring加载`META-INF/spring.factories`里的`EnableCircuitBreaker`声明的配置 + 在`META-INF/spring.factories`里可以找到下面的配置,也就是引入了`HystrixCircuitBreakerConfiguration`。 + ```properties + org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker=\ + org.springframework.cloud.netflix.hystrix.HystrixCircuitBreakerConfiguration + ``` +3. 在`HystrixCircuitBreakerConfiguration`里可以发现创建了`HystrixCommandAspect` + ```java + @Configuration + public class HystrixCircuitBreakerConfiguration { + + @Bean + public HystrixCommandAspect hystrixCommandAspect() { + return new HystrixCommandAspect(); + } + ``` +可见`spring-cloud-starter-netflix-hystrix`实际上也是创建了`HystrixCommandAspect`来集成Hystrix。 +另外`spring-cloud-starter-netflix-hystrix`里还有metrics, health, dashboard等集成。 + +## 总结 +- 对于dubbo provider的`@Service`是一个spring bean,直接在上面配置`@HystrixCommand`即可 +- 对于dubbo consumer的`@Reference`,可以通过加一层简单的spring method包装,配置`@HystrixCommand`即可 +- Hystrix本身提供`HystrixCommandAspect`来集成Spring AOP,配置了`@HystrixCommand`和`@HystrixCollapser`的spring method都会被Hystrix处理 + +### Sentinel 与 Hystrix 的比较 + +目前业界常用的熔断降级/隔离的库是 Netflix 的 [Hystrix](https://github.com/Netflix/Hystrix),那么 Sentinel 与 Hystrix 有什么异同呢?Hystrix 的关注点在于以 _隔离_ 和 _熔断_ 为主的容错机制,而 Sentinel 的侧重点在于多样化的流量控制、熔断降级、系统负载保护、实时监控和控制台,可以看到解决的问题还是有比较大的不同的。 + +Hystrix 采用命令模式封装资源调用逻辑,并且资源的定义与隔离规则是强依赖的,即在创建 HystrixCommand 的时候就要指定隔离规则(因其执行模型依赖于隔离模式)。Sentinel 的设计更为简单,不关注资源是如何执行的,资源的定义与规则的配置相分离。用户可以先定义好资源,然后在需要的时候配置规则即可。Sentinel 的原则非常简单:根据对应资源配置的规则来为资源执行相应的限流/降级/负载保护策略,若规则未配置则仅进行统计。从 0.1.1 版本开始,Sentinel 还引入了[注解支持](https://github.com/alibaba/Sentinel/wiki/%E6%B3%A8%E8%A7%A3%E6%94%AF%E6%8C%81),可以更方便地定义资源。 + +隔离是 Hystrix 的核心功能。Hystrix 通过线程池或信号量的方式来对依赖(即 Sentinel 中对应的资源)进行隔离,其中最常用的是资源隔离。Hystrix 线程池隔离的好处是比较彻底,但是不足之处在于要开很多线程池,在应用本身线程数目比较多的时候上下文切换的 overhead 会非常大;Hystrix 的信号量隔离模式可以限制调用的并发数而不显式创建线程,这样的方式比较轻量级,但缺点是无法对慢调用自动进行降级,只能等待客户端自己超时,因此仍然可能会出现级联阻塞的情况。Sentinel 可以通过并发线程数模式的流量控制来提供信号量隔离的功能。并且结合基于响应时间的熔断降级模式,可以在不稳定资源的平均响应时间比较高的时候自动降级,防止过多的慢调用占满并发数,影响整个系统。 + +Hystrix 熔断降级功能采用熔断器模式,在某个服务失败比率高时自动进行熔断。Sentinel 的熔断降级功能更为通用,支持平均响应时间与失败比率两个指标。Sentinel 还提供各种调用链路关系和流量控制效果支持,同时还可以根据系统负载去实时地调整流量来保护系统,应用场景更为丰富。同时,Sentinel 还提供了实时的监控 API 和控制台,可以方便用户快速了解目前系统的状态,对服务的稳定性了如指掌。 + +更详细的对比请参见 [Sentinel 与 Hystrix 的对比](https://github.com/alibaba/Sentinel/wiki/Sentinel-%E4%B8%8E-Hystrix-%E7%9A%84%E5%AF%B9%E6%AF%94)。 + +### 链接 +- +- +- +- diff --git a/content/zh-cn/blog/java/demos/resilience4j.md b/content/zh-cn/blog/java/demos/resilience4j.md new file mode 100644 index 000000000000..797b88f19258 --- /dev/null +++ b/content/zh-cn/blog/java/demos/resilience4j.md @@ -0,0 +1,14 @@ +--- +aliases: + - /zh/overview/tasks/rate-limit/resilience4j/ + - /zh-cn/overview/tasks/rate-limit/resilience4j/ +description: "使用 Resilience4j 断路器、限流器、重试、隔离机制保护 Dubbo 应用" +linkTitle: Resilience4j +title: 使用 Resilience4j 断路器、限流器、重试、隔离机制保护 Dubbo 应用 +tags: ["Java", "Resilience4j", "限流降级"] +date: 2023-12-14 +--- + +Resilience4j 提供了一组高阶函数(装饰器),包括断路器,限流器,重试,隔离,可以对任何的函数式接口,lambda表达式,或方法的引用进行增强,并且这些装饰器可以进行叠加。这样做的好处是,你可以根据需要选择特定的装饰器进行组合。 + +关于 Resilience4j 与 Dubbo 集成的使用示例请参见 [dubbo-samples-resilience4j](https://github.com/apache/dubbo-samples/tree/master/3-extensions/protocol/dubbo-samples-resilience4j) diff --git a/content/zh-cn/blog/java/proposals/_index.md b/content/zh-cn/blog/java/proposals/_index.md new file mode 100644 index 000000000000..cfafe94c7d75 --- /dev/null +++ b/content/zh-cn/blog/java/proposals/_index.md @@ -0,0 +1,7 @@ +--- +title: "方案设计" +linkTitle: "方案设计" +weight: 30 +--- + + diff --git a/content/zh-cn/blog/java/proposals/service-discovery-migration.md b/content/zh-cn/blog/java/proposals/service-discovery-migration.md new file mode 100644 index 000000000000..9716a859dbfe --- /dev/null +++ b/content/zh-cn/blog/java/proposals/service-discovery-migration.md @@ -0,0 +1,401 @@ +--- +aliases: + - /zh-cn/overview/mannual/java-sdk/upgrades-and-compatibility/service-discovery/migration-service-discovery/ +title: "如果从接口级服务发现平滑迁移到应用级服务发现" +linkTitle: "Dubbo3 服务发现平滑迁移步骤与原理" +tags: ["Java","服务发现"] +date: 2024-05-13 +description: > + "Dubbo3 应用级服务发现迁移详情,如果从接口级服务发现平滑迁移到应用级服务发现,迁移规则详情与工作原理。" +--- + +总体上来说,在地址注册与发现环节,`3.x` 是完全兼容 `2.x` 版本的,这意味着,用户可以选择将集群内任意数量的应用或机器升级到 `3.x`,同时在这个过程中保持与 `2.x` 版本的互操作性。 + +> 如关心迁移背后工作原理,请参考 [迁移规则详情与工作原理](../service-discovery-rule) + +## 1 快速升级步骤 + +简单的修改 pom.xml 到最新版本就可以完成升级,如果要迁移到应用级地址,只需要调整开关控制 3.x 版本的默认行为。 + +1. 升级 Provider 应用到最新 3.x 版本依赖,配置双注册开关`dubbo.application.register-mode=all`(建议通过全局配置中心设置,默认已自动开启),完成应用发布。 +2. 升级 Consumer 应用到最新 3.x 版本依赖,配置双订阅开关`dubbo.application.service-discovery.migration=APPLICATION_FIRST`(建议通过全局配置中心设置,默认已自动开启),完成应用发布。 +3. 在确认 Provider 的上有 Consumer 全部完成应用级地址迁移后,Provider 切到应用级地址单注册。完成升级 + + + +以下是关于迁移流程的详细描述。 + +## 2 Provider 端升级过程详解 + +在不改变任何 Dubbo 配置的情况下,可以将一个应用或实例升级到 3.x 版本,升级后的 Dubbo 实例会默保保证与 2.x 版本的兼容性,即会正常注册 2.x 格式的地址到注册中心,因此升级后的实例仍会对整个集群仍保持可见状态。 + +同时新的地址发现模型(注册应用级别的地址)也将会自动注册。 + +![//imgs/v3/migration/provider-registration.png](/imgs/v3/migration/provider-registration.png) + +1. 全局开关 + +应用配置(可以通过配置文件或者 -D 指定)`dubbo.application.register-mode` 为 instance(只注册应用级)、all(接口级+应用级均注册)开启全局的注册开关,配置此开关后,默认会向所有的注册中心中注册应用级的地址,供消费端服务发现使用。 + +``` +# 双注册 +dubbo.application.register-mode=all +``` +``` +# 仅应用级注册 +dubbo.application.register-mode=instance +``` +通过 -D 参数,可以指定 provider 启动时的注册行为 + +```text +-Ddubbo.application.register-mode=all +# 可选值 interface、instance、all,默认是 all,即接口级地址、应用级地址都注册 +``` + +另外,可以在配置中心修改全局默认行为,来控制所有 3.x 实例注册行为。其中,全局性开关的优先级低于 -D 参数。 + +2. 注册中心地址参数配置 + +注册中心的地址上可以配置 `registry-type=service` 来显示指定该注册中心为应用级服务发现的注册中心,带上此配置的注册中心将只进行应用级服务发现。 +> [参考示例](https://github.com/apache/dubbo-samples/blob/master/2-advanced/dubbo-samples-service-discovery/dubbo-demo-servicediscovery-xml/servicediscovery-provider/src/main/resources/spring/dubbo-provider.xml) + +```xml + +``` + +为了保证平滑迁移,即升级到 3.x 的实例能同时被 2.x 与 3.x 的消费者实例发现,3.x 实例需要开启双注册;当所有上游的消费端都迁移到 3.x 的地址模型后,提供端就可以切换到 instance 模式(只注册应用级地址)。对于如何升级消费端到 3.x 请参见下一小节。 + +### 2.1 双注册带来的资源消耗 + +双注册不可避免的会带来额外的注册中心存储压力,但考虑到应用级地址发现模型的数据量在存储方面的极大优势,即使对于一些超大规模集群的用户而言,新增的数据量也并不会带来存储问题。总体来说,对于一个普通集群而言,数据增长可控制在之前数据总量的 1/100 ~ 1/1000 + +以一个中等规模的集群实例来说: 2000 实例、50个应用(500 个 Dubbo 接口,平均每个应用 10 个接口)。 + +​ 假设每个接口级 URL 地址平均大小为 5kb,每个应用级 URL 平均大小为 0.5kb + +​ 老的接口级地址量:2000 * 500 * 5kb ≈ 4.8G + +​ 新的应用级地址量:2000 * 50 * 0.5kb ≈ 48M + +​ 双注册后仅仅增加了 48M 的数据量。 + + + +## 3 Consumer 端升级过程 + +对于 2.x 的消费者实例,它们看到的自然都是 2.x 版本的提供者地址列表; + +对于 3.x 的消费者,它具备同时发现 2.x 与 3.x 提供者地址列表的能力。在默认情况下,如果集群中存在可以消费的 3.x 的地址,将自动消费 3.x 的地址,如果不存在新地址则自动消费 2.x 的地址。Dubbo3 提供了开关来控制这个行为: + +```text +dubbo.application.service-discovery.migration=APPLICATION_FIRST +# 可选值 +# FORCE_INTERFACE,只消费接口级地址,如无地址则报错,单订阅 2.x 地址 +# APPLICATION_FIRST,智能决策接口级/应用级地址,双订阅 +# FORCE_APPLICATION,只消费应用级地址,如无地址则报错,单订阅 3.x 地址 +``` + +![//imgs/v3/migration/consumer-subscription.png](/imgs/v3/migration/consumer-subscription.png) + +1. 默认配置(不需要配置) + +升级到 Dubbo 3.0 后默认行为为接口级+应用级多订阅,如果应用级能订阅到地址就使用应用级的订阅,如果订阅不到地址则使用接口级的订阅,以此保证最大的兼容性。 + +2. 订阅参数配置 + +应用配置(可以通过配置文件或者 -D 指定)`dubbo.application.service-discovery.migration` 为 `APPLICATION_FIRST` 可以开启多订阅模式,配置为 `FORCE_APPLICATION` 可以强制为仅应用级订阅模式。 +具体接口订阅可以在 `ReferenceConfig` 中的 `parameters` 中配置 Key 为 `migration.step`,Value 为 `APPLICATION_FIRST` 或 `FORCE_APPLICATION` 的键值对来对单一订阅进行配置。 + +`dubbo.application.service-discovery.migration ` 支持通过 `-D` 以及 `全局配置中心` 两种方式进行配置。 + +> [参考示例](https://github.com/apache/dubbo-samples/blob/master/2-advanced/dubbo-samples-service-discovery/dubbo-servicediscovery-migration/dubbo-servicediscovery-migration-consumer/src/test/java/org/apache/dubbo/demo/consumer/DemoServiceConfigIT.java) + +```java +System.setProperty("dubbo.application.service-discovery.migration", "APPLICATION_FIRST"); +``` +```java +ReferenceConfig referenceConfig = new ReferenceConfig<>(applicationModel.newModule()); +referenceConfig.setInterface(DemoService.class); +referenceConfig.setParameters(new HashMap<>()); +referenceConfig.getParameters().put("migration.step", mode); +return referenceConfig.get(); +``` + +3. 动态配置(优先级最高,可以在运行时修改配置) + +此配置需要基于配置中心进行推送,Key 为应用名 + `.migration` (如 `demo-application.migraion`),Group 为 `DUBBO_SERVICEDISCOVERY_MIGRATION`。规则体配置详见[接口级服务发现迁移至应用级服务发现指南](../migration-service-discovery/)。 +> [参考示例](https://github.com/apache/dubbo-samples/blob/master/2-advanced/dubbo-samples-service-discovery/dubbo-servicediscovery-migration/dubbo-servicediscovery-migration-consumer/src/main/java/org/apache/dubbo/demo/consumer/UpgradeUtil.java) + +```java +step: FORCE_INTERFACE +``` + + +接下来,我们就具体看一下,如何通过双订阅模式(APPLICATION_FIRST)让升级到 3.x 的消费端迁移到应用级别的地址。在具体展开之前,先明确一条消费端的选址行为:**对于双订阅的场景,消费端虽然可同时持有 2.x 地址与 3.x 地址,但选址过程中两份地址是完全隔离的:要么用 2.x 地址,要么用 3.x 地址,不存在两份地址混合调用的情况,这个决策过程是在收到第一次地址通知后就完成了的。** + + + +下面,我们看一个`APPLICATION_FIRST`策略的具体操作过程。 + +首先,提前在全局配置中心 Nacos 配置一条配置项(所有消费端都将默认执行这个选址策略): + +![//imgs/v3/migration/nacos-migration-item.png](/imgs/v3/migration/nacos-migration-item.png) + + + +紧接着,升级消费端到 3.x 版本并启动,这时消费端读取到`APPLICATION_FIRST`配置后,执行双订阅逻辑(订阅 2.x 接口级地址与 3.x 应用级地址) + + + +至此,升级操作就完成了,剩下的就是框架内部的执行了。在调用发生前,框架在消费端会有一个“选址过程”,注意这里的选址和之前 2.x 版本是有区别的,选址过程包含了两层筛选: + +* 先进行地址列表(ClusterInvoker)筛选(接口级地址 or 应用级地址) +* 再进行实际的 provider 地址(Invoker)筛选。 + +![//imgs/v3/migration/migration-cluster-item.png](/imgs/v3/migration/migration-cluster-invoker.png) + +ClusterInvoker 筛选的依据,可以通过 MigrationAddressComparator SPI 自行定义,目前官方提供了一个简单的地址数量比对策略,即当 `应用级地址数量 == 接口级地址数量` 满足时则进行迁移。 + +> 其实 FORCE_INTERFACE、APPLICATION_FIRST、FORCE_APPLICATION 控制的都是这里的 ClusterInvoker 类型的筛选策略 + + + +### 3.1 双订阅带来的资源消耗 + +双订阅不可避免的会增加消费端的内存消耗,但由于应用级地址发现在地址总量方面的优势,这个过程通常是可接受的,我们从两个方面进行分析: + +1. 双订阅带来的地址推送数据量增长。这点我们在 ”双注册资源消耗“ 一节中做过介绍,应用级服务发现带来的注册中心数据量增长非常有限。 +2. 双订阅带来的消费端内存增长。要注意双订阅只存在于启动瞬态,在ClusterInvoker选址决策之后其中一份地址就会被完全销毁;对单个服务来说,启动阶段双订阅带来的内存增长大概能控制在原内存量的 30% ~ 40%,随后就会下降到单订阅水平,如果切到应用级地址,能实现内存 50% 的下降。 + + + +### 3.2 消费端更细粒度的控制 + +除了全局的迁移策略之外,Dubbo 在消费端提供了更细粒度的迁移策略支持。控制单位可以是某一个消费者应用,它消费的服务A、服务B可以有各自独立的迁移策略,具体是用方式是在消费端配置迁移规则: + + +```yaml +key: demo-consumer +step: APPLICATION_FIRST +applications: + - name: demo-provider + step: FORCE_APPLICATION +services: + - serviceKey: org.apache.dubbo.config.api.DemoService:1.0.0 + step: FORCE_INTERFACE +``` + +使用这种方式能做到比较精细迁移控制,但是当下及后续的改造成本会比较高,除了一些特别场景,我们不太推荐启用这种配置方式。 +[迁移指南](../service-discovery-rule/)官方推荐使用的全局的开关式的迁移策略,让消费端实例在启动阶段自行决策使用哪份可用的地址列表。 + + + +## 4 迁移状态的收敛 + +为了同时兼容 2.x 版本,升级到 3.x 版本的应用在一段时间内要么处在双注册状态,要么处在双订阅状态。 + +解决这个问题,我们还是从 Provider 视角来看,当所有的 Provider 都切换到应用级地址注册之后,也就不存在双订阅的问题了。 + +### 4.1 不同的升级策略影响很大 + +毫无疑问越早越彻底的升级,就能尽快摆脱这个局面。设想,如果可以将组织内所有的应用都升级到 3.x 版本,则版本收敛就变的非常简单:升级过程中 Provider 始终保持双注册,当所有的应用都升级到 3.x 之后,就可以调整全局默认行为,让 Provider 都变成应用级地址单注册了,这个过程并不会给 Consumer 应用带来困扰,因为它们已经是可以识别应用级地址的 3.x 版本了。 + +如果没有办法做到应用的全量升级,甚至在相当长的时间内只能升级一部分应用,则不可避免的迁移状态要持续比较长的时间。 +在这种情况下,我们追求的只能是尽量保持已升级应用的上下游实现版本及功能收敛。推动某些 Provider 的上游消费者都升级到 Dubbo3,这样就可以解除这部分 Provider 的双注册,要做到这一点,可能需要一些辅助统计工具的支持。 + +1. 要能分析出应用间的依赖关系,比如一个 Provdier 应用被哪些消费端应用消费,这可以通过 Dubbo 提供的服务元数据上报能力来实现。 +2. 要能知道每个应用当前使用的 dubbo 版本,可以通过扫描或者主动上报手段。 + +## 5. 迁移状态模型 + +在 Dubbo 3 之前地址注册模型是以接口级粒度注册到注册中心的,而 Dubbo 3 全新的应用级注册模型注册到注册中心的粒度是应用级的。从注册中心的实现上来说是几乎不一样的,这导致了对于从接口级注册模型获取到的 invokers 是无法与从应用级注册模型获取到的 invokers 进行合并的。为了帮助用户从接口级往应用级迁移,Dubbo 3 设计了 Migration 机制,基于三个状态的切换实现实际调用中地址模型的切换。 + +![//imgs/v3/migration/migration-1.png](/imgs/v3/migration/migration-1.png) + +当前共存在三种状态,FORCE_INTERFACE(强制接口级),APPLICATION_FIRST(应用级优先)、FORCE_APPLICATION(强制应用级)。 + + +FORCE_INTERFACE:只启用兼容模式下接口级服务发现的注册中心逻辑,调用流量 100% 走原有流程 +APPLICATION_FIRST:开启接口级、应用级双订阅,运行时根据阈值和灰度流量比例动态决定调用流量走向 +FORCE_APPLICATION:只启用新模式下应用级服务发现的注册中心逻辑,调用流量 100% 走应用级订阅的地址 + + +### 5.1 规则体说明 + + +规则采用 yaml 格式配置,具体配置下参考如下: +```yaml +key: 消费者应用名(必填) +step: 状态名(必填) +threshold: 决策阈值(默认1.0) +proportion: 灰度比例(默认100) +delay: 延迟决策时间(默认0) +force: 强制切换(默认 false) +interfaces: 接口粒度配置(可选) + - serviceKey: 接口名(接口 + : + 版本号)(必填) + threshold: 决策阈值 + proportion: 灰度比例 + delay: 延迟决策时间 + force: 强制切换 + step: 状态名(必填) + - serviceKey: 接口名(接口 + : + 版本号) + step: 状态名 +applications: 应用粒度配置(可选) + - serviceKey: 应用名(消费的上游应用名)(必填) + threshold: 决策阈值 + proportion: 灰度比例 + delay: 延迟决策时间 + force: 强制切换 + step: 状态名(必填) +``` + + +- key: 消费者应用名 +- step: 状态名(FORCE_INTERFACE、APPLICATION_FIRST、FORCE_APPLICATION) +- threshold: 决策阈值(浮点数,具体含义参考后文) +- proportion: 灰度比例(0~100,决定调用次数比例) +- delay: 延迟决策时间(延迟决策的时间,实际等待时间为 1~2 倍 delay 时间,取决于注册中心第一次通知的时间,对于目前 Dubbo 的注册中心实现次配置项保留 0 即可) +- force: 强制切换(对于 FORCE_INTERFACE、FORCE_APPLICATION 是否不考虑决策直接切换,可能导致无地址调用失败问题) +- interfaces: 接口粒度配置 + + + +参考配置示例如下: +```yaml +key: demo-consumer +step: APPLICATION_FIRST +threshold: 1.0 +proportion: 60 +delay: 0 +force: false +interfaces: + - serviceKey: DemoService:1.0.0 + threshold: 0.5 + proportion: 30 + delay: 0 + force: true + step: APPLICATION_FIRST + - serviceKey: GreetingService:1.0.0 + step: FORCE_APPLICATION +``` + + +### 5.1 配置方式说明 +#### 1. 配置中心配置文件下发(推荐) + + +- Key: 消费者应用名 + ".migration" +- Group: DUBBO_SERVICEDISCOVERY_MIGRATION + + +配置项内容参考上一节 + + +程序启动时会拉取此配置作为最高优先级启动项,当配置项为启动项时不执行检查操作,直接按状态信息达到终态。 +程序运行过程中收到新配置项将执行迁移操作,过程中根据配置信息进行检查,如果检查失败将回滚为迁移前状态。迁移是按接口粒度执行的,也即是如果一个应用有 10 个接口,其中 8 个迁移成功,2 个失败,那终态 8 个迁移成功的接口将执行新的行为,2 个失败的仍为旧状态。如果需要重新触发迁移可以通过重新下发规则达到。 + + +注:如果程序在迁移时由于检查失败回滚了,由于程序无回写配置项行为,所以如果此时程序重启了,那么程序会直接按照新的行为不检查直接初始化。 + + +#### 2. 启动参数配置 + + +- 配置项名:dubbo.application.service-discovery.migration +- 允许值范围:FORCE_INTERFACE、APPLICATION_FIRST、FORCE_APPLICATION + + + +此配置项可以通过环境变量或者配置中心传入,启动时优先级比配置文件低,也即是当配置中心的配置文件不存在时读取此配置项作为启动状态。 + + +#### 3. 本地文件配置 + + + +| 配置项名 | 默认值 | 说明 | +| --- | --- | --- | +| dubbo.migration.file | dubbo-migration.yaml | 本地配置文件路径 | +| dubbo.application.migration.delay | 60000 | 配置文件延迟生效时间(毫秒) | + +配置文件中格式与前文提到的规则一致 + + +本地文件配置方式本质上是一个延时配置通知的方式,本地文件不会影响默认启动方式,当达到延时时间后触发推送一条内容和本地文件一致的通知。这里的延时时间与规则体中的 delay 字段无关联。 +本地文件配置方式可以保证启动以默认行为初始化,当达到延时时触发迁移操作,执行对应的检查,避免启动时就以终态方式启动。 + + +### 5.2 决策说明 +##### 1. 阈值探测 + + +阈值机制旨在进行流量切换前的地址数检查,如果应用级的可使用地址数与接口级的可用地址数对比后没达到阈值将检查失败。 + + +核心代码如下: +```java +if (((float) newAddressSize / (float) oldAddressSize) >= threshold) { + return true; +} +return false; +``` + + +同时 MigrationAddressComparator 也是一个 SPI 拓展点,用户可以自行拓展,所有检查的结果取交集。 + + +##### 2. 灰度比例 + + +灰度比例功能仅在应用级优先状态下生效。此功能可以让用户自行决定调用往新模式应用级注册中心地址的调用数比例。灰度生效的前提是满足了阈值探测,在应用级优先状态下,如果阈值探测通过,`currentAvailableInvoker` 将被切换为对应应用级地址的 invoker;如果探测失败 `currentAvailableInvoker` 仍为原有接口级地址的 invoker。 + + +流程图如下: +探测阶段 +![//imgs/v3/migration/migration-2.png](/imgs/v3/migration/migration-2.png) +调用阶段 +![//imgs/v3/migration/migration-3.png](/imgs/v3/migration/migration-3.png) + + +核心代码如下: +```java +// currentAvailableInvoker is based on MigrationAddressComparator's result +if (currentAvailableInvoker != null) { + if (step == APPLICATION_FIRST) { + // call ratio calculation based on random value + if (ThreadLocalRandom.current().nextDouble(100) > promotion) { + return invoker.invoke(invocation); + } + } + return currentAvailableInvoker.invoke(invocation); +} + +``` + + +### 5.3 切换过程说明 + + +地址迁移过程中涉及到了三种状态的切换,为了保证平滑迁移,共有 6 条切换路径需要支持,可以总结为从强制接口级、强制应用级往应用级优先切换;应用级优先往强制接口级、强制应用级切换;还有强制接口级和强制应用级互相切换。 +对于同一接口切换的过程总是同步的,如果前一个规则还未处理完就收到新规则则回进行等待。 + + +###### 1. 切换到应用级优先 + + +从强制接口级、强制应用级往应用级优先切换本质上是从某一单订阅往双订阅切换,保留原有的订阅并创建另外一种订阅的过程。这个切换模式下规则体中配置的 delay 配置不会生效,也即是创建完订阅后马上进行阈值探测并决策选择某一组订阅进行实际优先调用。由于应用级优先模式是支持运行时动态进行阈值探测,所以对于部分注册中心无法启动时即获取全量地址的场景在全部地址通知完也会重新计算阈值并切换。 +应用级优先模式下的动态切换是基于服务目录(Directory)的地址监听器实现的。 +![//imgs/v3/migration/migration-4.png](/imgs/v3/migration/migration-4.png) + + +###### 2. 应用级优先切换到强制 + + +应用级优先往强制接口级、强制应用级切换的过程是对双订阅的地址进行检查,如果满足则对另外一份订阅进行销毁,如果不满足则回滚保留原来的应用级优先状态。 +如果用户希望这个切换过程不经过检查直接切换可以通过配置 force 参数实现。 +![//imgs/v3/migration/migration-5.png](/imgs/v3/migration/migration-5.png) +###### 3. 强制接口级和强制应用级互相切换 + + +强制接口级和强制应用级互相切换需要临时创建一份新的订阅,判断新的订阅(即阈值计算时使用新订阅的地址数去除旧订阅的地址数)是否达标,如果达标则进行切换,如果不达标会销毁这份新的订阅并且回滚到之前的状态。 +![//imgs/v3/migration/migration-6.png](/imgs/v3/migration/migration-6.png) diff --git a/content/zh-cn/overview/mannual/java-sdk/upgrades-and-compatibility/service-discovery/service-discovery-rule.md b/content/zh-cn/blog/java/proposals/service-discovery-rule.md similarity index 98% rename from content/zh-cn/overview/mannual/java-sdk/upgrades-and-compatibility/service-discovery/service-discovery-rule.md rename to content/zh-cn/blog/java/proposals/service-discovery-rule.md index cb9c91c73d16..f89e8ad74e44 100644 Binary files a/content/zh-cn/overview/mannual/java-sdk/upgrades-and-compatibility/service-discovery/service-discovery-rule.md and b/content/zh-cn/blog/java/proposals/service-discovery-rule.md differ diff --git a/content/zh-cn/overview/mannual/java-sdk/upgrades-and-compatibility/service-discovery/service-discovery-samples.md b/content/zh-cn/blog/java/proposals/service-discovery-samples.md similarity index 96% rename from content/zh-cn/overview/mannual/java-sdk/upgrades-and-compatibility/service-discovery/service-discovery-samples.md rename to content/zh-cn/blog/java/proposals/service-discovery-samples.md index 95f60a64e55c..876f291d3959 100644 --- a/content/zh-cn/overview/mannual/java-sdk/upgrades-and-compatibility/service-discovery/service-discovery-samples.md +++ b/content/zh-cn/blog/java/proposals/service-discovery-samples.md @@ -2,11 +2,11 @@ aliases: - /zh/docs3-v2/java-sdk/upgrades-and-compatibility/service-discovery/service-discovery-samples/ - /zh-cn/docs3-v2/java-sdk/upgrades-and-compatibility/service-discovery/service-discovery-samples/ -description: 本文具体说明了用户在升级到 Dubbo 3.0 之后如何快速开启应用级服务发现新特性。 + - /zh-cn/overview/mannual/java-sdk/upgrades-and-compatibility/service-discovery/service-discovery-samples/ linkTitle: 应用级服务发现迁移示例 title: 应用级服务发现迁移示例 -type: docs -weight: 5 +tags: ["Java","服务发现"] +date: 2024-05-13 --- diff --git a/content/zh-cn/blog/news/20230130-release.md b/content/zh-cn/blog/news/20230130-release.md index d8a56fa3112b..8d7114700b5a 100644 --- a/content/zh-cn/blog/news/20230130-release.md +++ b/content/zh-cn/blog/news/20230130-release.md @@ -46,7 +46,7 @@ Dubbo 3.1.5 版本是目前 Dubbo 3 的最新稳定版本,我们建议所有 ### FAQ -本次发布中有 5 个提交涉及异常日志 FAQ 的完善。关于错误码机制请参考官网[错误码机制介绍](/zh-cn/overview/mannual/java-sdk/faq/intro/)一文。 +本次发布中有 5 个提交涉及异常日志 FAQ 的完善。关于错误码机制请参考官网[错误码机制介绍](/zh-cn/overview/java-sdk/reference-manual/faq/intro/)一文。 ### 代码优化 diff --git a/content/zh-cn/blog/news/apache-33-release.md b/content/zh-cn/blog/news/apache-33-release.md new file mode 100644 index 000000000000..901bddf0021b --- /dev/null +++ b/content/zh-cn/blog/news/apache-33-release.md @@ -0,0 +1,192 @@ +--- +title: "Apache Dubbo 3.3 全新发布:Triple X 领衔,开启微服务通信新时代" +linkTitle: "Apache Dubbo 3.3 全新发布" +date: 2024-09-11 +tags: ["新闻动态"] +description: > + 在 Apache Dubbo 突破 4w Star 之际,Apache Dubbo 团队正式宣布,Dubbo 3.3 正式发布!作为全球领先的开源微服务框架,Dubbo 一直致力于为开发者提供高性能、可扩展且灵活的分布式服务解决方案。此次发布的 Dubbo 3.3,通过 Triple X 的全新升级,突破了以往局限,实现了对南北向与东西向流量的全面支持,并提升了对云原生架构的友好性。 +--- + +在 Apache Dubbo 突破 4w Star 之际,Apache Dubbo 团队正式宣布,Dubbo 3.3 正式发布!作为全球领先的开源微服务框架,Dubbo 一直致力于为开发者提供高性能、可扩展且灵活的分布式服务解决方案。此次发布的 Dubbo 3.3,通过 Triple X 的全新升级,突破了以往局限,实现了对南北向与东西向流量的全面支持,并提升了对云原生架构的友好性。 + +## Dubbo 的基础介绍 + +**Apache Dubbo** 是一个高性能、轻量级的微服务框架,最初由 Java 开发,但现在已扩展支持 **Go、Rust、Python** 等多种语言,为全球企业构建跨语言、跨平台的分布式系统提供了强有力的支持。Dubbo 提供了丰富的服务治理能力,包括服务注册与发现、负载均衡、容错机制和调用链追踪,帮助开发者构建高效、灵活的微服务架构。 + +随着 Dubbo 逐渐演进,其通信性能、服务治理能力和跨语言兼容性得到了大幅提升,成为支持现代微服务架构的理想工具。 + +## Triple X 全新升级背景 + +在 Dubbo 的早期应用中,虽然其在数据中心内部的服务互通中展现了卓越的性能,但随着技术演进和应用场景的扩展,原有架构逐渐暴露出了一些瓶颈。这些瓶颈在跨区域、跨云的环境中尤为明显,尤其是在 Web 框架与 RPC 框架之间的频繁切换中,开发复杂性和系统性能都受到了影响。 + +**传统架构的痛点主要体现在:** + +1. **局限于数据中心内的应用场景**:在跨地域或跨云应用中,Dubbo 的传统架构缺乏对广域环境的原生支持,导致开发者需要在多种协议和框架中切换,增加了复杂性。 + +2. **南北向与东西向流量的双重挑战**:在现代微服务架构下,传统的 RPC 框架往往更侧重南北向流量优化,而服务间(东西向)通信的性能要求日益增加,对传统 Dubbo 架构提出了新的挑战。 + +3. **云原生与跨语言互操作性要求**:随着云原生技术的普及,系统需要对 HTTP 协议有更深层次的支持,并具备跨语言的通信能力,然而传统 Dubbo 在这一点上并未原生优化。 + + +**Triple X 的变革和突破:** Triple X 的诞生,直接回应了这些痛点,它不仅延续了 Dubbo 一贯的高性能通信能力,还实现了与 gRPC 协议的全面兼容,通过支持 HTTP/1、HTTP/2、HTTP/3 等协议,为跨云、跨区域的广泛应用场景提供了更具灵活性和高效性的解决方案。 + +![image.png](/imgs/blog/33-release/ee5812e0-a90b-4a02-abab-b658cdddefc1.png) + +## Triple X 核心能力概述 + +* **全面支持南北向与东西向流量**:Triple X 无缝支持从客户端到服务器的南北向流量及服务间通信的东西向流量,并确保灵活转换,提升通信链路的整体效率。 + +* **遵循 gRPC 协议标准**:Triple X 遵循了 gRPC 协议标准,支持通过 Protobuf 进行通信,与 gRPC 服务无缝交互,扩展了 Dubbo 的跨语言、跨平台通信能力。 + +* **基于 HTTP 协议,原生支持云原生架构**:Triple X 构建于 HTTP/1、HTTP/2 和 HTTP/3 协议栈之上,全面优化了网络通信性能,并与现代云原生基础设施无缝集成,支持各种网关和服务网格。 + +* **高性能优化**:Triple X 提供了极致的性能提升,尤其在高并发和弱网环境下表现卓越,极大提高了系统吞吐量与响应速度。 + +* **平滑迁移与框架兼容**:支持从现有的 Spring Web 项目无缝迁移,开发者无需更改现有代码即可切换至 Triple X,提升性能,并保留对 Spring MVC 等框架的支持。 + +* **高扩展性**:Triple X 新引入 20+ SPI 扩展点,支持自定义核心行为,包括路由映射、参数解析、序列化及异常处理等。显著提升框架的灵活性和可定制性,使开发者能够根据特定业务需求和场景自定义行为,提高开发效率并降低定制化成本。 + + +## Triple X 使用场景 + +**Triple X** 在 Dubbo 3.3 中为微服务架构提供了灵活的接入方式,能够适应不同场景下的系统需求。根据系统架构的不同,Triple X 提供了 **中心化接入方式** 和 **去中心化接入方式**,适用于多种应用场景。 + +### 1. 中心化接入方式 + +在 **中心化接入方式** 中,外部流量通过一个统一的服务网关进入 Dubbo 后端服务。网关负责处理 HTTP 流量的解析、转发,并将请求路由到合适的后端服务中。这种方式适用于对流量统一管理、流量控制、权限校验等有较高要求的系统,能够集中式地控制流量的进入点。 + +![lQLPJxkYhOcUzFfNA3bNC0Sw5rRkqBkcwQ4GwaypwVc_AA_2884_886.png](/imgs/blog/33-release/78d6744b-928a-41d4-857c-ff91ad69c896.png) + +* **使用场景**:当系统需要集中管理外部请求、对流量进行监控和限流等操作时,Triple X 能够通过服务网关处理 HTTP/1、HTTP/2 和 HTTP/3 的流量,并高效地转发给 Dubbo 服务进行处理。 + +* **优势**:集中化控制、易于管理,适合大规模系统中的统一流量治理。 + + +### 2. 去中心化接入方式 + +在 **去中心化接入方式** 中,外部客户端可以直接通过 HTTP 协议访问后端 Dubbo 服务,而不需要依赖中间的网关层。这种方式适合对性能和低延迟有较高要求的系统,通过减少网关的转发,直接将流量路由到服务节点,从而降低通信开销,提升系统响应速度。网关节点的消除,能避免网关故障造成的系统不可用,简化部署架构,提升系统稳定性。 + +![lQLPJw7B47rI7FfNAzjNCYiwStDS2ladC3oGwaypwZe9AA_2440_824.png](/imgs/blog/33-release/68b69954-9df2-48b2-bd63-fe07ba8cb25b.png) + +* **使用场景**:当系统希望通过直接的 HTTP 流量接入 Dubbo 服务,减少中间环节,提高系统的响应速度时,Triple X 提供了直接暴露 REST API 的能力,无需借助网关即可完成服务导出。 + +* **优势**:去除中间环节,提升性能和响应速度,简化了架构,适合对低延迟有需求的应用场景。 + + +## Triple X 核心能力拆解说明 + +### 1. 支持全面的流量管理与高效通信 + +在复杂的微服务架构中,南北向流量(客户端到服务器)和东西向流量(服务间通信)需要采用不同的技术进行处理,系统往往面临性能瓶颈与复杂的开发和运维问题。 + +Triple X 协议通过统一的通信协议,同时支持南北向与东西向流量。无需在 Web 框架与 RPC 框架之间切换,简化了开发流程,提升了系统的整体性能和可维护性。 + +开发者可以通过 Triple X 实现全方位的流量支持,无论是用户发起的请求,还是服务间的通信,均可通过 Triple X 实现高效传输。 + +```java +package org.apache.test; + +@DubboService +public class UserServiceImpl implements UserService { + // 处理东西向请求 +} + +// Triple X 也支持南北向流量处理 +@DubboService +public class OrderService { + @GetMapping("/order/{orderId}") + public Order getOrderById(@PathVariable("orderId") String orderId) {} +} +``` + +调用方式: + +1. Dubbo Client 直接发起 RPC 调用 + +2. 前端使用 HTTP 直接请求,目标路径为 `http://server:50051/order/{orderId}` + +3. 使用 Dubbo 默认发布的路径进行请求,目标路径为 `http://server:50051/org.apache.test.OrderService/getOrderById?orderId=xxx` + + +### 2. 遵循 gRPC 协议标准 + +跨语言服务之间的通信经常成为分布式系统中的难题,gRPC 是常用的解决方案之一,但传统 Dubbo 需要借助额外工具实现与 gRPC 的互操作性。 + +Triple X 遵循 **gRPC 协议标准**,通过 Protobuf 实现与 gRPC 的无缝交互,简化了开发流程,增强了跨语言和跨平台通信能力。 + +使用 Triple X 的服务可直接与基于 gRPC 的服务进行互通,无需额外适配,系统之间即可高效互访。 + +### 3. 基于 HTTP 协议,原生支持云原生架构 + +在云原生环境下,服务需要与各种网络设施(如 API 网关、服务网格)进行高效集成,同时支持多种 HTTP 协议以优化网络性能。 + +Triple X 同时支持 **HTTP/1、HTTP/2 和 HTTP/3** 协议,开发者无需进行额外配置即可利用这些协议的优势,包括长连接、多路复用和头部压缩,从而实现高效的网络通信。使用 **HTTP/3** 还能彻底解决队头阻塞问题,同时基于 UDP 的通讯方式,在弱网下能够维持较高的连接质量和服务性能,同等环境 TCP 在高丢包率下可能已不可用。 + +Triple X 支持复用 Spring Boot 现有 **Servlet** 端口接入 HTTP 流量,无需新增 Netty 监听端口。网络架构的简化,可以降低使用和维护成本,提升安全性,流量易于通过企业防火墙和网关。 + +![image.png](/imgs/blog/33-release/0e6b75c3-3340-4bed-a566-88c46a03ada6.png) + +### 4. 高性能优化,提升 5 倍 QPS + +在高并发场景中,传统通信协议并未做深度优化,容易造成瓶颈,影响系统的整体响应时间和吞吐量。 + +Triple X 通过 **Radix Tree** 和 **Zero Copy** 等技术降低了 CPU 使用和内存用量,显著提升了系统性能,尤其在高并发和弱网环境下表现突出: + +* **高效路由**:采用 Radix Tree 前缀树结构进行路由匹配,优化 key hash 算法并支持动态更新,减少内存占用,提高匹配效率。 + +* **内存使用优化**:结合 Zero Copy 技术和对象复用技术,减少数据复制和对象创建开销,降低垃圾回收压力,提升吞吐量。 + +* **HTTP/3 支持**:引入基于 QUIC 的 HTTP/3 协议,显著提升弱网环境下的性能表现,解决队头阻塞问题,减少延迟并提高连接可靠性。 + +* **多协议压测优化**:Dubbo 团队对各种协议进行了全面压测,基于测试结果进行了多轮性能优化,确保在不同场景下都能达到最佳表现。 + + +经过压测,简单 Rest 服务相较于传统 Spring Boot REST 服务,Triple X 服务的平均响应时间降低至 1/3,高压力下 QPS 提升 5 倍,同时内存分配量减少 50%,显著提升了系统整体性能和资源利用效率。 + +![image.png](/imgs/blog/33-release/c7d4f983-f619-4d39-94b6-5d62fd5a430e.png) + +![image.png](/imgs/blog/33-release/53a6f3c7-20ad-49f6-abc0-4e2d80a9597d.png) + +![image.png](/imgs/blog/33-release/7e4f3ced-9932-472f-bb8f-272ec97a7fbe.png) + +![image.png](/imgs/blog/33-release/5f8ebef5-08f3-463a-bb86-14b32a09ebb2.png) + +### 5. 平滑迁移与框架兼容 + +此外,Triple X 还支持对于已有 Spring Web 的项目,在不大幅修改代码的前提下提升性能,向微服务架构迁移。 + +Triple X 支持零侵入式的迁移方案,开发者无需更改现有代码即可将现有的 Spring Web 项目迁移至 Triple X,同时保留对 Spring MVC 等框架的支持。 + +```java +@DubboService // 仅需添加服务发布配置 +@RestController +public class DemoController { + + @GetMapping("/spring-test") + public String sayHello(@RequestParam("name") String name) { + return "Hello " + name; + } +} +``` + +## 此次版本升级其他的能力优化概述 + +### 1. Native Image AOT 支持 + +Dubbo 3.3 引入了对 **Native Image AOT(Ahead-of-Time 编译)** 的支持,开发者可以将 Dubbo 应用编译为原生二进制文件,极大缩短启动时间,降低内存占用,特别适合无服务器(Serverless)场景。 + +### 2. Project Loom 支持 + +Dubbo 3.3 提供了对 **Project Loom** 的支持,通过虚拟线程优化了高并发场景下的线程管理,简化了异步编程模型,提升了并发处理能力。 + +### 3. 全新路由规则 + +在路由机制上,Dubbo 3.3 引入了全新的路由规则,支持更加灵活的流量控制和服务治理,增强了微服务系统在大规模部署中的适应性。 + +## 总结 + +**Apache Dubbo 3.3** 的发布标志着微服务通信技术迈向新高度。通过 **Triple X**,Dubbo 不仅实现了对南北向与东西向流量的全面支持,还通过与 gRPC 的无缝集成、基于 HTTP 协议的云原生支持以及高性能优化,为开发者提供了更强大、灵活的工具,帮助他们构建现代分布式系统。 + +无论是提升服务间通信的高效性、实现跨语言兼容,还是优化云原生环境下的通信性能,Dubbo 3.3 都是开发者应对现代分布式系统挑战的理想选择。立即升级至 Dubbo 3.3,体验 **Triple X** 带来的变革,开启微服务通信的新时代! + +更多升级指南和兼容性说明,请参考[Dubbo 3.2 升级 3.3 指南](/zh-cn/overview/mannual/java-sdk/reference-manual/upgrades-and-compatibility/version/3.2-to-3.3-compatibility-guide/)。 diff --git a/content/zh-cn/blog/news/dubbo-initializer.md b/content/zh-cn/blog/news/dubbo-initializer.md new file mode 100644 index 000000000000..3cb2c3b16dcc --- /dev/null +++ b/content/zh-cn/blog/news/dubbo-initializer.md @@ -0,0 +1,64 @@ +--- +aliases: + - /zh/overview/tasks/develop/template/ + - /zh-cn/overview/tasks/develop/template/ + - /zh-cn/overview/mannual/java-sdk/tasks/develop/template/ +title: "通过模板生成项目脚手架" +linkTitle: "通过模板生成项目脚手架" +date: 2023-12-31 +tags: ["新闻动态"] +description: > + 本文介绍 dubbo initializer 的基本使用,使用 start.dubbo.apache.org 快速生成 Dubbo 项目(应用)。 +--- + +Dubbo Initializer 可用来快速生成 Java 项目脚手架,帮助简化微服务项目搭建、基本配置、组件依赖管理等。 + +> Initializer 仍在持续更新中,更多 Dubbo Feature 的支持将会陆续发布。 + +## 选择 Dubbo 版本 +Initializer 将使用 `dubbo-spring-boot-starter` 创建 Spring Boot 项目,因此我们首先需要选择 Dubbo 与 Spring Boot 的版本。 + +![initializer-choose-version](/imgs/v3/tasks/develop/initializer-choose-version.png) + +## 录入项目基本信息 +接下来,填入项目基本信息,包括项目坐标、项目名称、包名、JDK 版本等。 + +![initializer-project-info](/imgs/v3/tasks/develop/initializer-project-info.png) + +## 选择项目结构 +有两种项目结构可共选择,分别是 `单模块` 和 `多模块`,在这个示例中我们选择 `单模块`。 + +![initializer-project-architecture](/imgs/v3/tasks/develop/initializer-project-architecture.png) + +* 单模块,所有组件代码存放在一个 module 中,特点是结构简单。 +* 多模块,生成的项目有 `API`、`Service` 两个模块,其中 `API` 用于存放 Dubbo 服务定义,`Service` 用于存放服务实现或调用逻辑。通常多模块更有利于服务定义的单独管理与发布。 + +## 选择依赖组件 +我们为模板默认选择如下几个依赖组件: +* Dubbo 组件 + * Java Interface + * 注册中心,zookeeper + * 协议 TCP +* 常用微服务组件 + * Web + * Mybatis + * 模版引擎 + +![initializer-dependencies](/imgs/v3/tasks/develop/initializer-dependencies.png) + +基于以上选项,生成的项目将以 Zookeeper 为注册中心,以高性能 Dubbo2 TCP 协议为 RPC 通信协议,并且增加了 Web、Mybatis 等组件依赖和示例。 + +> 注意:上面选中的 Dubbo 组件也都是默认选项,即在不手动添加任何依赖的情况下,打开页面后直接点击代码生成,生成的代码即包含以上 Dubbo 组件。 +> +> 如手动添加依赖组件,请注意 Dubbo 各个依赖组件之间的隐含组合关系限制,比如 +> * 如果选择了【Dubbo Service API】-【IDL】,则目前仅支持选择 【Dubbo Protocol】中的 【HTTP/2】或 【gRPC】 协议。 +> * 同一个依赖分组下,相同类型的依赖只能选择一个,比如 【Dubbo Registry&Config&Metadata】分组下,从注册中心视角【Zookeeper】、【Nacos】只能选一个,如果要设置多注册中心,请在生成的代码中手动修改配置。但注册中心、配置中心可以分别选一个,比如 Zookeeper 和 Apollo 可同时选中。 + +## 生成项目模板 +* 点击 “浏览代码” 可在线浏览项目结构与代码 +* 点击 “获取代码” 生成项目下载地址 + +![initializer-preview](/imgs/v3/tasks/develop/initializer-preview.png) + +项目下载到本地后,解压并导入 IDE 后即可根据需要开发定制 Dubbo 应用。 + diff --git a/content/zh-cn/blog/news/releases/3.1.4.md b/content/zh-cn/blog/news/releases/3.1.4.md index 54f4401cadfa..94164461c6f7 100644 --- a/content/zh-cn/blog/news/releases/3.1.4.md +++ b/content/zh-cn/blog/news/releases/3.1.4.md @@ -38,7 +38,7 @@ Dubbo 3.1.4 版本是目前 Dubbo 3 的最新稳定版本,我们建议所有 ### FAQ -本次发布中有 3 个提交涉及异常日志 FAQ 的完善。关于错误码机制请参考官网错误码机制介绍一文。(https://cn.dubbo.apache.org/zh-cn/overview/mannual/java-sdk/faq/intro/) +本次发布中有 3 个提交涉及异常日志 FAQ 的完善。关于错误码机制请参考官网错误码机制介绍一文。(https://cn.dubbo.apache.org/zh-cn/overview/java-sdk/reference-manual/faq/intro/) ### 代码优化 diff --git a/content/zh-cn/blog/nodejs/_index.md b/content/zh-cn/blog/nodejs/_index.md new file mode 100644 index 000000000000..a19aad2ce1ec --- /dev/null +++ b/content/zh-cn/blog/nodejs/_index.md @@ -0,0 +1,9 @@ + +--- +title: "Node.js" +linkTitle: "Node.js" +weight: 11 +description: "使用 Node.js 开发 Dubbo 应用与微服务" +--- + + diff --git a/content/zh-cn/contact/_index.md b/content/zh-cn/contact/_index.md index 60d309bc36ce..d2cde263b288 100755 --- a/content/zh-cn/contact/_index.md +++ b/content/zh-cn/contact/_index.md @@ -4,9 +4,9 @@ aliases: - /zh/contribution-guidelines/ description: 联系社区,Dubbo 社区贡献指南 linkTitle: 联系社区 -menu: - main: - weight: 40 +# menu: +# main: +# weight: 40 title: 联系社区 type: docs --- diff --git a/content/zh-cn/demo/_index.md b/content/zh-cn/demo/_index.md new file mode 100755 index 000000000000..4249f2952dd4 --- /dev/null +++ b/content/zh-cn/demo/_index.md @@ -0,0 +1,31 @@ +--- +title: "使用 Dubbo 开发的完整商城系统示例" +linkTitle: "商城示例" +--- + +
+
+ +
+ +
+{{< page/toc collapsed=true placement="inline" >}} +
+ +
+
+

+1. 示例提供了运行以下命令部署到本地Kubernetes集群: + + ```shell + kubectl apply -f xxx/kubernetes-manifests.yaml + ``` + +2. 示例提供了 Java 和 Go 语言实现,点击链接查看源码。 +

+ + + +
+
+
diff --git a/content/zh-cn/docs/advanced/service-container.md b/content/zh-cn/docs/advanced/service-container.md index ca32fd694aa4..864b2ebb35be 100644 --- a/content/zh-cn/docs/advanced/service-container.md +++ b/content/zh-cn/docs/advanced/service-container.md @@ -10,7 +10,7 @@ weight: 40 -{{% pageinfo %}} 此文档已经不再维护。您当前查看的是快照版本。如果想要查看最新版本的文档,请参阅[最新版本](/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/others/service-container/)。 +{{% pageinfo %}} 此文档已经不再维护。您当前查看的是快照版本。 {{% /pageinfo %}} 服务容器是一个 standalone 的启动程序,因为后台服务不需要 Tomcat 或 JBoss 等 Web 容器的功能,如果硬要用 Web 容器去加载服务提供方,增加复杂性,也浪费资源。 diff --git a/content/zh-cn/docs/advanced/static-service.md b/content/zh-cn/docs/advanced/static-service.md index 73663d7b5e1d..440d4229b71a 100644 --- a/content/zh-cn/docs/advanced/static-service.md +++ b/content/zh-cn/docs/advanced/static-service.md @@ -10,7 +10,7 @@ weight: 11 -{{% pageinfo %}} 此文档已经不再维护。您当前查看的是快照版本。如果想要查看最新版本的文档,请参阅[最新版本](/zh-cn/overview/mannual/java-sdk/reference-manual/registry/simple/)。 +{{% pageinfo %}} 此文档已经不再维护。您当前查看的是快照版本。 {{% /pageinfo %}} 有时候希望人工管理服务提供者的上线和下线,此时需将注册中心标识为非动态管理模式。 diff --git a/content/zh-cn/docs/references/registry/simple.md b/content/zh-cn/docs/references/registry/simple.md index a0bae65cd7e6..2a01f468e7ec 100644 --- a/content/zh-cn/docs/references/registry/simple.md +++ b/content/zh-cn/docs/references/registry/simple.md @@ -10,7 +10,7 @@ weight: 4 -{{% pageinfo %}} 此文档已经不再维护。您当前查看的是快照版本。如果想要查看最新版本的文档,请参阅[最新版本](/zh-cn/overview/mannual/java-sdk/reference-manual/registry/simple/)。 +{{% pageinfo %}} 此文档已经不再维护。您当前查看的是快照版本。 {{% /pageinfo %}} Simple 注册中心本身就是一个普通的 Dubbo 服务,可以减少第三方依赖,使整体通讯方式一致。 diff --git a/content/zh-cn/download/_index.md b/content/zh-cn/download/_index.md index 9a37f8867815..f41f15cb3fc9 100644 --- a/content/zh-cn/download/_index.md +++ b/content/zh-cn/download/_index.md @@ -3,10 +3,10 @@ aliases: - /zh/download/ description: 版本发布 layout: basic -linkTitle: 版本发布 +linkTitle: 下载 menu: main: - weight: 30 + weight: 4 no_list: true title: 版本发布 type: docs diff --git a/content/zh-cn/featured-background.jpg b/content/zh-cn/featured-background.jpg index f6a02b9113ea..d4bc6b77b851 100644 Binary files a/content/zh-cn/featured-background.jpg and b/content/zh-cn/featured-background.jpg differ diff --git a/content/zh-cn/github/_index.md b/content/zh-cn/github/_index.md index 3283ffe0d3d8..7ad9af012270 100755 --- a/content/zh-cn/github/_index.md +++ b/content/zh-cn/github/_index.md @@ -1,10 +1,10 @@ --- title: "Github" linkTitle: "Github" -menu: - main: - post: - weight: 70 +# menu: +# main: +# post: +# weight: 70 ---
diff --git a/content/zh-cn/overview/core-features/_index.md b/content/zh-cn/overview/core-features/_index.md deleted file mode 100755 index 04b79971c1ae..000000000000 --- a/content/zh-cn/overview/core-features/_index.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -aliases: - - /zh/overview/core-features/ -description: Dubbo 核心特性 -linkTitle: 功能 -title: Dubbo 核心特性 -type: docs -weight: 4 ---- diff --git a/content/zh-cn/overview/core-features/service-discovery.md b/content/zh-cn/overview/core-features/service-discovery.md deleted file mode 100644 index 98795cc74ea3..000000000000 --- a/content/zh-cn/overview/core-features/service-discovery.md +++ /dev/null @@ -1,72 +0,0 @@ ---- -aliases: - - /zh/overview/core-features/service-discovery/ - - /zh-cn/overview/mannual/java-sdk/concepts-and-architecture/service-discovery/ -description: 服务发现 -feature: - description: | - Dubbo 提供了高性能、可伸缩的服务发现机制,面向百万集群实例规模设计,默认提供 Nacos、Zookeeper 等注册中心适配并支持自定义扩展。 - title: 服务发现 -linkTitle: 服务发现 -title: 服务发现 -type: docs -weight: 2 ---- - - -Dubbo 提供的是一种 Client-Based 的服务发现机制,依赖第三方注册中心组件来协调服务发现过程,支持常用的注册中心如 Nacos、Consul、Zookeeper 等。 - -以下是 Dubbo 服务发现机制的基本工作原理图: - -![service-discovery](/imgs/v3/feature/service-discovery/arc.png) - -服务发现包含提供者、消费者和注册中心三个参与角色,其中,Dubbo 提供者实例注册 URL 地址到注册中心,注册中心负责对数据进行聚合,Dubbo 消费者从注册中心读取地址列表并订阅变更,每当地址列表发生变化,注册中心将最新的列表通知到所有订阅的消费者实例。 - -## 面向百万实例集群的服务发现机制 -区别于其他很多微服务框架的是,**Dubbo3 的服务发现机制诞生于阿里巴巴超大规模微服务电商集群实践场景,因此,其在性能、可伸缩性、易用性等方面的表现大幅领先于业界大多数主流开源产品**。是企业面向未来构建可伸缩的微服务集群的最佳选择。 - -![service-discovery](/imgs/v3/feature/service-discovery/arc2.png) - -* 首先,Dubbo 注册中心以应用粒度聚合实例数据,消费者按消费需求精准订阅,避免了大多数开源框架如 Istio、Spring Cloud 等全量订阅带来的性能瓶颈。 -* 其次,Dubbo SDK 在实现上对消费端地址列表处理过程做了大量优化,地址通知增加了异步、缓存、bitmap 等多种解析优化,避免了地址更新常出现的消费端进程资源波动。 -* 最后,在功能丰富度和易用性上,服务发现除了同步 ip、port 等端点基本信息到消费者外,Dubbo 还将服务端的 RPC/HTTP 服务及其配置的元数据信息同步到消费端,这让消费者、提供者两端的更细粒度的协作成为可能,Dubbo 基于此机制提供了很多差异化的治理能力。 - -### 高效地址推送实现 - -从注册中心视角来看,它负责以应用名 (dubbo.application.name) 对整个集群的实例地址进行聚合,每个对外提供服务的实例将自身的应用名、实例ip:port 地址信息 (通常还包含少量的实例元数据,如机器所在区域、环境等) 注册到注册中心。 - -> Dubbo2 版本注册中心以服务粒度聚合实例地址,比应用粒度更细,也就意味着传输的数据量更大,因此在大规模集群下也遇到一些性能问题。 -> 针对 Dubbo2 与 Dubbo3 跨版本数据模型不统一的问题,Dubbo3 给出了[平滑迁移方案](/zh-cn/overview/mannual/java-sdk/upgrades-and-compatibility/service-discovery/migration-service-discovery/),可做到模型变更对用户无感。 - -![service-discovery](/imgs/v3/feature/service-discovery/registry-data.png) - -
-每个消费服务的实例从注册中心订阅实例地址列表,相比于一些产品直接将注册中心的全量数据 (应用 + 实例地址) 加载到本地进程,Dubbo 实现了按需精准订阅地址信息。比如一个消费者应用依赖 app1、app2,则只会订阅 app1、app2 的地址列表更新,大幅减轻了冗余数据推送和解析的负担。 - -

-
- -![service-discovery](/imgs/v3/feature/service-discovery/subscription2.png) - -### 丰富元数据配置 -除了与注册中心的交互,Dubbo3 的完整地址发现过程还有一条额外的元数据通路,我们称之为元数据服务 (MetadataService),实例地址与元数据共同组成了消费者端有效的地址列表。 - -![service-discovery](/imgs/v3/feature/service-discovery/metadata.png) - -完整工作流程如上图所示,首先,消费者从注册中心接收到地址 (ip:port) 信息,然后与提供者建立连接并通过元数据服务读取到对端的元数据配置信息,两部分信息共同组装成 Dubbo 消费端有效的面向服务的地址列表。以上两个步骤都是在实际的 RPC 服务调用发生之前。 - -> 关于 MetadataService 的定义及完整服务发现流程分析,请查看 [应用级服务发现详解]({{< relref "../../../blog/proposals/service-discovery/" >}})。 - -> 对于微服务间服务发现模型的数据同步,REST 定义了一套非常有意思的成熟度模型,感兴趣的朋友可以参考这里的链接 https://www.martinfowler.com/articles/richardsonMaturityModel.html, 按照文章中的 4 级成熟度定义,Dubbo 当前基于接口粒度的模型可以对应到最高的 L4 级别。 - -## 配置方式 -Dubbo 服务发现扩展了多种注册中心组件支持,如 Nacos、Zookeeper、Consul、Redis、kubernetes 等,可以通过配置切换不同实现,同时还支持鉴权、命名空间隔离等配置。具体配置方式请查看 SDK 文档 - -* [Java](../../mannual/java-sdk/reference-manual/registry) -* [Golang](../../mannual/golang-sdk/tutorial/develop/registry) -* [Rust](../../mannual/rust-sdk/) - -Dubbo 还支持一个应用内配置多注册中心的情形如双注册、双订阅等,这对于实现不同集群地址数据互通、集群迁移等场景非常有用处,我们将在未来文档中添加 `最佳实践` 对这部分内容进行示例说明。 - -## 自定义扩展 -注册中心适配支持自定义扩展实现,具体请参见 [Dubbo 可扩展性](../extensibility) diff --git a/content/zh-cn/overview/core-features/traffic/_index.md b/content/zh-cn/overview/core-features/traffic/_index.md deleted file mode 100755 index a8a760fd244a..000000000000 --- a/content/zh-cn/overview/core-features/traffic/_index.md +++ /dev/null @@ -1,274 +0,0 @@ ---- -aliases: - - /zh/overview/core-features/traffic/ -description: 流量管控 -feature: - description: | - Dubbo 提供的基于路由规则的流量管控策略,可以帮助实现全链路灰度、金丝雀发布、按比例流量转发、动态调整调试时间、设置重试次数等服务治理能力。 - title: 流量管控 -linkTitle: 流量管控 -no_list: true -title: 流量管控 -type: docs -weight: 4 ---- - - - -Dubbo 提供了丰富的流量管控策略 -* **地址发现与负载均衡**,地址发现支持服务实例动态上下线,负载均衡确保流量均匀的分布到每个实例上。 -* **基于路由规则的流量管控**,路由规则对每次请求进行条件匹配,并将符合条件的请求路由到特定的地址子集。 - -服务发现保证调用方看到最新的提供方实例地址,服务发现机制依赖注册中心 (Zookeeper、Nacos、Istio 等) 实现。在消费端,Dubbo 提供了多种负载均衡策略,如随机负载均衡策略、一致性哈希负载、基于权重的轮询、最小活跃度优先、P2C 等。 - -Dubbo 的流量管控规则可以基于应用、服务、方法、参数等粒度精准的控制流量走向,根据请求的目标服务、方法以及请求体中的其他附加参数进行匹配,符合匹配条件的流量会进一步的按照特定规则转发到一个地址子集。流量管控规则有以下几种: -* 条件路由规则 -* 标签路由规则 -* 脚本路由规则 -* 动态配置规则 - -如果底层用的是基于 HTTP 的 RPC 协议 (如 REST、gRPC、Triple 等),则服务和方法等就统一映射为 HTTP 路径 (path),此时 Dubbo 路由规则相当于是基于 HTTP path 和 headers 的流量分发机制。 - -> Dubbo 中有应用、服务和方法的概念,一个应用可以发布多个服务,一个服务包含多个可被调用的方法,从抽象的视角来看,一次 Dubbo 调用就是某个消费方应用发起了对某个提供方应用内的某个服务特定方法的调用,Dubbo 的流量管控规则可以基于应用、服务、方法、参数等粒度精准的控制流量走向。 - -## 工作原理 - -以下是 Dubbo 单个路由器的工作过程,路由器接收一个服务的实例地址集合作为输入,基于请求上下文 (Request Context) 和 (Router Rule) 实际的路由规则定义对输入地址进行匹配,所有匹配成功的实例组成一个地址子集,最终地址子集作为输出结果继续交给下一个路由器或者负载均衡组件处理。 - -![Router](/imgs/v3/feature/traffic/router1.png) - -通常,在 Dubbo 中,多个路由器组成一条路由链共同协作,前一个路由器的输出作为另一个路由器的输入,经过层层路由规则筛选后,最终生成有效的地址集合。 -* Dubbo 中的每个服务都有一条完全独立的路由链,每个服务的路由链组成可能不同,处理的规则各异,各个服务间互不影响。 -* 对单条路由链而言,即使每次输入的地址集合相同,根据每次请求上下文的不同,生成的地址子集结果也可能不同。 - -![Router](/imgs/v3/feature/traffic/router2.png) - -## 路由规则分类 -### 标签路由规则 - -标签路由通过将某一个服务的实例划分到不同的分组,约束具有特定标签的流量只能在指定分组中流转,不同分组为不同的流量场景服务,从而实现流量隔离的目的。标签路由可以作为蓝绿发布、灰度发布等场景能力的基础。 - -标签路由规则是一个非此即彼的流量隔离方案,也就是匹配`标签`的请求会 100% 转发到有相同`标签`的实例,没有匹配`标签`的请求会 100% 转发到其余未匹配的实例。如果您需要按比例的流量调度方案,请参考示例 [基于权重的按比例流量路由](../../tasks/traffic-management/weight/)。 - -`标签`主要是指对 Provider 端应用实例的分组,目前有两种方式可以完成实例分组,分别是`动态规则打标`和`静态规则打标`。`动态规则打标` 可以在运行时动态的圈住一组机器实例,而 `静态规则打标` 则需要实例重启后才能生效,其中,动态规则相较于静态规则优先级更高,而当两种规则同时存在且出现冲突时,将以动态规则为准。 - -#### 标签规则示例 - 静态打标 - -静态打标需要在服务提供者实例启动前确定,并且必须通过特定的参数 `tag` 指定。 - -##### Provider - -在 Dubbo 实例启动前,指定当前实例的标签,如部署在杭州区域的实例,指定 `tag=gray`。 - -```xml - -``` - -or - -```xml - -``` - -or - -```properties -java -jar xxx-provider.jar -Ddubbo.provider.tag=gray -``` - -##### Consumer - -发起调用的一方,在每次请求前通过 `tag` 设置流量标签,确保流量被调度到带有同样标签的服务提供方。 - -```java -RpcContext.getContext().setAttachment(Constants.TAG_KEY, "gray"); -``` - -#### 标签规则示例 - 动态打标 - -相比于静态打标只能通过 `tag` 属性设置,且在启动阶段就已经固定下来,动态标签可以匹配任意多个属性,根据指定的匹配条件将 Provider 实例动态的划分到不同的流量分组中。 - -##### Provider - -以下规则对 `shop-detail` 应用进行了动态归组,匹配 `env: gray` 的实例被划分到 `gray` 分组,其余不匹配 `env: gray` 继续留在默认分组 (无 tag)。 - -```yaml -configVersion: v3.0 -force: true -enabled: true -key: shop-detail -tags: - - name: gray - match: - - key: env - value: - exact: gray -``` - -> 这里牵涉到如何给您的实例打各种原始 label 的问题,即上面示例中的 `env`,一种方式是直接写在配置文件中,如上面静态规则实例 provider 部分的配置所示,另一种方式是通过预设环境变量指定,关于这点请参考下文的 [如何给实例打标](#如何给实例打标) 一节。 - -##### Consumer - -服务发起方的设置方式和之前静态打标规则保持一致,只需要在每次请求前通过 `tag` 设置流量标签,确保流量被调度到带有同样标签的服务提供方。 - -```java -RpcContext.getContext().setAttachment(Constants.TAG_KEY, "Hangzhou"); -``` - -设置了以上标签的流量,将全部导流到 `hangzhou-region` 划分的实例上。 - -> 请求标签的作用域仅为一次点对点的 RPC 请求。比如,在一个 A -> B -> C 调用链路上,如果 A -> B 调用通过 `setAttachment` 设置了 `tag` 参数,则该参数不会在 B -> C 的调用中生效,同样的,在完成了 A -> B -> C 的整个调用同时 A 收到调用结果后,如果想要相同的 `tag` 参数,则在发起其他调用前仍需要单独设置 `setAttachment`。可以参考 [示例任务 - 环境隔离](../../tasks/traffic-management/isolation/) 了解更多 `tag` 全链路传递解决方案。 - -### 条件路由规则 - -条件路由与标签路由的工作模式非常相似,也是首先对请求中的参数进行匹配,符合匹配条件的请求将被转发到包含特定实例地址列表的子集。相比于标签路由,条件路由的匹配方式更灵活: - -* 在标签路由中,一旦给某一台或几台机器实例打了标签,则这部分实例就会被立马从通用流量集合中移除,不同标签之间不会再有交集。有点类似下图,地址集合在输入阶段就已经划分明确。 - -![tag-condition-compare](/imgs/v3/feature/traffic/tag-condition-compare1.png) - -* 而从条件路由的视角,所有的实例都是一致的,路由过程中不存在分组隔离的问题,每次路由过滤都是基于全量地址中执行 - -![tag-condition-compare](/imgs/v3/feature/traffic/tag-condition-compare2.png) - -条件路由规则的主体 `conditions` 主要包含两部分内容: - -* => 之前的为请求参数匹配条件,指定的 `匹配条件指定的参数` 将与 `消费者的请求上下文 (URL)、甚至方法参数` 进行对比,当消费者满足匹配条件时,对该消费者执行后面的地址子集过滤规则。 -* => 之后的为地址子集过滤条件,指定的 `过滤条件指定的参数` 将与 `提供者实例地址 (URL)` 进行对比,消费者最终只能拿到符合过滤条件的实例列表,从而确保流量只会发送到符合条件的地址子集。 - * 如果匹配条件为空,表示对所有请求生效,如:`=> status != staging` - * 如果过滤条件为空,表示禁止来自相应请求的访问,如:`application = product =>` - - -#### 条件路由规则示例 - -基于以下示例规则,所有 `org.apache.dubbo.demo.CommentService` 服务调用都将被转发到与当前消费端机器具有相同 `region` 标记的地址子集。`$region` 是特殊引用符号,执行过程中将读取消费端机器的实际的 `region` 值替代。 - -```yaml -configVersion: v3.0 -enabled: true -force: false -key: org.apache.dubbo.samples.CommentService -conditions: - - '=> region = $region' -``` - -> 针对条件路由,我们通常推荐配置 `scope: service` 的规则,因为它可以跨消费端应用对所有消费特定服务 (service) 的应用生效。关于 Dubbo 规则中的 `scope` 以及 `service`、`application` 的说明请阅读 [条件路由规则手册](./condition-rule)。 - -条件路由规则还支持设置具体的机器地址如 ip 或 port,这种情况下使用条件路由可以处理一些开发或线上机器的临时状况,实现**黑名单、白名单、实例临时摘除**等运维效果,如以下规则可以将机器 `172.22.3.91` 从服务的可用列表中排除。 - -```yaml -=> host != 172.22.3.91 -``` - -条件路由还支持基于请求参数的匹配,示例如下: - -```yaml -conditions: - - method=getDetail&arguments[0]=dubbo => port=20880 -``` - -### 动态配置规则 -通过 Dubbo 提供的动态配置规则,您可以动态的修改 Dubbo 服务进程的运行时行为,整个过程不需要重启,配置参数实时生效。基于这个强大的功能,基本上所有运行期参数都可以动态调整,比如超时时间、临时开启 Access Log、修改 Tracing 采样率、调整限流降级参数、负载均衡、线程池配置、日志等级、给机器实例动态打标签等。与上文讲到的流量管控规则类似,动态配置规则支持应用、服务两个粒度,也就是说您一次可以选择只调整应用中的某一个或几个服务的参数配置。 - -当然,出于系统稳定性、安全性的考量,有些特定的参数是不允许动态修改的,但除此之外,基本上所有参数都允许动态修改,很多强大的运行态能力都可以通过这个规则实现,您可以找个示例应用去尝试一下。通常 URL 地址中的参数均可以修改,这在每个语言实现的参考手册里也记录了一些更详细的说明。 - -#### 动态配置规则示例 - 修改超时时间 - -以下示例将 `org.apache.dubbo.samples.UserService` 服务的超时参数调整为 2000ms - -```yaml -configVersion: v3.0 -scope: service -key: org.apache.dubbo.samples.UserService -enabled: true -configs: - - side: provider - parameters: - timeout: 2000 -``` - -以下部分指定这个配置是服务粒度,具体变更的服务名为 `org.apache.dubbo.samples.UserService`。`scope` 支持 `service`、`application` 两个可选值,如果 `scope: service`,则 `key` 应该配置为 `version/service:group` 格式。 - -```yaml -scope: service -key: org.apache.dubbo.samples.UserService -``` - -> 关于 Dubbo 规则中的 `scope` 以及 `service`、`application` 的说明请参考 [动态配置参考手册](./configuration-rule/) 或 [动态配置示例](../../tasks/traffic-management/timeout/)。 - -`parameters` 参数指定了新的修改值,这里将通过 `timeout: 2000` 将超时时间设置为 2000ms。 - -```yaml -parameters: - timeout: 2000 -``` - -### 脚本路由规则 -脚本路由是最直观的路由方式,同时它也是当前最灵活的路由规则,因为你可以在脚本中定义任意的地址筛选规则。如果我们为某个服务定义一条脚本规则,则后续所有请求都会先执行一遍这个脚本,脚本过滤出来的地址即为请求允许发送到的、有效的地址集合。 - -```yaml -configVersion: v3.0 -key: demo-provider -type: javascript -enabled: true -script: | - (function route(invokers,invocation,context) { - var result = new java.util.ArrayList(invokers.size()); - for (i = 0; i < invokers.size(); i ++) { - if ("10.20.3.3".equals(invokers.get(i).getUrl().getHost())) { - result.add(invokers.get(i)); - } - } - return result; - } (invokers, invocation, context)); // 表示立即执行方法 -``` - -## 如何给实例打标 - -当前,有两种方式可以在启动阶段为 Dubbo 实例指定标签,一种是之前提到的应用内配置的方式,如在 xml 文件中设置 ``,应用打包部署后即自动被打标。 - -还有一种更灵活的方式,那就是通过读取所部署机器上的环境信息给应用打标,这样应用的标签就可以跟随实例动态的自动填充,避免每次更换部署环境就重新打包应用镜像的问题。当前 Dubbo 能自动读取以下环境变量配置: - -```yaml -spec: - containers: - - name: detail - image: apache/demo-detail:latest - env: - - name: DUBBO_LABELS - value: "region=hangzhou; env=gray" -``` - -```yaml -spec: - containers: - - name: detail - image: apache/demo-detail:latest - env: - - name: DUBBO_ENV_KEYS - value: "REGION, ENV" - - name: REGION - value: "hangzhou" - - name: ENV - value: "gray" -``` - -如果您有不同的实例环境保存机制,可以通过扩展 `InfraAdapter 扩展点` 来自定义自己的标签加载方式。如果您的应用是部署在 Kubernetes 环境下,并且已经接入了服务网格体系,则也可以使用标准 deployment 标签的方式打标,具体请跟随 [服务网格任务示例](../../tasks/mesh/) 学习。 - -## 如何配置流量规则 -Dubbo 提供了控制台 Dubbo Admin,帮助您可视化的下发流量管控规则,并实时监控规则生效情况。 - -![Admin](/imgs/v3/what/admin.png) - -Dubbo 还提供了 `dubboctl` 命令行工具,需要有 Dubbo Admin 提前部署就绪,因为 dubboctl 是通过与 Admin 进行 http 通信完成规则下发的。 - -如果您使用的是如 Istio 的服务网格架构,还可以使用 Istioctl、kubectl 等下发 Istio 标准规则。 - -## 接入服务网格 - -以上介绍的都是 Dubbo 体系内的流量治理规则,如果您对服务网格架构感兴趣,则可以将 Dubbo 服务接入服务网格体系,这样,您就可以使用服务网格提供的流量治理能力,如 Istio 体系的 VirtualService 等。 - -具体请参见 [Dubbo 中的服务网格架构](../service-mesh)。 - -## 跟随示例学习 -我们搭建了一个 [线上商城系统](../../tasks/traffic-management/) 供您学习流量规则的具体使用。 diff --git a/content/zh-cn/overview/core-features/traffic/mesh-rule.md.bak b/content/zh-cn/overview/core-features/traffic/mesh-rule.md.bak deleted file mode 100644 index 7c4fad9c586e..000000000000 --- a/content/zh-cn/overview/core-features/traffic/mesh-rule.md.bak +++ /dev/null @@ -1,372 +0,0 @@ ---- -type: docs -title: "Mesh 路由规则" -linkTitle: "Mesh 路由" -weight: 50 -description: "" ---- - -Dubbo Mesh 路由规则是基于 Istio 的 VirtualService、DestinationRule 改造而来,总体思路和格式可以参考 Istio 流量管控规则参考手册:[Istio VirtualService](https://istio.io/latest/docs/reference/config/networking/virtual-service/) 和 [Istio DestinationRule](https://istio.io/latest/docs/reference/config/networking/destination-rule/) - -本文描述了 Dubbo Mesh 路由规则的设计原理,和 Istio 规则的差异等。 - -### 基本思想 -基于路由链,采用Pipeline的处理方式,如下图所示: - -![route-rule1.png](/imgs/user/route-rule1.png) - - -可以把路由链的逻辑简单的理解为 target = rn(...r3(r2(r1(src))))。对于每一个 router 内部的逻辑,可以抽象为输入地址 addrs-in 与 router 中按全量地址 addrs-all 实现切分好的 n 个互不相交的地址池 addrs-pool-1 ... addrs-pool-n 按实现定义好的规则取交集作为输出 addrs-out。以此类推,完成整个路由链的计算。 - -![route-rule2.png](/imgs/user/route-rule2.png) - -另外一方面,如果 router(n) 需要执行 fallback 逻辑的时候,那么需要经过 router(n) 就应该决定好 fallback 逻辑 - - -### fallback 处理原则 - -由于多个 router 之间多个条件组件之后,很容易出现地址被筛选为空的情况,那么我们需要针对这情况进行 fallback 处理,保证业务在正确性的前提下,能够顺利找到有效地址。 - -首先我们看一下以下规则 - -```yaml -apiVersion: service.dubbo.apache.org/v1alpha1 -kind: VirtualService -metadata: - name: demo-route -spec: - hosts: - - demo // 统一定义为应用名 - dubbo: - - service: - - exact: com.taobao.hsf.demoService:1.0.0 - - exact: com.taobao.hsf.demoService:2.0.0 - routedetail: - - name: sayHello-String-method-route - match: - - method: - name_match: - exact: "sayHello" - ..... - argp: - - string - route: - - destination: - host: demo - subset: v1 - fallback: - destination: - host: demo - subset: v2 - fallback: - destination: - host: demo - subset: v3 - - - name: sayHello-method-route - match: - - method: - name_match: - exact: "s-method" - route: - - destination: - host: demo - subset: v2 - fallback: - destination: - host: demo - subset: v3 - - - name: interface-route - route: - - destination: - host: demo - subset: v3 - - - service: - - .... ---- -apiVersion: service.dubbo.apache.org/v1alpha1 -kind: DestinationRule -metadata: - name: demo-route -spec: - host: demo - subsets: - - name: v1 - labels: - sigma.ali/mg: v1-host - - - name: v2 - labels: - sigma.ali/mg: v2-host - - - name: v3 - labels: - sigma.ali/mg: v3-host - -``` - -我们以脚本路由为例,这个脚本路由的匹配条件是遵循一个原则的,就是匹配的范围是从精确到广泛的一个过程,在这个示例来说,就是 sayHello(string)参数 -> sayHello 方法 -> 接口级路由 的一个匹配查找过程。 - -那么如果我们已经满足某个条件,但是选到的 subset 地址为空,我们将如何进行 fallback 处理呢? - -以匹配 sayHello(string)参数 条件为例,我们选择到的是 v1 subset,如果是空,我们可以向上一级是寻找地址,也就是方法级去寻找地址,具体的配置为下 - -```yaml - - name: sayHello-String-method-route - match: - - method: - name_match: - exact: "sayHello" - ..... - argp: - - string - route: - - destination: - host: demo - subset: v1 - fallback: - destination: - host: demo - subset: v2 - fallback: - destination: - host: demo - subset: v3 -``` - -此时我们选到的地址是 v2 方法级地址,如果 v2 还是没有地址,根据规则的定义,我们是可以 fallback 到 v3 接口级。 - -假设我们有一个方法匹配时,如果没有地址,需要不进行 fallback,直接报错,我们可以这样配置 - - -```yaml -apiVersion: service.dubbo.apache.org/v1alpha1 -kind: VirtualService -metadata: - name: demo-route -spec: - hosts: - - demo // 统一定义为应用名 - dubbo: - - service: - - exact: com.taobao.hsf.demoService:1.0.0 - - exact: com.taobao.hsf.demoService:2.0.0 - routedetail: - - name: sayHello-String-method-route - match: - - method: - name_match: - exact: "sayHello" - ..... - argp: - - string - route: - - destination: - host: demo - subset: v1 - fallback: - destination: - host: demo - subset: v2 - fallback: - destination: - host: demo - subset: v3 - - - name: sayHello-method-route - match: - - method: - name_match: - exact: "s-method" - route: - - destination: - host: demo - subset: v2 - fallback: - destination: - host: demo - subset: v3 - - name: some-method-route - match: - - method: - name_match: - exact: "some-method" - route: - - destination: - host: demo - subset: v4 - - - name: interface-route - route: - - destination: - host: demo - subset: v3 - - - service: - - .... ---- -apiVersion: service.dubbo.apache.org/v1alpha1 -kind: DestinationRule -metadata: - name: demo-route -spec: - host: demo - subsets: - - name: v1 - labels: - sigma.ali/mg: v1-host - - - name: v2 - labels: - sigma.ali/mg: v2-host - - - name: v3 - labels: - sigma.ali/mg: v3-host -``` - -从这个规则我们看出来匹配到 some-method 条件时对应的是 v4 subset,那么 v4 为空时,因为没有配置 fallback ,此时会直接报错 - -#### fallback 处理原则总结 - -- 我们应该在 VirtualService route 中配置好 Destination 的 fallback 处理逻辑 -- 在 fallback subset 时,如果对应的 subset 也配置有 fallback subset 时,也应递归处理;fallback subset 之间的关系也应该是从具体到广泛 -- 我们在编写匹配条件时,应该遵循从 具体条件到广泛条件 的原则 - -### RouteChain 的组装模式 (目前未实现) - -![route-rule3.png](/imgs/user/route-rule3.png) - - -我们看到上面的图,在路由的过程当中,我们是 Pipeline 的处理方式,Pipeline 的 Router 节点存在顺序,并且每个 Router 都有一个唯一对应的 VirtualService 和 **多个** 相应的 DestinationRule 进行描述。 - -以 Nacos 上存着的路由规则配置为例,配置的格式如下: - -```yaml -DataId: Demo.rule.yaml -GROUP: HSF - -content: - -VirtualService A ---- -DestinationRule A1 ---- -DestinationRule A2 ---- -VirtualService B ---- -DestinationRule B ---- -VirtualService C ---- -DestinationRule C ---- -... -``` - -`VirtualService A` 与 `DestinationRule A1` 、`DestinationRule A2` 组成一个 Router A,`VirtualService B` 与 `DestinationRule B` 组成 Router B,以此类推,完成整个 router 链的组装。 - -### 示例:按比例流量路由规则 - -> 注意,虽然接下来的规则和 Istio 的 VirtualService、DestinationRule 很像,但工作过程和具体规则和 Istio 还是有一些差异,Dubbo 只是参考了 Istio 的设计。如果您想接入原生的 Istio 服务网格治理体系,请参考下文 [接入服务网格流量治理](#接入服务网格流量治理)。 - -在一些场景下,我们需要将相同属性的流量按比例的分发到不同的实例分组。一个典型的示例场景是 A/B 测试,比如我们需要将 20% 流量转发到服务新版本 v2 的实例,以验证新版本的稳定性,或者是将公司内部的一部分用户导流到新版本 v2 的实例进行测试验证。另一个应用场景是实现服务的金丝雀发布,通过逐步调整流量分配比例值,使得新版本的流量逐步提升并最终将全部流量完全迁移到新版本之上。 - -#### 按比例流量规则示例 - -以下示例会将访问服务 `org.apache.dubbo.demo.DetailService` 特定方法 `getDetail` 的所有请求按比例进行转发。 - -```yaml -... -apiVersion: service.dubbo.apache.org/v1alpha1 -kind: VirtualService -metadata: - name: details -spec: - dubbo: - - name: detail-service-traffic-split - match: - - name: - services: - - exact: "org.apache.dubbo.demo.DetailService" - method: - name_match: - exact: "getDetail" - route: - - destination: - subset: details-v1 - weight: 60 - - destination: - subset: details-v2 - weight: 40 ---- -... -apiVersion: service.dubbo.apache.org/v1alpha1 -kind: DestinationRule -metadata: - name: reviews-route -spec: - subsets: - - name: details-v1 - labels: - detail_version: v1 # 'version' is a reserved key in Dubbo, so must not be used. - - name: details-v2 - labels: - detail_version: v2 # 'version' is a reserved key in Dubbo, so must not be used. ---- -``` - -##### Dubbo VirtualService - -> 此部分完全可参考 Istio VirtualService 语义,两者几乎完全相同,Dubbo 增加了 `dubbo` 协议标签(对应 http 协议位置)并对 `match` 条件进行了丰富。 - -`match` 条件设置了流量规则只对访问服务 "org.apache.dubbo.demo.DetailService" 的 `getDetail` 方法的请求有效。 - -```yaml -match: - - name: - services: - - exact: "org.apache.dubbo.demo.DetailService" - method: - name_match: - exact: "getDetail" -``` - -以下 `route` 指定匹配后流量的目标实例子集,实例子集 `details-v1` `details-v2` 是通过下面的 DestinationRule 定义的。对于没有匹配的流量,则默认可以访问任何实例,不会做任何过滤。 - -```yaml -route: - - destination: - subset: details-v1 - weight: 60 - - destination: - subset: details-v2 - weight: 40 -``` - -##### Dubbo DestinationRule - -> 此部分完全可参考 Istio DestinationRule 语义,两者完全相同。 - -以下规则通过匹配 `detail_version` 值将应用 details 划分为两个部署版本 `v1` 和 `v2`,分别命名为 `deatils-v1` 和 `details-v2`,同时 `deatils-v1` 和 `details-v2` 将成为 Dubbo VirtualService 的流量转发目标对象。 - -```yaml -subsets: - - name: details-v1 - labels: - detail_version: v1 # 'version' is a reserved key in Dubbo, so must not be used. - - name: details-v2 - labels: - detail_version: v2 # 'version' is a reserved key in Dubbo, so must not be used. -``` - -> 和标签路由类似,这里牵涉到如何给您的实例打标(这里是 `detail_version`)的问题,请参考下文的 [如何给实例打标](#如何给实例打标) 一节。 - -除了以上介绍的与 Istio 流量规则很相似的功能之外,Dubbo 的 VirtualService、DestinationRule 还可以实现方法参数路由等 Istio 规则不能做到的事情,具体查看 [参考手册]()。 - - diff --git a/content/zh-cn/overview/demo/_index.md b/content/zh-cn/overview/demo/_index.md new file mode 100644 index 000000000000..52a64b0f67b1 --- /dev/null +++ b/content/zh-cn/overview/demo/_index.md @@ -0,0 +1,6 @@ +--- +title: "Demo" +layout: "shortcodes/blocks/demo-zh" +toc_hide: true +--- + {{< blocks/demo-zh >}} diff --git a/content/zh-cn/overview/home/_index.md b/content/zh-cn/overview/home/_index.md index b247ff3189e9..faa0410eae51 100644 --- a/content/zh-cn/overview/home/_index.md +++ b/content/zh-cn/overview/home/_index.md @@ -53,6 +53,7 @@ hide_feedback: true hide_summary: true linkTitle: 主页 main_menu: true +toc_hide: true menu: main: name: 文档 diff --git a/content/zh-cn/overview/mannual/_index.md b/content/zh-cn/overview/mannual/_index.md index 3b6de506518d..b2af438234a2 100755 --- a/content/zh-cn/overview/mannual/_index.md +++ b/content/zh-cn/overview/mannual/_index.md @@ -9,7 +9,7 @@ feature: description: | 提供 Java、Golang、Rust、Node.js、Python 等多语言 SDK 实现,支持基于 IDL 的跨语言服务定义和基于 Protobuf、Json 的数据编码 title: 多语言 SDK -linkTitle: SDK 用户手册 +linkTitle: 用户手册 no_list: true title: Dubbo SDK 用户手册 type: docs @@ -40,7 +40,7 @@ weight: 6

- Golang SDK + Go SDK

Dubbo Golang SDK 手册

@@ -50,9 +50,9 @@ weight: 6

- Erlang SDK + Node.js

-

Dubbo Erlang SDK 手册

+

Dubbo Node.js SDK 手册

@@ -60,9 +60,9 @@ weight: 6

- Dubbo Go Pixiu + Web SDK

-

Dubbo Go Pixiu 手册

+

Dubbo Web SDK 手册

@@ -72,11 +72,10 @@ weight: 6

Rust SDK

-

Rust SDK 手册

+

Dubbo Rust SDK 手册

-
diff --git a/content/zh-cn/overview/mannual/control-plane/_index.md b/content/zh-cn/overview/mannual/control-plane/_index.md new file mode 100644 index 000000000000..8421fd1f3f8d --- /dev/null +++ b/content/zh-cn/overview/mannual/control-plane/_index.md @@ -0,0 +1,10 @@ +--- +aliases: + - /zh/overview/reference/admin/ + - /zh-cn/overview/reference/admin/ +description: "" +linkTitle: 控制面 +title: Admin 控制台操作手册 +type: docs +weight: 20 +--- diff --git a/content/zh-cn/overview/mannual/control-plane/architecture.md b/content/zh-cn/overview/mannual/control-plane/architecture.md new file mode 100644 index 000000000000..d6b1eb5565b0 --- /dev/null +++ b/content/zh-cn/overview/mannual/control-plane/architecture.md @@ -0,0 +1,296 @@ +--- +aliases: + - /zh/overview/reference/admin/architecture/ + - /zh-cn/overview/reference/admin/architecture/ +description: "" +linkTitle: 架构与安装 +no_list: true +title: Admin 整体架构与安装步骤 +type: docs +weight: 1 +working_in_progress: true +--- + +回顾 [Dubbo 服务治理体系的总体架构](../../../what/overview/),Admin 是服务治理控制面中的一个核心组件,负责微服务集群的服务治理、可视化展示等。 + +## Admin 部署架构 + +![admin-core-components.png](/imgs/v3/reference/admin/admin-core-components.png) + +总体上来说,Admin 部署架构分为以下几个部分: +* Admin 主进程,包括服务发现元数据管理、可视化控制台、安全认证策略管控、其他定制化服务治理能力等组件。 +* 强依赖组件,包括 Mysql 数据库、注册/配置/元数据中心(可以是 Kubernetes、Nacos、Zookeeper 等) +* 可选依赖组件,包括 Prometheus、Grafana、Zipkin 等 + +## 安装 Admin + +### Dubboctl 安装 +#### Download +当前Dubboctl未正式发行,可按以下方式进行尝试。 +拉取Dubbo Admin并编译Dubboctl +```shell +git clone https://github.com/apache/dubbo-admin.git +cd dubbo-admin/cmd/dubboctl +go build -o dubboctl . +``` + +将 dubboctl 放入可执行路径 +```shell +ln -s dubbo-admin/cmd/dubboctl/dubboctl /usr/local/bin/dubboctl +``` +#### Install +安装过程会依次: + +1. 将用户自定义的配置profile以及set参数覆盖于默认profile,得到最终的profile +```yaml +# default profile +apiVersion: dubbo.apache.org/v1alpha1 +kind: DubboOperator +metadata: + namespace: dubbo-system +spec: + profile: default + namespace: dubbo-system + componentsMeta: + admin: + enabled: true + grafana: + enabled: true + repoURL: https://grafana.github.io/helm-charts + version: 6.52.4 + nacos: + enabled: true + zookeeper: + enabled: true + repoURL: https://charts.bitnami.com/bitnami + version: 11.1.6 + prometheus: + enabled: true + repoURL: https://prometheus-community.github.io/helm-charts + version: 20.0.2 + skywalking: + enabled: true + repoURL: https://apache.jfrog.io/artifactory/skywalking-helm + version: 4.3.0 + zipkin: + enabled: true + repoURL: https://openzipkin.github.io/zipkin + version: 0.3.0 +``` +建议使用自定义profile进行配置,在componentsMeta中开启或关闭组件,在components下配置各组件。其中components下各组件的配置值都是helm chart的values,各组件的具体配置请参考: +Grafana: https://github.com/grafana/helm-charts/blob/main/charts/grafana/README.md +Zookeeper: https://github.com/bitnami/charts/tree/main/bitnami/zookeeper/#installing-the-chart +Prometheus: https://github.com/prometheus-community/helm-charts/tree/main/charts +Skywalking: https://github.com/apache/skywalking-kubernetes/blob/master/chart/skywalking/README.md +Zipkin: https://github.com/openzipkin/zipkin-helm +```yaml +# customization profile +apiVersion: dubbo.apache.org/v1alpha1 +kind: DubboOperator +metadata: + namespace: dubbo-system +spec: + profile: default + namespace: dubbo-system + componentsMeta: + admin: + enabled: true + grafana: + enabled: true + version: 6.31.0 + prometheus: + enabled: false + components: + admin: + replicas: 3 + grafana: + testFramework: + enabled: false +``` +2. 根据profile拉取所需组件并生成manifest,目前Admin,Nacos已在本地,无需拉取;Grafana,Zookeeper,Prometheus,Skywalking,Zipkin将从官方chart库拉取,具体地址和版本可见上方default profile +3. 将manifest应用于k8s集群 +```shell +dubboctl manifest install # 使用默认 manifests 安装 + +# or + +dubboctl manifest generate | kubectl apply -f - +``` + +```shell +dubboctl install --set spec.components.admin.replicas=2 # 设置组件的配置 +``` + +```shell +dubboctl install --set spec.componentsMeta.admin.enabled=true, spec.componentsMeta.grafana.enabled=false +# 开启或关闭组件 +``` + +```shell +dubboctl install --set spec.componentsMeta.grafana.repoURL=https://grafana.github.io/helm-charts, spec.componentsMeta.grafana.version=6.31.0 +# 设置需远程拉取组件的仓库地址与版本 +``` + +检查安装效果 +```shell +kubectl get pod -n dubbo-system +``` + +#### 打开 Admin 控制台 +```shell +kubectl port-forward svc/dubbo-admin -n dubbo-system 38080:38080 +``` + +打开浏览器,访问: `http://127.0.0.1:38080/` + +### Helm 安装 + +获取图表 +``` +helm repo add https://charts.bitnami.com/bitnami +helm repo add https://prometheus-community.github.io/helm-charts +helm repo add https://grafana.github.io/helm-charts +helm repo add https://apache.jfrog.io/artifactory/skywalking-helm +helm repo add https://openzipkin.github.io/zipkin +``` +安装 zookeeper +```bash +helm install zookeeper bitnami/zookeeper -n dubbo-system +``` + +安装 prometheus +```bash +helm install prometheus prometheus-community/prometheus -n dubbo-system +``` + +安装 grafana +```bash +helm install grafana grafana/grafana -n dubbo-system +``` + +安装 skywalking +```bash +helm install skywalking skywalking/skywalking -n dubbo-system +``` + +安装 zipkin +``` +helm install zipkin openzipkin/zipkin -n dubbo-system +``` + +检查安装状态 +```shell +helm ls -n dubbo-system ;kubectl get pods -n dubbo-system --output wide +``` + +### VM 安装 +#### Download +下载 Dubbo Admin 发行版本 +```shell +curl -L https://dubbo.apache.org/installer.sh | VERSION=0.1.0 sh - +# Admin 要组织好发行版本 +``` + +将 dubboctl 放入可执行路径 +```shell +ln -s dubbo-admin-0.1.0/bin/dubbo-admin /usr/local/bin/dubbo-admin +``` +#### Run +```shell +dubbo-admin run -f override-configuration.yml +``` +## 配置手册 (Configuration) +配置用于控制 dubbo-admin 的行为 + + +```yaml +# Environment type. Available values are: "kubernetes" or "universal" +environment: universal # ENV: DUBBO_ENVIRONMENT +# Mode in which Dubbo CP is running. Available values are: "standalone", "global", "zone" +mode: standalone # ENV: DUBBO_MODE + +# Resource Store configuration +store: + # Type of Store used in the Control Plane. Available values are: "kubernetes", "postgres" or "memory" + type: memory # ENV: DUBBO_STORE_TYPE + + # Kubernetes Store configuration (used when store.type=kubernetes) + kubernetes: + # Namespace where Control Plane is installed to. + systemNamespace: dubbo-system # ENV: DUBBO_STORE_KUBERNETES_SYSTEM_NAMESPACE + + # Postgres Store configuration (used when store.type=postgres) + mysql: + # Host of the Postgres DB + host: 127.0.0.1 # ENV: DUBBO_STORE_POSTGRES_HOST + # Port of the Postgres DB + port: 15432 # ENV: DUBBO_STORE_POSTGRES_PORT + # User of the Postgres DB + user: dubbo # ENV: DUBBO_STORE_POSTGRES_USER + # Password of the Postgres DB + password: dubbo # ENV: DUBBO_STORE_POSTGRES_PASSWORD + # Database name of the Postgres DB + dbName: dubbo # ENV: DUBBO_STORE_POSTGRES_DB_NAME + # Connection Timeout to the DB in seconds + connectionTimeout: 5 # ENV: DUBBO_STORE_POSTGRES_CONNECTION_TIMEOUT + # Maximum number of open connections to the database + # `0` value means number of open connections is unlimited + maxOpenConnections: 50 # ENV: DUBBO_STORE_POSTGRES_MAX_OPEN_CONNECTIONS + # Maximum number of connections in the idle connection pool + # <0 value means no idle connections and 0 means default max idle connections + maxIdleConnections: 50 # ENV: DUBBO_STORE_POSTGRES_MAX_IDLE_CONNECTIONS + # TLS settings + tls: + # Mode of TLS connection. Available values are: "disable", "verifyNone", "verifyCa", "verifyFull" + mode: disable # ENV: DUBBO_STORE_POSTGRES_TLS_MODE + # Path to TLS Certificate of the client. Used in verifyCa and verifyFull modes + certPath: # ENV: DUBBO_STORE_POSTGRES_TLS_CERT_PATH + # Path to TLS Key of the client. Used in verifyCa and verifyFull modes + keyPath: # ENV: DUBBO_STORE_POSTGRES_TLS_KEY_PATH + # Path to the root certificate. Used in verifyCa and verifyFull modes. + caPath: # ENV: DUBBO_STORE_POSTGRES_TLS_ROOT_CERT_PATH + # MinReconnectInterval controls the duration to wait before trying to + # re-establish the database connection after connection loss. After each + # consecutive failure this interval is doubled, until MaxReconnectInterval + # is reached. Successfully completing the connection establishment procedure + # resets the interval back to MinReconnectInterval. + minReconnectInterval: "10s" # ENV: DUBBO_STORE_POSTGRES_MIN_RECONNECT_INTERVAL + # MaxReconnectInterval controls the maximum possible duration to wait before trying + # to re-establish the database connection after connection loss. + maxReconnectInterval: "60s" # ENV: DUBBO_STORE_POSTGRES_MAX_RECONNECT_INTERVAL +server: + port: 38080 +registry: + address: xxx +metadata-center: + address: xxx +config-center: + address: xxx +external-services: + prometheus: + # Prometheus service name is "metrics" and is in the "telemetry" namespace + # http://prometheus.:9090 + url: "http://metrics.telemetry:9090/" + tracing: + # Enabled by default. Kiali will anyway fallback to disabled if + # Jaeger is unreachable. + enabled: true + # Jaeger service name is "tracing" and is in the "telemetry" namespace. + # Make sure the URL you provide corresponds to the non-GRPC enabled endpoint + # if you set "use_grpc" to false. + in_cluster_url: 'http://tracing.telemetry:16685/jaeger' + use_grpc: true + # Public facing URL of Jaeger + url: 'http://my-jaeger-host/jaeger' + grafana: + enabled: true + # Grafana service name is "grafana" and is in the "telemetry" namespace. + in_cluster_url: 'http://grafana.telemetry:3000/' + # Public facing URL of Grafana + url: 'http://my-ingress-host/grafana' + +# 更多配置 +``` +#### 打开 Admin 控制台 + +打开浏览器,访问: `http://127.0.0.1:38080/` diff --git a/content/zh-cn/overview/mannual/control-plane/documentation.md b/content/zh-cn/overview/mannual/control-plane/documentation.md new file mode 100644 index 000000000000..e05ebf8b72fb --- /dev/null +++ b/content/zh-cn/overview/mannual/control-plane/documentation.md @@ -0,0 +1,17 @@ +--- +aliases: + - /zh/overview/reference/admin/documentation/ + - /zh-cn/overview/reference/admin/documentation/ +description: "" +linkTitle: 文档管理 +no_list: true +toc_hide: true +title: Admin 文档管理功能介绍 +type: docs +weight: 6 +working_in_progress: true +--- + +// TBD + + diff --git a/content/zh-cn/overview/mannual/control-plane/mock.md b/content/zh-cn/overview/mannual/control-plane/mock.md new file mode 100644 index 000000000000..582960435e70 --- /dev/null +++ b/content/zh-cn/overview/mannual/control-plane/mock.md @@ -0,0 +1,176 @@ +--- +aliases: + - /zh/overview/reference/admin/mock/ + - /zh-cn/overview/reference/admin/mock/ +description: "" +linkTitle: 服务Mock +no_list: true +title: Admin 服务 Mock 功能简介 +type: docs +weight: 4 +working_in_progress: true +--- + +Mock 功能是设计用来提升微服务研发与测试效率的,它可以短路 Consumer 侧发起的远程调用,提前返回预先设定好的 Mock 值,这样即使在没有 Provider 可用的情况下,消费端也能正常的推进开发、测试进程。除此之外,mock 也可用于快速模拟负责返回值的测试数据、模拟服务端异常等场景 + +需要注意的是,Mock 能力仅限用于测试环境,应避免将其用于生产环境。 + +# 设计背景 +在跨团队或是多应用开发时,在前期开发中往往会出现依赖的服务还未开发完成的情况,这样就会导致流程的阻塞,影响研发效率。基于这种情况,Dubbo Admin 提供了 mock 能力来解耦 Consumer 与 Provider 之间的依赖,以确保在 Provider 未就绪的情况下 Consumer 仍能正常开展测试,提高研发效率。 + +Dubbo 框架本身设计有服务降级(有时也称为 mock)能力,通过配置 `org.apache.dubbo.config.ReferenceConfig` 的 mock 字段(可设置为true或是对应接口的Mock实现)或动态配置规则,此时就可以启动服务降级能力。这种服务降级能力是为生产环境的限流降级准备的,虽然也可以用于本地开发测试场景,但灵活度并不高,基于提升开发效率的根本诉求,我们设计了基于 Admin 的服务降级能力。 + +Dubbo Admin 服务 mock 是一种更为轻量和便捷实现方式,主要用于开发测试阶段的,目标是提升微服务场景下的整体研发效率。需求详见:[Dubbo Admin Mock需求](https://github.com/apache/dubbo-admin/issues/757)。 + +## 架构设计 + +![admin-mock-architecture.png](/imgs/v3/reference/admin/console/mock-architecture.png) + +**实现 Mock 能力,Dubbo 框架与 Admin 侧要支持的能力** + +* Dubbo Admin + * 规则管理 + * 规则新增 + * 规则查询 + * 规则修改 + * 规则删除 + * 请求历史记录 + * Mock 请求数据查询 + * MockService Provider + * 根据规则生成 Mock 数据 + * 响应 Consumer Mock 请求 + * 保存请求和返回数据 +* Dubbo + * 根据 mock 开关配置,转发请求到 Admin 注册的 MockService + * 处理 mock 返回值并转换为匹配方法签名的强类型数据 + +**Mock 请求原理时序图** + +![admin-mock-workflow.png](/imgs/v3/reference/admin/console/mock-workflow.png) + +## 使用方式 + +1. 在 Consumer 应用中添加依赖 + + 开启 Mock 前,请确保在消费端应用中引入以下依赖: + + ```xml + + org.apache.dubbo.extensions + dubbo-mock-admin + ${version} + + ``` + + > 查看 [dubbo-mock-admin 的可用版本](/zh-cn/download/spi-extensions/) + +2. 配置 `-Denable.dubbo.admin.mock=true` 参数开启 Mock 并重启进程 +3. 打开 Admin 配置 Mock 规则 + + 用户可以通过在控制台上指定需要被 mock 的消费端IP、服务名和方法和具体的 mock 行为,实现对调用结果的 mock。 + + ![admin-mock](/imgs/v3/reference/admin/console/mock-rule-screenshot.png) + + 一些支持的规则类型与示例 + + ``` + 数字类型:123 + + 字符串:"hello, world!" + + 数组、列表:[1, 2, 3] + + 枚举:"ENUM_TYPE" + + Map、对象: + { + "prop1": "value1", + "prop2": ["a", "b", "c"] + } + + null: null + ``` + +4. 此时,消费端再次发起远程调用,就会得到预期 Mock 返回值。 + + > 注意事项 + > 1. Mock 仅限用于测试开发环境,因此为了确保核心依赖的稳定性,社区没有将 mock 组件打包在核心框架包中,用户可以自行决策是否将其作为应用的默认依赖在公司内推广 + > 2. 即使添加了 mock 二进制依赖,mock 功能也不会默认开启,需要设置 `-Denable.dubbo.admin.mock=true` 后才能开启。 + +## 实现原理 + +Consumer 调用发起的调用会被本地的 MockServiceFilter 拦截,如果 mock 开关开启,则 MockServiceFilter 将请求转发到 MockService (由 Dubbo Admin 发布的服务),MockService 根据请求的服务、方法等查询用户预先配置的 mock 规则,如果查询到则返回规则中的 mock 值,Consumer 收到 mock 值后调用成功返回。 + +### Mock 返回值如何定义? + +当前 Admin 支持录入 JSON 或者基本类型数据,如: + +* 返回数字值 (当方法签名返回值是数字类型) + +``` +123 +``` + +* 返回字符串 (当方法签名返回值是字符串类型) +``` +"hello, world!" +``` + +* 返回 JSON (当方法签名返回值是 Map 或对象类型) +``` +{ + "prop1": "value1", + "prop2": ["a", "b", "c"] +} +``` + +* 返回数组 (当方法签名返回值是数组或列表) +``` +[1, 2, 3] +``` + +### 消费端如何发起 MockService 调用? + +`dubbo-mock-admin` 将为消费端引入 MockServiceFilter 请求拦截器,如果用户打开 mock 开关,那么 Filter 会将请求转发到 Admin MockService 服务。 + +### Mock 值如何转换为原始类型值? + +MockService 支持返回标准 JSON 格式或者基本类型数据,消费端会基于 Dubbo 内置类型转换器将 JSON 等值转为原始对象类型。 + +### 未来优化点 +* 保存 Mock 开关到配置中心,用户可以通过 Admin 动态控制开关。 +* 开启 Mysql 数据库链接池 + +### 表结构设计 +Admin 依赖 Mysql 数据库存储用户配置的 mock 规则,具体的表结构设计如下。 + +#### Mock Rule + +```sql +CREATE TABLE `mock_rule` ( + `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', + `service_name` varchar(255) DEFAULT NULL COMMENT '服务名', + `method_name` varchar(255) DEFAULT NULL COMMENT '方法名', + `rule` text NULL DEFAULT COMMENT '规则', + `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='服务mock方法表'; +``` +#### Mock Log + +```sql +CREATE TABLE `mock_log` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键id', + `method_id` int(11) DEFAULT NULL COMMENT '规则id', + `request` text COMMENT '请求数据', + `response` text COMMENT '返回值', + `created_at` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `updated_at` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='mock请求记录表'; +``` + + + + diff --git a/content/zh-cn/overview/reference/admin/search.md b/content/zh-cn/overview/mannual/control-plane/search.md similarity index 94% rename from content/zh-cn/overview/reference/admin/search.md rename to content/zh-cn/overview/mannual/control-plane/search.md index 9001fa34093e..031f5289c8b9 100644 --- a/content/zh-cn/overview/reference/admin/search.md +++ b/content/zh-cn/overview/mannual/control-plane/search.md @@ -1,4 +1,7 @@ --- +aliases: + - /zh/overview/reference/admin/search/ + - /zh-cn/overview/reference/admin/search/ description: "" linkTitle: 文档查询 title: Admin 服务查询 diff --git a/content/zh-cn/overview/reference/admin/test.md b/content/zh-cn/overview/mannual/control-plane/test.md similarity index 98% rename from content/zh-cn/overview/reference/admin/test.md rename to content/zh-cn/overview/mannual/control-plane/test.md index 0e002de91d42..ce4a83b3356c 100644 --- a/content/zh-cn/overview/reference/admin/test.md +++ b/content/zh-cn/overview/mannual/control-plane/test.md @@ -1,4 +1,7 @@ --- +aliases: + - /zh/overview/reference/admin/test/ + - /zh-cn/overview/reference/admin/test/ description: "" linkTitle: 服务测试 no_list: true @@ -187,4 +190,4 @@ public class LocationDO { ### 泛化调用 -有了参数类型,下一个问题就是怎么能够调用到服务端,在传统的Dubbo RPC调用中,客户端需要依赖服务端的API jar包 (参考 [Quick Start](https://github.com/apache/dubbo-samples/tree/master/1-basic/dubbo-samples-spring-boot/dubbo-samples-spring-boot-consumer) 中的消费端示例,这对于 Dubbo Admin 来说不太可能,因为服务的上下线是动态的,Dubbo Admin 无法动态增加 jar 包依赖,因此需要用到 Dubbo 中的[**泛化调用**](../../../mannual/java-sdk/advanced-features-and-usage/service/generic-reference/),指的是在没有服务端API接口的情况下,客户端直接通过 `GenericService` 接口来发起服务调用,返回值中的数据对象都用Map来表示。泛化调用在服务端不需要做特殊处理,只需要客户端发起即可。 \ No newline at end of file +有了参数类型,下一个问题就是怎么能够调用到服务端,在传统的Dubbo RPC调用中,客户端需要依赖服务端的API jar包 (参考 [Quick Start](https://github.com/apache/dubbo-samples/tree/master/1-basic/dubbo-samples-spring-boot/dubbo-samples-spring-boot-consumer) 中的消费端示例,这对于 Dubbo Admin 来说不太可能,因为服务的上下线是动态的,Dubbo Admin 无法动态增加 jar 包依赖,因此需要用到 Dubbo 中的[**泛化调用**](../../../mannual/java-sdk/advanced-features-and-usage/service/generic-reference/),指的是在没有服务端API接口的情况下,客户端直接通过 `GenericService` 接口来发起服务调用,返回值中的数据对象都用Map来表示。泛化调用在服务端不需要做特殊处理,只需要客户端发起即可。 diff --git a/content/zh-cn/overview/mannual/dubbo-go-pixiu/_index.md b/content/zh-cn/overview/mannual/dubbo-go-pixiu/_index.md deleted file mode 100755 index ffc0955c4479..000000000000 --- a/content/zh-cn/overview/mannual/dubbo-go-pixiu/_index.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/dubbo-go-pixiu/ - - /zh-cn/docs3-v2/dubbo-go-pixiu/ -description: Dubbo Go Pixiu -linkTitle: Dubbo Go Pixiu -title: Dubbo Go Pixiu -type: docs -weight: 3 ---- diff --git a/content/zh-cn/overview/mannual/dubbo-go-pixiu/dev/_index.md b/content/zh-cn/overview/mannual/dubbo-go-pixiu/dev/_index.md deleted file mode 100755 index 498afec54a5d..000000000000 --- a/content/zh-cn/overview/mannual/dubbo-go-pixiu/dev/_index.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/dubbo-go-pixiu/dev/ - - /zh-cn/docs3-v2/dubbo-go-pixiu/dev/ -description: 开发者指南 -linkTitle: 开发者指南 -title: 开发者指南 -type: docs -weight: 30 ---- diff --git a/content/zh-cn/overview/mannual/dubbo-go-pixiu/overview/_index.md b/content/zh-cn/overview/mannual/dubbo-go-pixiu/overview/_index.md deleted file mode 100755 index 201ba51b761c..000000000000 --- a/content/zh-cn/overview/mannual/dubbo-go-pixiu/overview/_index.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/dubbo-go-pixiu/overview/ - - /zh-cn/docs3-v2/dubbo-go-pixiu/overview/ -description: 入门概述 -linkTitle: 入门概述 -title: 入门概述 -type: docs -weight: 10 ---- diff --git a/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/_index.md b/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/_index.md deleted file mode 100755 index be140f46f130..000000000000 --- a/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/_index.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/dubbo-go-pixiu/user/ - - /zh-cn/docs3-v2/dubbo-go-pixiu/user/ -description: 用户文档 -linkTitle: 用户文档 -title: 用户文档 -type: docs -weight: 20 ---- diff --git a/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/adapter/_index.md b/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/adapter/_index.md deleted file mode 100755 index 4ec10d599cd1..000000000000 --- a/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/adapter/_index.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/dubbo-go-pixiu/user/adapter/ - - /zh-cn/docs3-v2/dubbo-go-pixiu/user/adapter/ -description: Adapter 介绍 -linkTitle: Adapter 介绍 -title: Adapter 介绍 -type: docs -weight: 60 ---- diff --git a/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/adapter/dubbo.md b/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/adapter/dubbo.md deleted file mode 100644 index 9f20c49fea76..000000000000 --- a/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/adapter/dubbo.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/dubbo-go-pixiu/user/adapter/dubbo/ - - /zh-cn/docs3-v2/dubbo-go-pixiu/user/adapter/dubbo/ -description: Dubbo 集群中心 Adapter -linkTitle: Dubbo 集群中心 Adapter -title: Dubbo 集群中心 Adapter -type: docs -weight: 10 ---- diff --git a/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/adapter/springcloud.md b/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/adapter/springcloud.md deleted file mode 100644 index 03e9bd52d100..000000000000 --- a/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/adapter/springcloud.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/dubbo-go-pixiu/user/adapter/springcloud/ - - /zh-cn/docs3-v2/dubbo-go-pixiu/user/adapter/springcloud/ -description: Spring Cloud 集群中心 Adapter -linkTitle: Spring Cloud 集群中心 Adapter -title: Spring Cloud 集群中心 Adapter -type: docs -weight: 20 ---- diff --git a/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/appendix/_index.md b/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/appendix/_index.md deleted file mode 100755 index fd47ce60c8a0..000000000000 --- a/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/appendix/_index.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/dubbo-go-pixiu/user/appendix/ - - /zh-cn/docs3-v2/dubbo-go-pixiu/user/appendix/ -description: 附录 -linkTitle: 附录 -title: 附录 -type: docs -weight: 90 ---- diff --git a/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/httpfilter/_index.md b/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/httpfilter/_index.md deleted file mode 100755 index 290ba4d38c3e..000000000000 --- a/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/httpfilter/_index.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/dubbo-go-pixiu/user/httpfilter/ - - /zh-cn/docs3-v2/dubbo-go-pixiu/user/httpfilter/ -description: Http Filter 介绍 -linkTitle: Http Filter 介绍 -title: Http Filter 介绍 -type: docs -weight: 60 ---- diff --git a/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/httpfilter/hystrix.md b/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/httpfilter/hystrix.md deleted file mode 100644 index 6326c35a0007..000000000000 --- a/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/httpfilter/hystrix.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/dubbo-go-pixiu/user/httpfilter/hystrix/ - - /zh-cn/docs3-v2/dubbo-go-pixiu/user/httpfilter/hystrix/ -description: 断路器介绍 -linkTitle: 断路器介绍 -title: 断路器介绍 -type: docs -weight: 30 ---- - - - - - - -欢迎认领补充此文档。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/httpfilter/ratelimit.md b/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/httpfilter/ratelimit.md deleted file mode 100644 index 0787544cd573..000000000000 --- a/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/httpfilter/ratelimit.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/dubbo-go-pixiu/user/httpfilter/ratelimit/ - - /zh-cn/docs3-v2/dubbo-go-pixiu/user/httpfilter/ratelimit/ -description: RateLimiter 介绍 -linkTitle: RateLimiter 介绍 -title: RateLimiter 介绍 -type: docs -weight: 20 ---- - - - - - - -欢迎认领补充此文档。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/listener/_index.md b/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/listener/_index.md deleted file mode 100755 index ca07556a9eb4..000000000000 --- a/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/listener/_index.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/dubbo-go-pixiu/user/listener/ - - /zh-cn/docs3-v2/dubbo-go-pixiu/user/listener/ -description: Listener 介绍 -linkTitle: Listener 介绍 -title: Listener 介绍 -type: docs -weight: 40 ---- diff --git a/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/listener/http.md b/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/listener/http.md deleted file mode 100644 index b28e8dfaadb8..000000000000 --- a/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/listener/http.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/dubbo-go-pixiu/user/listener/http/ - - /zh-cn/docs3-v2/dubbo-go-pixiu/user/listener/http/ -description: Http Listener 介绍 -linkTitle: Http Listener 介绍 -title: Http Listener 介绍 -type: docs -weight: 10 ---- - - - - - - -Http Listener 是专门负载接收 HTTP 请求的 Listener,它可以设置 HTTP 监听的地址和端口。它可以通过如下配置进行引入。 - -``` -static_resources: - listeners: - - name: "net/http" - protocol_type: "HTTP" # 表明是引入 HTTP Listener - address: - socket_address: - address: "0.0.0.0" # 地址 - port: 8883 # 端口 -``` - -Http Listener 的具体实现可以参考 `pkg/listener/http`。 - -有关 HTTP Listener 的案例,可以参考: -- HTTP to Dubbo 请求的转换,[案例](/zh-cn/overview/mannual/dubbo-go-pixiu/user/samples/http_to_dubbo/) -- HTTP 请求代理,[案例](/zh-cn/overview/mannual/dubbo-go-pixiu/user/samples/http_proxy/) - -目前也支持 HTTPS 协议。可以将 `protocol_type` 修改为 `HTTPS`。并且添加 `domains` 和 `certs_dir` 来指定域名和 cert 文件目录。 - -``` - listeners: - - name: "net/http" - protocol_type: "HTTPS" - address: - socket_address: - domains: - - "sample.domain.com" - - "sample.domain-1.com" - - "sample.domain-2.com" - certs_dir: $PROJECT_DIR/cert -``` - -具体案例可以查看 [案例](/zh-cn/overview/mannual/dubbo-go-pixiu/user/samples/https/) \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/listener/http2.md b/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/listener/http2.md deleted file mode 100644 index cd7c82ba7d0d..000000000000 --- a/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/listener/http2.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/dubbo-go-pixiu/user/listener/http2/ - - /zh-cn/docs3-v2/dubbo-go-pixiu/user/listener/http2/ -description: Http2 Listener 介绍 -linkTitle: Http2 Listener 介绍 -title: Http2 Listener 介绍 -type: docs -weight: 20 ---- - - - - - - -欢迎认领补充此文档。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/listener/tcp.md b/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/listener/tcp.md deleted file mode 100644 index 6ebb172b27e5..000000000000 --- a/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/listener/tcp.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/dubbo-go-pixiu/user/listener/tcp/ - - /zh-cn/docs3-v2/dubbo-go-pixiu/user/listener/tcp/ -description: TCP Listener 介绍 -linkTitle: TCP Listener 介绍 -title: TCP Listener 介绍 -type: docs -weight: 30 ---- - - - - - - -欢迎认领补充此文档。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/listener/triple.md b/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/listener/triple.md deleted file mode 100644 index 051f6ef177f3..000000000000 --- a/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/listener/triple.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/dubbo-go-pixiu/user/listener/triple/ - - /zh-cn/docs3-v2/dubbo-go-pixiu/user/listener/triple/ -description: Triple Listener 介绍 -linkTitle: Triple Listener 介绍 -title: Triple Listener 介绍 -type: docs -weight: 40 ---- - - - - - - -欢迎认领补充此文档。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/networkfilter/_index.md b/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/networkfilter/_index.md deleted file mode 100755 index f75123a0bcf3..000000000000 --- a/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/networkfilter/_index.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/dubbo-go-pixiu/user/networkfilter/ - - /zh-cn/docs3-v2/dubbo-go-pixiu/user/networkfilter/ -description: Network Filter 介绍 -linkTitle: Network Filter 介绍 -title: Network Filter 介绍 -type: docs -weight: 50 ---- diff --git a/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/networkfilter/dubbo.md b/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/networkfilter/dubbo.md deleted file mode 100644 index 4dcfbca3dd00..000000000000 --- a/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/networkfilter/dubbo.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/dubbo-go-pixiu/user/networkfilter/dubbo/ - - /zh-cn/docs3-v2/dubbo-go-pixiu/user/networkfilter/dubbo/ -description: Dubbo NetWorkFilter 介绍 -linkTitle: Dubbo NetWorkFilter 介绍 -title: Dubbo NetWorkFilter 介绍 -type: docs -weight: 30 ---- - - - - - - -欢迎认领补充此文档。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/networkfilter/http.md b/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/networkfilter/http.md deleted file mode 100644 index c58aec4c004f..000000000000 --- a/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/networkfilter/http.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/dubbo-go-pixiu/user/networkfilter/http/ - - /zh-cn/docs3-v2/dubbo-go-pixiu/user/networkfilter/http/ -description: Http NetWorkFilter 介绍 -linkTitle: Http NetWorkFilter 介绍 -title: Http NetWorkFilter 介绍 -type: docs -weight: 10 ---- - - - - - - -Http NetWorkFilter 用来处理 HTTP 请求,它能接收来自 HTTP Listener 传递的 HTTP 请求,然后将其交给自身维护的 HTTP Filter 链进行处理,最后将响应返回给调用方。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/quality/_index.md b/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/quality/_index.md deleted file mode 100755 index 8422e88acf82..000000000000 --- a/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/quality/_index.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/dubbo-go-pixiu/user/quality/ - - /zh-cn/docs3-v2/dubbo-go-pixiu/user/quality/ -description: 质量指标 -linkTitle: 质量指标 -title: 质量指标 -type: docs -weight: 80 ---- diff --git a/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/quality/performance.md b/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/quality/performance.md deleted file mode 100755 index 082d8f901f80..000000000000 --- a/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/quality/performance.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/dubbo-go-pixiu/user/quality/performance/ - - /zh-cn/docs3-v2/dubbo-go-pixiu/user/quality/performance/ -description: 性能 -linkTitle: 性能 -title: 性能 -type: docs -weight: 10 ---- - - - - - - -欢迎认领补充此文档。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/quality/stability.md b/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/quality/stability.md deleted file mode 100644 index 6687acf1657e..000000000000 --- a/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/quality/stability.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/dubbo-go-pixiu/user/quality/stability/ - - /zh-cn/docs3-v2/dubbo-go-pixiu/user/quality/stability/ -description: 稳定性 -linkTitle: 稳定性 -title: 稳定性 -type: docs -weight: 10 ---- - - - - - - -欢迎认领补充此文档。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/samples/_index.md b/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/samples/_index.md deleted file mode 100755 index 24d2c344bdce..000000000000 --- a/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/samples/_index.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/dubbo-go-pixiu/user/samples/ - - /zh-cn/docs3-v2/dubbo-go-pixiu/user/samples/ -description: 案例介绍 -linkTitle: 案例介绍 -title: 案例介绍 -type: docs -weight: 70 ---- diff --git a/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/samples/http_to_dubbo.md b/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/samples/http_to_dubbo.md deleted file mode 100644 index 9ee572397f62..000000000000 --- a/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/samples/http_to_dubbo.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/dubbo-go-pixiu/user/samples/http_to_dubbo/ - - /zh-cn/docs3-v2/dubbo-go-pixiu/user/samples/http_to_dubbo/ -description: Http to Dubbo 案例介绍 -linkTitle: Http to Dubbo 案例介绍 -title: Http to Dubbo 案例介绍 -type: docs -weight: 20 ---- - - - - - - -欢迎认领补充此文档。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/samples/https.md b/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/samples/https.md deleted file mode 100644 index 3d8a389a4c53..000000000000 --- a/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/samples/https.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/dubbo-go-pixiu/user/samples/https/ - - /zh-cn/docs3-v2/dubbo-go-pixiu/user/samples/https/ -description: Https 案例介绍 -linkTitle: Https 案例介绍 -title: Https 案例介绍 -type: docs -weight: 30 ---- - - - - - - -欢迎认领补充此文档。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/erlang-sdk/_index.md b/content/zh-cn/overview/mannual/erlang-sdk/_index.md deleted file mode 100755 index fb1ec3e6297e..000000000000 --- a/content/zh-cn/overview/mannual/erlang-sdk/_index.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/erlang-sdk/ - - /zh-cn/docs3-v2/erlang-sdk/ -description: Erlang 支持 -linkTitle: Erlang SDK -title: Erlang SDK 手册 -type: docs -weight: 5 ---- diff --git a/content/zh-cn/overview/mannual/erlang-sdk/quick-start.md b/content/zh-cn/overview/mannual/erlang-sdk/quick-start.md deleted file mode 100644 index 5f54a0e8732e..000000000000 --- a/content/zh-cn/overview/mannual/erlang-sdk/quick-start.md +++ /dev/null @@ -1,74 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/erlang-sdk/quick-start/ - - /zh-cn/docs3-v2/erlang-sdk/quick-start/ -description: Erlang 快速开始 -linkTitle: 快速开始 -title: 快速开始 -type: docs -weight: 1 ---- - - - - - - -建议先使用 java 定义接口 jar,并使用 [erlanalysis](https://github.com/apache/dubbo-erlang/tree/master/tools/erlanalysis) 工具解析java接口至Erlang lib - -## 导入依赖库 - -### 使用 Rebar 编译工具。 -Add dubblerl to rebar.config with your project -```erlang -{deps, [ - {dubboerl, {git, "https://github.com/apache/dubbo-erlang.git", {branch, "master"}}} -]}. -``` - -### 使用 erlang.mk 编译工具 -`待补充` - -## 导入接口库 -Suppose the interface lib you exported is called dubbo_service. -* If you didn't upload your lib to your git repository, It is recommended that you copy the `dubbo_service` lib -into the project's `apps` directory. -* If it is upload to your git repository, you can import like this: -```erlang -{deps, [ - {dubboerl, {git, "https://github.com/apache/dubbo-erlang.git", {branch, "master"}}}, - {dubbo_service,{git,"${INTERFACE_LIB_URL}",{branch,"master"}}} %% replace ${INTERFACE_LIB_URL} with your lib git repos url -]}. -``` - -## 消费者配置 -Please reference [Reference Config](../reference/) - -## Init dubbolib in your project -It is need you -```erlang -dubboerl:init(). -``` - -## 如何调用? - -### 同步调用 -```erlang -Request = #userInfoRequest{requestId = 123, username = "testname"}, -{ok,RequestRef,Response,RpcContent} = userOperator:queryUserInfo(Request,#{sync=> true}). -``` -If it occur error, is reponse `{error,Reason}`. - -### 异步调用 - -Default is Async call. -```erlang -Request = #userInfoRequest{requestId = 123, username = "testname"}, -{ok,RequestRef} = userOperator:queryUserInfo(Request). - -%% you can receive the message after. -handle_cast({msg_back,RequestRef,Response,RpcContent},State). -``` - -## 示例 -参考项目 [dubboerl_demo](https://github.com/apache/dubbo-erlang/tree/master/samples) diff --git a/content/zh-cn/overview/mannual/erlang-sdk/serialization.md b/content/zh-cn/overview/mannual/erlang-sdk/serialization.md deleted file mode 100644 index a78b2ffd1f87..000000000000 --- a/content/zh-cn/overview/mannual/erlang-sdk/serialization.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/erlang-sdk/serialization/ - - /zh-cn/docs3-v2/erlang-sdk/serialization/ -description: 在 erlang 中配置序列化方式 -linkTitle: 序列化配置项 -title: 序列化配置项 -type: docs -weight: 4 ---- - - - - - - -当前该库只实现了 `dubbo://` 通讯协议。 - -序列化方式实现了 `hessian` 和 `json` 两种方式。 - -## 配置样例 - -序列化配置需要添加到 `sys.config` 文件 `dubboerl` 应用配置项里。 - -```erlang -{dubboerl,[ - %% other config ... - {protocol,hessian} -]} -``` - -| ConfigName | Type | DefaultValue | Remarks | -| --- | --- | --- | --- | -| protocol | atom() | hessian | hessian,json | diff --git a/content/zh-cn/overview/mannual/golang-sdk/_index.md b/content/zh-cn/overview/mannual/golang-sdk/_index.md index cfe0135770aa..cfece42de572 100755 --- a/content/zh-cn/overview/mannual/golang-sdk/_index.md +++ b/content/zh-cn/overview/mannual/golang-sdk/_index.md @@ -4,7 +4,7 @@ aliases: - /zh-cn/docs3-v2/golang-sdk/ description: Golang SDK 手册 linkTitle: Golang SDK -title: Golang SDK 手册 +title: Golang SDK type: docs weight: 2 --- diff --git a/content/zh-cn/overview/mannual/golang-sdk/introduction.md b/content/zh-cn/overview/mannual/golang-sdk/introduction.md new file mode 100644 index 000000000000..61191e64c539 --- /dev/null +++ b/content/zh-cn/overview/mannual/golang-sdk/introduction.md @@ -0,0 +1,124 @@ +--- +aliases: + - /zh/docs3-v2/golang-sdk/preface/ + - /zh-cn/docs3-v2/golang-sdk/preface/ + - /zh-cn/overview/mannual/golang-sdk/preface/ + - /zh-cn/overview/mannual/golang-sdk/preface/concept/ + - /zh-cn/overview/mannual/golang-sdk/preface/concept/protocol/ +description: Dubbo-go 框架 +linkTitle: 框架介绍 +title: 框架介绍 +type: docs +weight: 1 +--- + +## 什么是 dubbo-go +Dubbo-go 是 Apache Dubbo 的 go 语言实现,它完全遵循 Apache Dubbo 设计原则与目标,是 go 语言领域的一款优秀微服务开发框架。dubbo-go 提供: +* **API 与 RPC 协议**:帮助解决组件之间的 RPC 通信问题,提供基于 HTTP/1/2 的通信协议、streaming流式通信模型。 +* **丰富的微服务治理能力**:解决地址发现、流量管控、可观测性、全链路追踪、日志等微服务整体解决方案。 + +## 概念与架构 +以下是 dubbo-go 的整体架构图: +![dubbo-go architecture](/imgs/golang/architecture/arc.png) + +dubbo-go 总体上遵循 `框架内核+插件` 的的设计理念,左侧的 `框架内核` 定义了 dubbo-go 作为微服务框架的一些核心概念,右侧的 `插件` 部分则提供了核心概念扩展实现。 + +`框架内核` 可分为 4 个层次,从上到下依次为: +* API 层:dubbo-go 同时支持基于 IDL、interface/struct 的服务契约定义,兼顾跨语言与易用性诉求;支持基于纯 yaml 文件的微服务配置模式;提供了同步、异步、单次(unary)、流式(streaming) 等 RPC 通信与编码模型。 + +* 服务治理层:dubbo-go 内置了多维度的服务治理能力抽象,确保满足微服务开发与集群治理的核心诉求,这包括地址发现(Service Discovery)、负载均衡(Load Balancing)、可观测指标(Metrics)、流量管控(Traffic Management)、全链路追踪(Tracing)等。 + +* RPC 协议层:dubbo-go 实现的最核心的 RPC 协议是 - triple 协议,triple 可同时工作在 http1/2 之上 (支持 CURL 直接访问),兼容 gRPC;从设计上,dubbo-go 还提供了多协议发布服务的支持,你可以在一个进程内同时发布 triple、dubbo2、rest、jsonRPC 等多种不同通信协议的服务。 + +* 传输层:支持 HTTP1/2、TCP 传输层,兼顾性能与通用性,同时支持多种序列化方式。 + +`插件` 体系极大的丰富了 dubbo-go 功能与生态,社区内置提供了大量的内置扩展实现,同时,开发者可以非常容易的根据需求增加扩展实现。以下是一些典型的插件定义: + +* Protocol:dubbo-go 基于 protocol 插件内置提供了 triple、dubbo2、rest 等协议支持,通过扩展 protocol 可以为 dubbo-go 扩展更多协议 +* Service Discovery:支持 Nacos、Zookeeper、Polaris 等主流注册中心集成 +* Traffic Management:dubbo-go 支持 Dubbo 体系定义的流量规则,可以实现在运行期动态的调整服务行为如超时时间、重试次数、限流参数等,通过控制流量分布可以实现 A/B 测试、金丝雀发布、多版本按比例流量分配、条件匹配路由、黑白名单等 +* Metrics:提供 RPC 调用(RT、QPS、调用量、请求成功数、请求失败数、并发请求数等)、注册中心、元数据中心、配置中心交互统计等丰富的内置采集埋点,支持多维度的指标聚合 +* Logging:提供通用的日志采集接口定义,内置 Zap、Logrus 支持 +* Tracing:提供分布式链路追踪能力,通过此插件扩展可接入 Zipkin、Jaeger、Skywalking 等链路追踪系统。 + +下图是从内核源码视角,给出的框架核心组件以及组件之间的关联关系: + +![img](/imgs/docs3-v2/golang-sdk/concept/more/app_and_interface/dubbogo-concept.png) + +### RPC +#### Triple +基于 Dubbo 定义的 [triple 协议](/zh-cn/overview/reference/protocols/triple/),你可以轻松编写浏览器、gRPC 兼容的 RPC 服务,并让这些服务同时运行在 HTTP/1 和 HTTP/2 上。作为 Apache Dubbo 多语言 RPC体系的一环,dubbo-go 提供了 triple 协议的完整实现,支持使用 IDL 或编程语言特有的方式定义服务,并提供一套轻量的 API 来发布或调用这些服务。triple 协议让 dubbo-go 可以: +* **作为后端服务与 Dubbo 其他语言实现互通** +* **接收浏览器等标准 http 工具发起的请求** +* **与标准的 gRPC 体系互通** + +![dubbo多语言实现](/imgs/golang/architecture/language.png) + +请参考以下链接了解更多 dubbo-go 跨语言或跨产品的互通细节: +* [与 Dubbo 其他多语言体系互通 - 基于 triple+protobuf](../tutorial/interop-dubbo/) +* [与 Dubbo2 Java互通 - 基于 dubbo2+hessian2](../tutorial/interop-dubbo) +* [与 gRPC 体系互通](../tutorial/interop-grpc) + +#### 多协议支持 +除了 triple 协议之外,dubbo-go 支持更多的 RPC 协议和序列化方式: + +| 协议 | 协议名 (用于配置) | 序列化方式 | 默认序列化方式 | +| --------------- | ----------------- | :------------------------: | -------------- | +| Triple 【推荐】 | tri | pb/json/自定义 | pb | +| Dubbo | dubbo | hessian2 | hessian2 | +| jsonRPC | jsonrpc | json | json | +| REST | rest | json | json | + +#### Filter +如下图所示,filter 是一个类似 AOP 的请求拦截机制,每一次 RPC 请求都会被 filter 拦截 + +![dubbo多语言实现](/imgs/golang/architecture/filter.png) + +我们可以在 filter 实现中完成比如请求拦截、记录、预处理、后处理的事情。dubbo-go 的一些核心能力,比如超时时间、访问日志(ccesslog)、metrtics 等都是基于内置 filter 实现的。 + +#### Streaming + +![dubbo多语言实现](/imgs/golang/architecture/streaming.png) + +* Server streaming RPC:一次 server-streaming RPC 请求与 unary RPC 非常类似,不同之处在于,对于单次 client 请求 server 会返回一系列的流式响应。 + +* Client streaming RPC:一次 client-streaming RPC 请求与 unary RPC 非常类似,不同之处在于,client 会发送一系列的流式请求到 server,最终 server 针对所有收到的请求返回一条响应信息。 + +* Bidirectional streaming RPC:在双向流式 RPC 请求中,请求首先由 client 端发起,server 在收到请求信息(方法名、metadata等)后,可以选择立即发送 metadata 作为响应,或者一直等到 client 进一步发起流式请求数据。 + +### 服务治理 +dubbo-go 提供了完善的服务治理能力,包括地址发现、可观测、全链路追踪、流量管控等。你可以使用 dubbo-go 开发与管理微服务集群并实现与 Apache Dubbo 其他语言体系的互通。 + +#### 地址发现 +![img](/imgs/architecture.png) + +Dubbo-go 支持的注册中心类型如下,具体配置方式请参考使用教程 [地址发现](../tutorial/service-discovery/): + +| 注册中心 | 注册中心名(用于配置) | +| --------- | ---------------------- | +| Zookeeper | zookeeper | +| Nacos | nacos | +| Etcd | etcd | +| Polaris | polaris | + +#### 可观测 +dubbo-go 的可视化指标采集遵循 Apache Dubbo 定义的 [metrics 指标规范](/zh-cn/overview/reference/Metrics/standard_metrics/)。在实现 metrics 指标采集后,接下来就是如何可视化展示的问题,当前最常用的式导出到 Prometheus 并通过 Grafana 实现数据可视化展示。 + +具体启用方式请参考使用手册中的 [可视化观测](../tutorial/observability/)。 + +#### 全链路追踪 +dubbo-go 支持通过 Open Telemetry 接入 Zipkin、Jaeger、Skywalking 等全链路追踪系统。 + +具体启用方式请参考使用手册中的 [全链路追踪](../tutorial/tracing/)。 + +#### 流量管控 +dubbo-go 实现的流量治理规则完全遵循 Dubbo 框架设计的流量治理能力,可以通过以下链接了解更多详情: +* [Dubbo 流量治理规则设计](/zh-cn/overview/core-features/traffic/) +* [Dubbo 流量治理示例任务](/zh-cn/overview/tasks/traffic-management/) + + + + + + + diff --git a/content/zh-cn/overview/mannual/golang-sdk/preface/_index.md b/content/zh-cn/overview/mannual/golang-sdk/preface/_index.md deleted file mode 100644 index 8a33ed5d5663..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/preface/_index.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/preface/ - - /zh-cn/docs3-v2/golang-sdk/preface/ -description: Dubbo-go 框架 -linkTitle: 框架介绍 -title: 框架介绍 -type: docs -weight: 1 ---- - -![img](/imgs/docs3-v2/golang-sdk/concept/dubbogo.png) - -Apache/Dubbo-go ([github.com/apache/dubbo-go](https://github.com/apache/dubbo-go)) - -是一款分布式 RPC 框架;是 Apache/Dubbo 的 Go 语言实现。旨在为开发者提供便利的微服务应用开发体验。 - -Dubbo-go 架起 Java 和 Go 语言之间的桥梁,与 gRPC/Dubbo/SpringCloud 生态互联互通,依赖 Go 语言生态发掘云原生时代的技术红利。 diff --git a/content/zh-cn/overview/mannual/golang-sdk/preface/concept/_index.md b/content/zh-cn/overview/mannual/golang-sdk/preface/concept/_index.md deleted file mode 100644 index ca1d23bfe5e0..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/preface/concept/_index.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/preface/concept/ - - /zh-cn/docs3-v2/golang-sdk/preface/concept/ -description: Dubbo-go 框架概念体系 -linkTitle: 概念体系 -title: 概念体系 -type: docs -weight: 2 ---- diff --git a/content/zh-cn/overview/mannual/golang-sdk/preface/concept/generic.md b/content/zh-cn/overview/mannual/golang-sdk/preface/concept/generic.md deleted file mode 100644 index 123a5ce9da81..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/preface/concept/generic.md +++ /dev/null @@ -1,162 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/preface/concept/generic/ - - /zh-cn/docs3-v2/golang-sdk/preface/concept/generic/ -description: 泛化调用 -keywords: 泛化调用 -title: 泛化调用 -type: docs ---- - - - - - - -泛化调用是一种 Dubbo-Go 的特殊调用方式,它允许中间节点在没有接口信息的情况下传递调用信息,常被用于测试、网关的场景下。泛化调用支持 Dubbo 和 Triple 协议,但是目前序列化方案只支持 Hessian。 - -## 背景 - -为了便于理解,这篇文档中以网关使用场景介绍泛化调用。我们先来考虑普通调用(非泛化调用)。下图包含了 consumer 和 provider 两个关键角色(后文中用 endpoint 代表一个 consumer 或一个 provider),各自都有一份关于 org.apache.dubbo.sample.User 接口的定义。假定在调用行为中需要使用 org.apache.dubbo.sample.User 接口。 - -![img](/imgs/docs3-v2/golang-sdk/concept/rpc/generic/1631941941270-86ce9845-5a88-4cb5-8c8a-da8ae7eeb4d5.png) - -RPC 需要借助网络介质传输,因此数据不能以 go struct 形式传输,而必须以二进制形式传输。这就要求 consumer 端在传输前,需要将实现 org.apache.dubbo.sample.User 接口的结构体序列化为二进制格式。同样的,对于 provider 端,需要将二进制数据反序列化为结构体信息。**总之,普通调用要求接口信息在每一个 endpoint 必须有相同的定义,这样才能保证数据序列化和反序列化的结果与预期一致**。 - -在网关场景下,网关不可能存储全部接口定义。比如一个网关需要转发 100 个服务调用,每个服务需要的接口数量为 10 个,普通调用要求把 1000 个(100 * 10)接口定义提前全部存储在网关内,这显然是难以做到的。所以有没有一种方式可以既不需要提前存储接口定义,又能正确转发调用呢?答案是肯定的,这就是使用泛化调用的原因。 - -## 原理 - -泛化调用本质上就是把复杂结构转化为通用结构,这里说的通用结构是指 map、string 等,网关是可以顺利解析并传递这些通用结构的。 - -![img](/imgs/docs3-v2/golang-sdk/concept/rpc/generic/1632207075184-25939db4-f384-452e-a0b8-e1deff7971de.png) - -目前,Dubbo-go v3 只支持 Map 泛化方式(default)。我们以 User 接口为例,其定义如下所示。 - -```go -// definition -type User struct { - ID string - Name string - Age int32 -} - -func (u *User) JavaClassName() string { - return "org.apache.dubbo.sample.User" -} -``` - -假定调用一个服务需要一个 user 作为入参,其定义如下所示。 - -```go -// an instance of the User -user := &User{ - ID: "1", - Name: "Zhangsan", - Age: 20, -} -``` - -那么在使用 Map 泛化方式下,user 会被自动转换为 Map 格式,如下所示。 - -```go -usermap := map[interface{}]interface{} { - "iD": "1", - "name": "zhangsan", - "age": 20, - "class": "org.apache.dubbo.sample.User", -} -``` - -需要注意的是: - -- Map 泛化方式会自动将首字母小写,即 ID 会被转换为 iD,如果需要对齐 Dubbo-Java 请考虑将 ID 改为 Id; -- 在 Map 中会自动插入 class 字段,用于标识原有接口类。 - -## 使用 - -泛化调用对 provider 端是透明的,即 provider 端不需要任何显式配置就可以正确处理泛化请求。 - -### 基于 Dubbo URL 泛化调用 - -基于 Filter 泛化调用对 consumer 是透明的,典型应用场景是网关。这种方式需要要求 Dubbo URL 中包含泛化调用标识,如下所示。 - -```plain -dubbo://127.0.0.1:20000/org.apache.dubbo.sample.UserProvider?generic=true&... -``` - -这个 Dubbo URL 表达的语意是: - -- RPC 协议为 dubbo; -- org.apache.dubbo.sample.UserProvider 接口位于 127.0.0.1:20000; -- 使用泛化调用(generic=true)。 - -Consumer 端的 Filter 会自动根据 Dubbo URL 携带的配置自动将普通调用转化为泛化调用,但是需要注意的是,在这种方式下响应结果是以泛化格式返回,不会自动转化为相应的对象。举个例子,在 map 泛化方式下,如果需要返回 User 类,那么 consumer 获得的相应是一个 User 类对应的 map。 - -### 手动泛化调用 - -手动泛化调用发起的请求不经过 filter,所以需要 consumer 端显式地发起泛化调用,典型应用场景是测试。在 [dubbo-go-samples](https://github.com/apache/dubbo-go-samples/tree/f7febed9d686cb940ea55d34b5baa567d7574a44/generic) 中,为了便于测试都是采用手动调用的方式。 - -泛化调用不需要创建配置文件(dubbogo.yaml),但是需要在代码中手动配置注册中心、reference 等信息,初始化方法被封装到 newRefConf 方法中,如下所示。 - -```go -func newRefConf(appName, iface, protocol string) config.ReferenceConfig { - registryConfig := &config.RegistryConfig{ - Protocol: "zookeeper", - Address: "127.0.0.1:2181", - } - - refConf := config.ReferenceConfig{ - InterfaceName: iface, - Cluster: "failover", - Registry: []string{"zk"}, - Protocol: protocol, - Generic: "true", - } - - rootConfig := config.NewRootConfig(config.WithRootRegistryConfig("zk", registryConfig)) - _ = rootConfig.Init() - _ = refConf.Init(rootConfig) - refConf.GenericLoad(appName) - - return refConf -} -``` - -newRefConf 方法接收三个参数,分别是: - -- appName: 应用名; -- iface: 服务接口名; -- protocol: RPC 协议,目前只支持 dubbo 和 tri(triple 协议)。 - -在上述方法中,为了保持函数简单性,把注册中心设置为一个固定值,即使用在 127.0.0.1:2181 的 ZooKeeper 作为注册中心,在实践中可以根据实际情况自由定制。 - -我们可以很容易的获取一个 ReferenceConfig 实例,暂时命名为 refConf。 - -```go -refConf := newRefConf("example.dubbo.io", "org.apache.dubbo.sample.UserProvider", "tri") -``` - -接着我们可以对 org.apache.dubbo.sample.UserProvider 服务的 GetUser 方法发起泛化调用。 - -```go -resp, err := refConf. - GetRPCService().(*generic.GenericService). - Invoke( - context.TODO(), - "GetUser", - []string{"java.lang.String"}, - []hessian.Object{"A003"}, - ) -``` - -GenericService 的 Invoke 方法接收四个参数,分别是: - -- context; -- 方法名: 在这个例子中表示调用 GetUser 方法; -- 参数类型: GetUser 方法接收一个 string 类型的参数,如果目标方法接收多个参数,可以写为 `[]string{"type1", "type2", ...}`,如果目前方法是无参的,则需要填入一个空数组 `[]string{}`; -- 实参: 写法同参数类型,如果是无参函数,依然要填入一个空数组 `[]hessian.Object{}` 占位。 - -注意:在目前版本中,无参调用会出现崩溃问题。 - -相关阅读:[【Dubbo-go 服务代理模型】](https://blog.csdn.net/weixin_39860915/article/details/122738548) diff --git a/content/zh-cn/overview/mannual/golang-sdk/preface/concept/multi_language.md b/content/zh-cn/overview/mannual/golang-sdk/preface/concept/multi_language.md deleted file mode 100644 index 39c91e3d6eab..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/preface/concept/multi_language.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/preface/concept/multi_language/ - - /zh-cn/docs3-v2/golang-sdk/preface/concept/multi_language/ -description: 多语言 RPC -keywords: 多语言 RPC -title: 多语言 RPC -type: docs ---- - - - - - - - -![img](/imgs/docs3-v2/golang-sdk/concept/rpc/multi_language/dubbogo-3.0-invocation.png) - -### 跨语言调用 - -随着微服务场景的大范围应用,多语言场景越来越普遍,开发人员更愿意使用更适合的语言,来实现一个复杂系统的不同模块。例如使用 C 来编写网关,使用 Go 来编写 K8S 资源 operator,使用 Java 来编写业务应用。语言与场景并不是绑定的,企业往往可以结合自身发展的技术栈、开发人员的专长,来选型合适的语言。 - -在多语言场景中,跨语言调用能力就显得十分重要。 - -跨语言能力本质上是 [【网络协议】](../protocol/) 提供的能力。如何方便地让用户使用需要的网络协议、针对合适的跨语言场景进行开发、享受 Dubbo 生态的服务治理能力,是 Dubbo-go 服务框架所关心的。 - -### 跨生态 - -Dubbo-go 服务框架提供了跨生态的能力,开发人员可以使用 Dubbo-go 以及其 [生态项目](../../../refer/ecology/) 建立 HTTP/前端服务、Dubbo/Spring 应用、gRPC 生态应用之间的联系。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/golang-sdk/preface/concept/protocol.md b/content/zh-cn/overview/mannual/golang-sdk/preface/concept/protocol.md deleted file mode 100644 index 475c52f95aeb..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/preface/concept/protocol.md +++ /dev/null @@ -1,117 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/preface/concept/protocol/ - - /zh-cn/docs3-v2/golang-sdk/preface/concept/protocol/ -description: 网络协议 -title: 网络协议 -type: docs ---- - - - - - - -## 1. RPC 服务框架与网络协议 - -网络协议在 RPC 场景十分重要,在微服务场景下,服务进程之间的通信依赖可以连通的网络,以及client与server 端保持一致的网络协议。网络协议是一个抽象的概念,站在 Dubbo-go 应用开发的角度,不妨把我们关注的协议分为三个维度来讨论。 - -### 1.1 打解包协议 - -Dubbo-go 服务框架内置的打解包协议都是基于 TCP/IP 协议栈的,在此基础之上,封装/引入了多种协议,例如 Triple(dubbo3)、Dubbo、gRPC。 - -这一类协议重点关注 TCP 报文的封装和拆解过程,保证点对点的可靠通信。 - -在 dubbo-go 生态中,支持多种网络往往指的这一类协议。 - - - -### 1.2 序列化协议 - -序列化协议负责将内存中的对象以特定格式序列化为二进制流。一些主流的序列化库有:具有较好可读性、应用广泛的 json 序列化方式;较高压缩效率,性能较好的 protobuf 序列化方式;适配与 Java 语言的 hessian2 序列化方式等。Dubbo-go 内置了这三种序列化方式 - -序列化协议是需要开发者在业务开发过程中关注的,序列化协议往往需要特定的对象标注: - -一个由 protoc-gen-go 生成的 protobuf 序列对象的例子: - -```protobuf -type HelloRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` -} -``` - -一个可与 java 服务互通的 hessian2 序列化对象 - -```go -type HelloRequest struct { - Name string `hessian:"name"` -} - -func (u *HelloRequest) JavaClassName() string { - return "org.apache.dubbo.sample.User" -} -``` - -序列化协议与打解包协议的关系 - -- 一种打解包协议可以适配于多种序列化协议支持:例如,您可以使用 dubbogo 的 triple 协议来传递 hessian序列化参数与 Dubbo-java 服务框架互通;传递 pb 序列化参数与原生 gRPC 服务互通;通过实现接口来自定义您的希望的序列化方式例如 json,从而传递具有较强可读性的参数。 - -### 1.3 接口协议 - -接口协议,是由业务开发人员开发并且维护的协议,用于描述服务接口的信息。例如接口名、方法、参数类型。 - -以 Triple/gRPC 为例,开发人员可以使用插件,从 proto 文件中定义的接口生成存根(.pb.go 文件),存根文件内包含接口所有信息,及接口协议。 - -在编写服务时,客户端和服务端同时引入相同的接口,即可保证客户端发起针对特定接口和方法的调用,能被服务端正确识别和响应。 - -一个由 proto 编写的接口描述文件: - -```protobuf -syntax = "proto3"; -package api; - -option go_package = "./;api"; - -// The greeting service definition. -service Greeter { - // Sends a greeting - rpc SayHello (HelloRequest) returns (User) {} - // Sends a greeting via stream - rpc SayHelloStream (stream HelloRequest) returns (stream User) {} -} - -// The request message containing the user's name. -message HelloRequest { - string name = 1; -} - -// The response message containing the greetings -message User { - string name = 1; - string id = 2; - int32 age = 3; -} -``` - -接口协议与序列化协议的关系 - -- 接口协议是抽象的概念,一种接口协议可以使用多种接口描述语言来编写,并且可以转化成多种序列化协议对象。 - -## 2. Dubbo-go 支持的网络协议 - -Dubbo-go 支持的网络协议和序列化方式如下: - -| 协议 | 协议名 (用于配置) | 序列化方式 | 默认序列化方式 | -| --------------- | ----------------- | :------------------------: | -------------- | -| Triple 【推荐】 | tri | pb/hessian2/msgpack/自定义 | pb | -| Dubbo | dubbo | hessian2 | hessian2 | -| gRPC | grpc | pb | pb | -| jsonRPC | jsonrpc | json | json | - - - -相关阅读:[【Dubbo-go 服务代理模型】](https://developer.aliyun.com/article/878252) \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/golang-sdk/preface/concept/registry.md b/content/zh-cn/overview/mannual/golang-sdk/preface/concept/registry.md deleted file mode 100644 index 7946c68db198..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/preface/concept/registry.md +++ /dev/null @@ -1,95 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/preface/concept/registry/ - - /zh-cn/docs3-v2/golang-sdk/preface/concept/registry/ -description: 服务注册发现 -keywords: 服务注册发现 -title: 服务注册发现 -type: docs ---- - - - - - - -## 1. Dubbo 的注册中心 - -注册中心在 RPC 场景下负责保存服务端应用的信息。 - -服务端注册接口信息和到自身地址到注册中心,客户端从注册中心读取和订阅需要调用的地址列表。整个架构如图所示: - -![img](/imgs/architecture.png) - -关于 Dubbo 服务发现细节,详情可参考 [Dubbo 官网的概念介绍](/zh-cn/docs/concepts/service-discovery/) - -## 2. 服务发现概念 - -Dubbo 生态中,服务发现有以下主要概念: - -- 应用 Application - - 应用是一个 dubbo 服务进程,对应一个应用名。 - -- 接口(服务) - - 接口是一个 RPC 接口类,例如一个通过 proto 定义的 Service,再例如一个 Java Interface 类。一个 dubbo 进程可以包含多个服务/接口。 - -- 方法 - - 方法在接口中定义,一个接口可以包含多个方法。 - -- 参数列表 - - 参数列表在方法中定义。由于 Java 支持重载,一个方法可以包含多个参数列表。对于 Go 是一对一的关系。 - -- 注册信息 - - 在“接口级服务发现”的场景下,注册信息主要包含应用名、接口列表、元数据信息、以及服务端的IP地址等。以 URL 的形式保存在注册中心,供客户端发起调用前查询。 - - 在“应用级服务发现”的场景下,注册信息只包含应用名、应用名到接口的映射等少量应用级别的信息,接口级别的信息作为元数据保存在元数据中心。 - -- 元数据 - - 元数据指接口信息,例如接口名、包含的方法、方法对应的参数、序列化方式、协议等等信息。 - -- 注册中心 - - 注册中心用于保存服务端的信息。 - -- 元数据中心 - - 元数据中心用于保存服务端的元数据信息,在“应用级服务发现”场景中,作为“服务自省”阶段的依赖。 - -Dubbo-go 中的服务网格能力,引入以下几个概念 - -- 主机名 - - 主机名当前应用在 k8s 上注册的 Service 名。其他应用可以通过主机名访问本应用实例。 - -- 端点 - - 端点包含实例的 IP 地址、端口。 - -- 集群 - - 集群 ID 保存了从{主机名、集群子集名、端口} - - 集群保存集群 ID 到所有其包含端点的映射关系。 - -- 服务网格元数据 - - 服务网格元数据是接口名到主机名到映射,用于客户端查询所需接口的主机名信息。 - -## 3. Dubbo-go 注册中心 - -Dubbo-go 支持的注册中心类型如下: - -| 注册中心 | 注册中心名(用于配置) | -| --------- | ---------------------- | -| Zookeeper | zookeeper | -| Nacos | nacos | -| Etcd | etcd | -| Consul | consul | - -相关阅读:[【应用级服务发现解析】](https://developer.aliyun.com/article/764173) diff --git a/content/zh-cn/overview/mannual/golang-sdk/preface/design/_index.md b/content/zh-cn/overview/mannual/golang-sdk/preface/design/_index.md deleted file mode 100644 index aa0c9edcc9fd..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/preface/design/_index.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/preface/design/ - - /zh-cn/docs3-v2/golang-sdk/preface/design/ -description: Dubbo-go 框架代码架构 -linkTitle: 代码架构 -title: 代码架构 -type: docs -weight: 4 ---- diff --git a/content/zh-cn/overview/mannual/golang-sdk/preface/design/architecture.md b/content/zh-cn/overview/mannual/golang-sdk/preface/design/architecture.md deleted file mode 100644 index b10ae48fdcd3..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/preface/design/architecture.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/preface/design/architecture/ - - /zh-cn/docs3-v2/golang-sdk/preface/design/architecture/ -description: 架构 -keywords: 架构 -title: 架构 -type: docs ---- - - - - - - -### 架构说明 - -![architecture](/imgs/docs3-v2/golang-sdk/concept/more/architecture/architecture.png) - -### 节点说明 - -* `Registry` : dubbo-go中负责服务注册与发现的注册中心 -* `Consumer` : 调用远程服务的服务消费方 -* `Provider` : 暴露服务的服务提供方 - -### 过程说明 -* `0. register` : 当服务提供方在启动的时候,会自动将自己的服务注册到注册中心 -* `1. subscribe` : 服务消费方会在启动的时候,向注册中心订阅自己所需要的服务 -* `2. notify` : 注册中心返回服务注册的信息给到服务消费方,当订阅的服务发生变更,会推送变更的数据给到消费方 -* `3. invoke` : 服务消费者根据从注册中心获得的服务地址,经过负载均衡算法选出一个合适的服务地址发起请求 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/golang-sdk/preface/samples.md b/content/zh-cn/overview/mannual/golang-sdk/preface/samples.md deleted file mode 100644 index 9f0151e10b7a..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/preface/samples.md +++ /dev/null @@ -1,184 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/preface/samples/ - - /zh-cn/docs3-v2/golang-sdk/preface/samples/ -description: Dubbo-go 示例使用方式 -linkTitle: 快速入门 -title: 快速入门 -type: docs -weight: 5 ---- - - - - - - - -为了方便 Dubbo-go 框架用户的使用,我们提供了 Samples 仓库以供用户参考: - -[【Dubbo-go-samples 仓库地址】](https://github.com/apache/dubbo-go-samples) - -## 1. Samples 仓库包含的例子 - -* config-api: 使用 API 进行配置初始化 -* configcenter: 使用不同的配置中心,目前支持三种:zookeeper、apollo、和 nacos -* context: 如何使用上下文传递 attachment -* direct: 直连模式 -* game: 游戏服务例子 -* generic: 泛化调用 -* rpc: RPC 调用例子, 包含 Triple、Dubbo等协议以及跨语言/gRPC互通示例 -* helloworld: RPC调用入门例子 -* logger: 日志例子 -* registry: 展示与不同注册中心的对接,包含了 zk、nacos、etcd -* metrics: 数据上报 -* filter: 使用提供filter和自定义filter的例子 -* registry/servicediscovery:应用级服务发现例子 -* router: 路由例子 -* tracing: 链路追踪例子 - -## 2. 如何运行 - -目前有三种方式来运行 dubbo-go 的示例: - -1. 通过 bash 命令快速开始: 通过简单的命令行启动样例以及进行单元测试 -2. 在 IDE 中快速开始,这也是**推荐**的方式: 在工程 ".run" 子目录下,提供了所有示例的 GoLand 运行配置文件,因此用户可以简单在 IDE 中单击运行所有的示例。 -3. 在 IDE 中手工配置并运行: 为了完整性的目的,也为了万一您不使用 GoLand 而使用其他的 IDE,这里也提供了如何一步一步的配置的指南,帮助用户理解如何在 IDE 中配置,运行或者调试 dubbo-go 的示例。 - -### 2.1 通过 命令行 快速开始 - -*前置条件:需要 docker 环境就绪* - -下面我们将使用 "helloworld" 作为示例: - -1. **启动注册中心(比如 zookeeper)** - - ```bash - make -f build/Makefile docker-up - ``` - - 当看到类似下面的输出信息时,就表明 zookeeper server 启动就绪了。 - - ```bash - > Starting dependency services with ./integrate_test/dockercompose/docker-compose.yml - Docker Compose is now in the Docker CLI, try `docker compose up` - - Creating network "dockercompose_default" with the default driver - Creating dockercompose_zookeeper_1 ... done - Creating etcd ... done - Creating nacos-standalone ... done - ``` - - 如果要停掉注册中心,可以通过运行以下的命令完成: - - ```bash - make -f build/Makefile docker-down - ``` - -2. **启动服务提供方** - - ```bash - cd helloworld/go-server/cmd - export DUBBO_GO_CONFIG_PATH="../conf/dubbogo.yml" - go run . - ``` - - 当看到类似下面的输出信息时,就表明服务提供方启动就绪了。 - - ```bash - 2021/10/27 00:33:10 Connected to 127.0.0.1:2181 - 2021/10/27 00:33:10 Authenticated: id=72057926938066944, timeout=10000 - 2021/10/27 00:33:10 Re-submitting `0` credentials after reconnect - ``` - -3. **运行服务调用方** - - ```bash - cd helloworld/go-client/cmd - export DUBBO_GO_CONFIG_PATH="../conf/dubbogo.yml" - go run . - ``` - - 当以下的信息输出时,说明 `go-client` 调用 `go-server` 成功。 - - ```bash - 2021-10-27T00:40:44.879+0800 DEBUG triple/dubbo3_client.go:106 TripleClient.Invoke: get reply = name:"Hello laurence" id:"12345" age:21 - 2021-10-27T00:40:44.879+0800 DEBUG proxy/proxy.go:218 [makeDubboCallProxy] result: name:"Hello laurence" id:"12345" age:21 , err: - 2021-10-27T00:40:44.879+0800 INFO cmd/client.go:51 client response result: name:"Hello laurence" id:"12345" age:21 - ``` - -4. **集成测试** - 本项目 dubbo-go-samples 除了用来展示如何使用 dubbo-go 中的功能和特性之外,还被用于 apache/dubbo-go 的集成测试。可以按照以下的步骤来运行针对 `go-server` 设计的集成测试: - - 首先启动服务方 - ```bash - cd helloworld/go-server/cmd - export DUBBO_GO_CONFIG_PATH="../conf/dubbogo.yml" - go run . - ``` - - 然后切换到单测目录, 设置环境变量,然后执行单测 - ```bash - cd integrate_test/helloworld/tests/integration - export DUBBO_GO_CONFIG_PATH="../../../../helloworld/go-client/conf/dubbogo.yml" - go test -v - ``` - - 当以下信息输出时,说明集成测试通过。 - - ```bash - > Running integration test for application go-server - ... - --- PASS: TestSayHello (0.01s) - PASS - ok github.com/apache/dubbo-go-samples/integrate_test/helloworld/tests/integration 0.119s - ``` - -7. **关闭并清理** - ```bash - make -f build/Makefile clean docker-down - ``` - -*以下的两种运行方式都与 IDE 有关。这里我们以 Intellij GoLand 为例来讨论。* - -### 2.2 在 IDE 中快速开始 - -一旦在 GoLand 中打开本项目,可以发现,在 "Run Configuration" 弹出菜单中已经存在了一系列事先配置好了的用来运行相关服务提供方和调用方的选项,例如:"helloworld-go-server" 和 "helloworld-go-client"。 - -可以选择其中的任意一个快速启动相关示例。当然在运行之前,假设需要的注册中心已经事先启动了,不然用例将会失败。您可以选择手动自行启动的方式,也可以利用工程中提供的 "docker-compose.yml" 在启动注册中心的 docker 实例。 - -### 2.3.在 IDE 中手工运行 - -这里以 *Intellij GoLand* 为例。在 GoLand 中打开 dubbo-go-samples 工程之后,按照以下的步骤来运行/调试本示例: - -1. **启动 zookeeper 服务器** - - 打开 "integrate_test/dockercompose/docker-compose.yml" 这个文件,然后点击位于编辑器左边 gutter 栏位中的 ▶︎▶︎ 图标运行,"Service" Tab 应当会弹出并输出类似下面的文本信息: - ``` - Deploying 'Compose: docker'... - /usr/local/bin/docker-compose -f ...integrate_test/dockercompose/docker-compose.yml up -d - Creating network "docker_default" with the default driver - Creating docker_zookeeper_1 ... - 'Compose: docker' has been deployed successfully. - ``` - -2. **启动服务提供方** - - 打开 "helloworld/go-server/cmd/server.go" 文件,然后点击左边 gutter 栏位中紧挨着 "main" 函数的 ▶︎ 图标,并从弹出的菜单中选择 "Modify Run Configuration...",并确保以下配置的准确: - * Working Directory: "helloworld/go-server" 目录的绝对路径,比如: */home/dubbo-go-samples/helloworld/go-server* - * Environment: DUBBO_GO_CONFIG_PATH="../conf/dubbogo.yml" - - 这样示例中的服务端就准备就绪,随时可以运行了。 - -3. **运行服务消费方** - - 打开 "helloworld/go-client/cmd/client.go" 这个文件,然后从左边 gutter 栏位中点击紧挨着 "main" 函数的 ▶︎ 图标,然后从弹出的菜单中选择 "Modify Run Configuration...",并确保以下配置的准确: - * Working Directory: "helloworld/go-client" 目录的绝对路径,比如: */home/dubbo-go-samples/helloworld/go-client* - * Environment: DUBBO_GO_CONFIG_PATH="../conf/dubbogo.yml" - - 然后就可以运行并调用远端的服务了,如果调用成功,将会有以下的输出: - ``` - [2021-02-03/16:19:30 main.main: client.go: 66] response result: &{A001 Alex Stocks 18 2020-02-04 16:19:30.422 +0800 CST} - ``` - -如果需要调试该示例或者 dubbo-go 框架,可以在 IDE 中从 "Run" 切换到 "Debug"。如果要结束的话,直接点击 ◼︎ 就好了。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/golang-sdk/quickstart/_index.md b/content/zh-cn/overview/mannual/golang-sdk/quickstart/_index.md old mode 100644 new mode 100755 index 502fb0eb9b06..7e5d6fad4738 --- a/content/zh-cn/overview/mannual/golang-sdk/quickstart/_index.md +++ b/content/zh-cn/overview/mannual/golang-sdk/quickstart/_index.md @@ -1,7 +1,9 @@ --- aliases: - - /zh/docs3-v2/golang-sdk/quickstart/ - - /zh-cn/docs3-v2/golang-sdk/quickstart/ + - /zh/docs3-v2/golang-sdk/quickstart/ + - /zh-cn/docs3-v2/golang-sdk/quickstart/ + - /zh/overview/quickstart/go/ + - /zh-cn/overview/quickstart/go/ description: Dubbo-go 快速开始 linkTitle: 快速开始 title: 快速开始 diff --git a/content/zh-cn/overview/mannual/golang-sdk/quickstart/install.md b/content/zh-cn/overview/mannual/golang-sdk/quickstart/install.md deleted file mode 100644 index aa9e2e3f64f5..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/quickstart/install.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/quickstart/install/ - - /zh-cn/docs3-v2/golang-sdk/quickstart/install/ -description: 安装 Dubbo-go 开发环境 -title: 安装 Dubbo-go 开发环境 -type: docs -weight: 1 ---- -### 1. 推荐 Go 版本 - -[Go](https://golang.google.cn/) >= `1.15` -> 建议使用最新 `1.19` - -安装成功后将 `$GOPATH/bin` 加入环境变量 - -### 2. 安装序列化工具 - -[protoc](https://github.com/protocolbuffers/protobuf/releases) - -### 3. 安装工具以及相关插件 - -执行以下指令安装 dubbogo-cli 至 `$GOPATH/bin` - -添加 Go 模块代理 -```bash -$ export GOPROXY="https://goproxy.cn" -``` -安装 dubbogo-cli 工具 -```bash -$ go install github.com/dubbogo/dubbogo-cli@latest -``` -执行 dubbogo-cli 命令 -```bash -$ dubbogo-cli -hello -``` - -安装依赖的工具插件 - -```bash -$ dubbogo-cli install all -``` - -确保上述安装的工具位于在系统环境变量内 - -```bash -$ protoc --version -libprotoc 3.14.0 -``` -```bash -$ protoc-gen-go --version -protoc-gen-go v1.26.0 -``` -```bash -$ protoc-gen-go-triple --version -protoc-gen-go-triple 1.0.8 -``` diff --git a/content/zh-cn/overview/mannual/golang-sdk/quickstart/microservices.md b/content/zh-cn/overview/mannual/golang-sdk/quickstart/microservices.md new file mode 100644 index 000000000000..8af303b021b5 --- /dev/null +++ b/content/zh-cn/overview/mannual/golang-sdk/quickstart/microservices.md @@ -0,0 +1,195 @@ +--- +aliases: + - /zh/docs3-v2/golang-sdk/quickstart/ + - /zh-cn/docs3-v2/golang-sdk/quickstart/ +description: Dubbo-go 快速开始 +linkTitle: 开发微服务应用 +title: 开发微服务 +type: docs +weight: 2 +--- + +本示例演示了使用 dubbo-go 开发微服务应用,为应用增加包括服务发现、负载均衡、流量管控等微服务核心能力。 + +## 前置条件 +本示例我们继续使用 Protobuf 开发微服务应用,请参考 [开发 rpc server 和 rpc client](../rpc) 了解如何安装 protoc、protoc-gen-go-triple 等必须插件。 + +## 快速运行示例 +### 下载示例源码 +我们在 apache/dubbo-go-samples 仓库维护了一系列 dubbo-go 使用示例,用来帮助用户快速学习 dubbo-go 使用方式。 + +你可以 下载示例zip包并解压,或者克隆仓库: + +```shell +$ git clone --depth 1 https://github.com/apache/dubbo-go-samples +``` + +切换到快速开始示例目录: + +```shell +$ cd dubbo-go-samples/registry/nacos +``` + +### 启动 Nacos + +由于示例应用中启用了服务发现能力且使用 Nacos 作为注册中心,在运行示例之前需要先启动注册中心。请参考 [Nacos 本地安装](/zh-cn/overview/reference/integrations/nacos/) 了解如何快速安装和启动 Nacos。 + +### 运行 server +在 `go-server/cmd` 示例目录: + +运行以下命令,启动 server: + +```shell +$ go run server.go +``` + +使用 `cURL` 验证 server 正常启动: + +```shell +$ curl \ + --header "Content-Type: application/json" \ + --data '{"name": "Dubbo"}' \ + http://localhost:50051/greet.v1.GreetService/Greet + +Greeting: Hello world +``` + +### 运行 client + +打开一个新的 terminal,运行以下命令,启动 client + +```shell +$ go run client.go + +Greeting: Hello world +``` + +以上就是一个完整的 dubbo-go 微服务应用工作流程。 + +## 源码讲解 +关于 `dubbo-go-samples/registry/nacos` 示例源码,包括服务定义、代码生成、server/client 启动等均与上一篇 [rpc server & rpc client]() 类似,请点击以上链接查看具体解读。 + +**开发微服务最大的不同点在于:应用中增加了关于注册中心的配置,如下所示(以 server.go 为例):** + +```go +func main() { + ins, err := dubbo.NewInstance( + dubbo.WithName("dubbo_registry_nacos_server"), + dubbo.WithRegistry( + registry.WithNacos(), + registry.WithAddress("127.0.0.1:8848"), + ), + dubbo.WithProtocol( + protocol.WithTriple(), + protocol.WithPort(20000), + ), + ) + + srv, _ := ins.NewServer() + + greet.RegisterGreetServiceHandler(srv, &GreetTripleServer{}) + + if err := srv.Serve(); err != nil { + logger.Error(err) + } +} +``` + +相比于开发 rpc 服务时我们直接声明 `server.NewServer(...)`,这里我们使用 `dubbo.newInstance(...)` 初始化了一些全局共享的微服务核心组件,包括应用名、注册中心、协议等: + +```go +ins, err := dubbo.NewInstance( + dubbo.WithName("dubbo_registry_nacos_server"), + dubbo.WithRegistry( + registry.WithNacos(), + registry.WithAddress("127.0.0.1:8848"), + ), + dubbo.WithProtocol( + protocol.WithTriple(), + protocol.WithPort(20000), + ), +) +``` + +然后,才是创建 `ins.NewServer()` 并为 server 实例注册服务 `greet.RegisterGreetServiceHandler(srv, &GreetTripleServer{})`,最后通过 `srv.Serve()` 启动进程。 + +{{% alert title="关于 dubbo.Insance 说明" color="info" %}} +* 在开发 dubbo 微服务应用时,我们推荐使用 `dubbo.Instance` 来设置一些全局性的服务治理能力,如注册中心、协议、应用名、tracing、配置中心等。 +* `ins.NewServer()` 可以创建多个,通常当你需要在多个端口 [发布多个协议]() 时才需要这么做。 +{{% /alert %}} + +如果你要为应用添加更多服务治理能力,请参考以下内容: + +## 更多内容 +{{< blocks/section color="white" height="auto">}} +
+
+
+
+
+

+ 服务发现与负载均衡 +

+

更多关于 Nacos、Zookeeper 等服务发现的使用方式,负载均衡策略配置等。

+
+
+
+
+
+
+

+ 流量管控 +

+

学习如何实现按比例流量分配、金丝雀发布、调整超时时间、流量灰度、服务降级等流量管控。

+
+
+
+
+
+
+

+ 监控服务状态 +

+

开启 Metrics 采集,通过 Prometheus、Grafana 可视化查看应用、服务、示例状态。

+
+
+
+
+
+
+

+ 全链路追踪 +

+

开启 OpenTelemetry 全链路追踪。

+
+
+
+
+
+
+

+ 网关 HTTP 接入 +

+

如何使用 Higress、Nginx 等网关产品,将前端 http 流量(北向流量)接入后端 dubbo-go 微服务集群。

+
+
+
+
+
+
+

+ 分布式事务 +

+

使用 Apache Seata 作为分布式事务解决方案,解决分布式数据一致性问题。

+
+
+
+
+
+
+{{< /blocks/section >}} + + + + diff --git a/content/zh-cn/overview/mannual/golang-sdk/quickstart/quickstart_triple.md b/content/zh-cn/overview/mannual/golang-sdk/quickstart/quickstart_triple.md deleted file mode 100644 index fc7b6ff71b0c..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/quickstart/quickstart_triple.md +++ /dev/null @@ -1,137 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/quickstart/quickstart_triple/ - - /zh-cn/docs3-v2/golang-sdk/quickstart/quickstart_triple/ -description: 完成一次 RPC 调用 -title: 完成一次 RPC 调用 -type: docs -weight: 2 ---- - -## 1. 生成 Demo 项目 - -使用安装好的 dubbogo-cli 工具,创建 demo 工程。 - -创建并切换目录 - -```bash -$ mkdir quickstart && cd quickstart -``` - -使用 dubbogo-cli 工具创建新项目 - -```bash -$ dubbogo-cli newDemo . -``` - -查看项目结构 - -```bash -$ tree . -. -├── api -│   ├── samples_api.pb.go -│   ├── samples_api.proto -│   └── samples_api_triple.pb.go -├── go-client -│   ├── cmd -│   │   └── client.go -│   └── conf -│   └── dubbogo.yaml -├── go-server -│   ├── cmd -│   │   └── server.go -│   └── conf -│   └── dubbogo.yaml -└── go.mod -``` -可看到生成的项目中包含一个 client 项目和一个 server 项目,以及相关的配置文件。 - -### 1.1 查看接口描述文件 sample_api.proto - -```protobuf -syntax = "proto3"; -package api; - -option go_package = "./;api"; - -// The greeting service definition. -service Greeter { - // Sends a greeting - rpc SayHello (HelloRequest) returns (User) {} - // Sends a greeting via stream - rpc SayHelloStream (stream HelloRequest) returns (stream User) {} -} - -// The request message containing the user's name. -message HelloRequest { - string name = 1; -} - -// The response message containing the greetings -message User { - string name = 1; - string id = 2; - int32 age = 3; -} -``` - -demo 项目中,默认生成了一个接口描述文件,接口服务名为 api.Greeter, 包含两个 RPC 方法,入参为 HelloRequest,返回值为 User,两个方法分别为普通 RPC 方法和 Streaming 类型 RPC 方法。 - -### 1.2 编译接口 (可选) - -使用安装好的编译工具编译 pb 接口。 - -```bash -$ cd api -$ protoc --go_out=. --go-triple_out=. ./samples_api.proto -``` - -参数意义:`--go_out=.` 使用上述安装的 `protoc-gen-go` 插件,生成文件到当前目录,`--go-triple_out=.` 使用上述安装的 `protoc-gen-go-triple` 插件,生成文件到当前目录。 - -执行该指令后,会生成两个文件,分别是 sample_api.pb (包含 proto 结构) 和 sample_api_triple.pb.go (包含 triple 协议接口)。 - -在 demo 工程中,预先生成好了这两个文件,修改 .proto 文件后重新执行命令生成,即可覆盖。 - -## 2. 开启一次 RPC 调用 - -项目根目录执行 - -```bash -$ go mod tidy -``` - -拉取到最新的框架依赖(其中 Go SDK 版本和 module 名以个人机器配置为准): - -```go -module helloworld - -go 1.21.1 - -require ( - dubbo.apache.org/dubbo-go/v3 v3.1.0 - github.com/dubbogo/gost v1.14.0 - github.com/dubbogo/grpc-go v1.42.10 - github.com/dubbogo/triple v1.2.2-rc3 - google.golang.org/protobuf v1.31.0 -) - -require ( - ... -) - -``` - -{{% alert title="输出结果" color="info" %}} -先后启动服务端和客户端: 开启两个终端,在 `go-server/cmd` 和 `go-client/cmd` 文件夹下分别执行 `go run .` , 可在客户端看到输出: - -```shell -client response result: name:"Hello laurence" id:"12345" age:21 -``` - -调用成功。 -{{% /alert %}} - -{{% alert title="更多" color="primary" %}} -细心的读者可以发现,以上例子编写的的服务端可以接受来自客户端的普通 RPC、流式 RPC 调用请求。目前只编写了普通调用的 Client,读者可以根据 samples 库中的例子来尝试编写流式客户端和服务端应用。 -{{% /alert %}} diff --git a/content/zh-cn/overview/mannual/golang-sdk/quickstart/quickstart_triple_with_customize.md b/content/zh-cn/overview/mannual/golang-sdk/quickstart/quickstart_triple_with_customize.md deleted file mode 100644 index 7550a192790e..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/quickstart/quickstart_triple_with_customize.md +++ /dev/null @@ -1,221 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/quickstart/quickstart_triple_with_customize/ - - /zh-cn/docs3-v2/golang-sdk/quickstart/quickstart_triple_with_customize/ -description: 完成一次 RPC 调用自己定义接口的版本 -title: 完成一次自己定义接口的版本 RPC 调用 -type: docs -weight: 3 ---- - -## 1. 实现概述 -我们本章来实现一个简单的小需求,实现一个分布式ID生成服务,通过该服务可以获取分布式ID -(假设的分布式ID,我们不探讨ID的生成方案和算法,这里直接使用uuid代替,只为演示自定义服务的创建) - -## 2. 服务端实现 -首先使用 dubbogo-cli 创建 IDC 服务 -```bash -dubbogo-cli newApp IDC && cd IDC -``` -查看项目结构 -```bash -tree . - -. -├── Makefile -├── api -│   ├── api.pb.go -│   ├── api.proto -│   └── api_triple.pb.go -├── build -│   └── Dockerfile -├── chart -│   ├── app -│   │   ├── Chart.yaml -│   │   ├── templates -│   │   │   ├── _helpers.tpl -│   │   │   ├── deployment.yaml -│   │   │   ├── service.yaml -│   │   │   └── serviceaccount.yaml -│   │   └── values.yaml -│   └── nacos_env -│   ├── Chart.yaml -│   ├── templates -│   │   ├── _helpers.tpl -│   │   ├── deployment.yaml -│   │   └── service.yaml -│   └── values.yaml -├── cmd -│   └── app.go -├── conf -│   └── dubbogo.yaml -├── go.mod -├── go.sum -└── pkg - └── service - └── service.go - -``` - -我们编辑 proto 定义我们的接口 - -```protobuf -syntax = "proto3"; -package api; - -option go_package = "./;api"; - -service Generator { - rpc GetID (GenReq) returns (GenResp) {} -} - -message GenReq { - string appId = 1; -} - -message GenResp { - string id = 1; -} -``` - -生成代码 - -```bash -$ cd api && protoc --go_out=. --go-triple_out=. ./api.proto -``` - -我们来调整 `service` 目录:`pkg/service/service.go` -修改后的代码如下 - -```go -type GeneratorServerImpl struct { - api.UnimplementedGeneratorServer -} - -func (s *GeneratorServerImpl) GetID(ctx context.Context, in *api.GenReq) (*api.GenResp, error) { - logger.Infof("Dubbo-go GeneratorProvider AppId = %s\n", in.AppId) - uuid, err := uuid.NewV4() - if err != nil { - logger.Infof("Dubbo-go GeneratorProvider get id err = %v\n", err) - return nil, err - } - return &api.GenResp{Id: uuid.String()}, nil -} - -func init() { - config.SetProviderService(&GeneratorServerImpl{}) -} -``` -同时,我们调整 `conf/dubbogo.yaml` 中的 `provider` 部分, -```yaml -dubbo: - registries: - nacos: - protocol: nacos - address: 127.0.0.1:8848 - protocols: - triple: - name: tri - port: 20000 - provider: - services: - GeneratorServerImpl: - interface: "" # read from stub -``` -我们需要拉起一个依赖的注册中心 nacos,如果你有现成的,本步骤可以忽略,我们使用 docker 来快速启动一个 nacos - -```bash -git clone https://github.com/nacos-group/nacos-docker.git && cd nacos-docker -``` - -```bash -docker-compose -f example/standalone-derby.yaml up -``` - -最后,我们启动服务端。 -```go -export DUBBO_GO_CONFIG_PATH=conf/dubbogo.yaml -``` -``` -go run cmd/app.go -``` -打开 nacos 的控制台,可以看到服务已经注册 - -![img](/imgs/docs3-v2/golang-sdk/quickstart/nacos.jpg) - - -## 2. 客户端使用 -首先,我们可以共享我们的服务端的 api 给客户端,并生成相关的代码(这里可以根据实际项目需要,共享 proto,每个 consumer 自行生成代码,或统一生成 sdk 后给依赖的服务引入) -客户端目录如下: -```bash -. -├── api -│   ├── api.pb.go -│   ├── api.proto -│   └── api_triple.pb.go -├── cmd -│   └── client.go -├── conf -│   └── dubbogo.yml -├── go.mod -├── go.sum - -``` -`api` 目录同服务端的 `api` 目录 `client.go` 代码如下: -```go - -var grpcGeneratorImpl = new(api.GeneratorClientImpl) - -func main() { - config.SetConsumerService(grpcGeneratorImpl) - if err := config.Load(); err != nil { - panic(err) - } - - logger.Info("start to test dubbo") - req := &api.GenReq{ - AppId: "laurence", - } - reply, err := grpcGeneratorImpl.GetID(context.Background(), req) - if err != nil { - logger.Error(err) - } - logger.Infof("get id result: %v\n", reply.Id) -} - -``` - -`dubbogo.yml` -```yaml -dubbo: - registries: - nacos: - protocol: nacos - address: 127.0.0.1:8848 - consumer: - references: - GeneratorClientImpl: - protocol: tri - interface: "" -``` - -运行 client,获取 id: - -```bash -export DUBBO_GO_CONFIG_PATH=conf/dubbogo.yml -``` -``` -go run cmd/client.go -``` -{{% alert title="输出结果" color="info" %}} -```shell -…… -…… -2022-12-30T20:59:19.971+0800 INFO cmd/client.go:44 start to test dubbo -2022-12-30T20:59:19.982+0800 INFO cmd/client.go:52 get id result: aafd9c73-4014-4d67-a67f-5d107105647b -``` -{{% /alert %}} - -{{% alert title="更多" color="primary" %}} -可以发现注册中心我们是使用 nacos,当然,我们也可以使用其他的注册中心,更多的使用方式,可以参考 [注册中心](/zh-cn/overview/mannual/golang-sdk/tutorial/develop/registry/) -{{% /alert %}} diff --git a/content/zh-cn/overview/mannual/golang-sdk/quickstart/rpc.md b/content/zh-cn/overview/mannual/golang-sdk/quickstart/rpc.md new file mode 100644 index 000000000000..82d695fa4b09 --- /dev/null +++ b/content/zh-cn/overview/mannual/golang-sdk/quickstart/rpc.md @@ -0,0 +1,248 @@ +--- +aliases: + - /zh/docs3-v2/golang-sdk/quickstart/ + - /zh-cn/docs3-v2/golang-sdk/quickstart/ + - /zh-cn/overview/mannual/golang-sdk/quickstart/quickstart_triple/ +description: Dubbo-go 快速开始 +linkTitle: 开发RPC服务 +title: 开发 RPC Server & RPC Client +type: docs +weight: 1 +--- + +基于 Dubbo 定义的 Triple 协议,你可以轻松编写浏览器、gRPC 兼容的 RPC 服务,并让这些服务同时运行在 HTTP/1 和 HTTP/2 上。Dubbo Go SDK 支持使用 IDL 或编程语言特有的方式定义服务,并提供一套轻量的 API 来发布或调用这些服务。 + +本示例演示了基于 Triple 协议的 RPC 通信模式,示例使用 Protocol Buffer 定义 RPC 服务,并演示了代码生成、服务发布和服务访问等过程。 + +## 前置条件 + +因为使用 Protocol Buffer 的原因,我们首先需要安装相关的代码生成工具,这包括 `protoc`、`protoc-gen-go`、`protoc-gen-go-triple`。 + +1. 安装 `protoc` + + 查看 Protocol Buffer Compiler 安装指南 + +2. 安装 `protoc` 插件 + + 接下来,我们安装插件 `protoc-gen-go`、`protoc-gen-go-triple`。 + + ```shell + go install google.golang.org/protobuf/cmd/protoc-gen-go@latest + go install dubbo.apache.org/dubbo-go/v3/cmd/protoc-gen-go-triple@v3.0.1 + ``` + + 确保 `protoc-gen-go`、`protoc-gen-go-triple` 在你的 `PATH` 中。这可以通过 `which protoc-gen-go` 验证,如果该命令不能正常工作的话,请执行以下命令: + + ```shell + [ -n "$(go env GOBIN)" ] && export PATH="$(go env GOBIN):${PATH}" + [ -n "$(go env GOPATH)" ] && export PATH="$(go env GOPATH)/bin:${PATH}" + ``` + +## 快速运行示例 +### 下载示例源码 +我们在 apache/dubbo-go-samples 仓库维护了一系列 dubbo-go 使用示例,用来帮助用户快速学习 dubbo-go 使用方式。 + +你可以 下载示例zip包并解压,或者克隆仓库: + +```shell +$ git clone --depth 1 https://github.com/apache/dubbo-go-samples +``` + +切换到快速开始示例目录: + +```shell +$ cd dubbo-go-samples/helloworld +``` + +### 运行 server +在 `go-server/cmd` 目录: + +运行以下命令,启动 server: + +```shell +$ go run server.go +``` + +使用 `cURL` 验证 server 已经正常启动: + +```shell +$ curl \ + --header "Content-Type: application/json" \ + --data '{"name": "Dubbo"}' \ + http://localhost:20000/greet.GreetService/Greet + +Greeting: Hello world +``` + +### 运行 client + +打开一个新的 terminal,运行以下命令,在 `go-client/cmd` 目录运行以下命令,启动 client + +```shell +$ go run client.go + +Greeting: Hello world +``` + +以上就是一个完整的 dubbo-go RPC 通信服务开发过程。 + +## 源码讲解 +接下来,我们将对 `dubbo-go-samples/helloworld` 示例进行源码层面的讲解。 + +### 定义服务 +示例使用 Protocol Buffer (IDL) 来定义 Dubbo 服务。 + +```protobuf +syntax = "proto3"; + +package greet; +option go_package = "github.com/apache/dubbo-go-samples/helloworld/proto;greet"; + +message GreetRequest { + string name = 1; +} + +message GreetResponse { + string greeting = 1; +} + +service GreetService { + rpc Greet(GreetRequest) returns (GreetResponse) {} +} +``` + +这个文件声明了一个叫做 `GreetService` 的服务,为这个服务定义了 Greet 方法以及它的请求参数 GreetRequest 和返回值 GreetResponse。 + +### 生成代码 + +在运行 server 或者 client 之前,我们需要使用 `protoc-gen-go`、`protoc-gen-go-triple` 生成相关的代码 + +```bash +protoc --go_out=. --go_opt=paths=source_relative \ + --go-triple_out=. --go-triple_opt=paths=source_relative \ + ./greet.proto +``` + +运行以上命令后,在目标目录中看到以下生成的文件: + +``` + proto + ├── greet.pb.go + ├── greet.proto + └── greet.triple.go +``` + +在 proto/greet/v1 包下有两部分内容: + +- `greet.pb.go` 是由谷歌标准的 `protoc-gen-go`生成,它包含 `GreetRequest`、`GreetResponse` 结构体和响应的编解码规则。 +- `greet.triple.go` 是由 Dubbo 自定义的插件`protoc-gen-go-triple`成,其中关键的信息包括生成的接口 `GreetService`、构造器等。 + +### 实现服务 + +接下来我们就需要添加业务逻辑了,实现 `greet.GreetService` 接口即可。 + +```go +type GreetTripleServer struct { +} + +func (srv *GreetTripleServer) Greet(ctx context.Context, req *greet.GreetRequest) (*greet.GreetResponse, error) { + resp := &greet.GreetResponse{Greeting: req.Name} + return resp, nil +} +``` + +### 启动 Server + +创建一个新的 Server,把我们上一步中实现的 `GreeterServer`注册给它,接下来就可以直接初始化和启动 Server 了,它将在指定的端口接收请求。 + +```go +func main() { + srv, err := server.NewServer( + server.WithServerProtocol( + protocol.WithPort(20000), + protocol.WithTriple(), + ), + ) + if err != nil { + panic(err) + } + + if err := greet.RegisterGreetServiceHandler(srv, &GreetTripleServer{}); err != nil { + panic(err) + } + + if err := srv.Serve(); err != nil { + logger.Error(err) + } +} +``` + +### 访问服务 + +最简单方式是使用 HTTP/1.1 POST 请求访问服务,参数则作以标准 JSON 格式作为 HTTP 负载传递。如下是使用 cURL 命令的访问示例: +```shell +curl \ + --header "Content-Type: application/json" \ + --data '{"name": "Dubbo"}' \ + http://localhost:20000/greet.GreetService/Greet +``` + +也可以使用 Dubbo client 请求服务,我们首先需要从生成代码即 `greet` 包中获取服务代理,为它指定 server 地址并初始化,之后就可以发起 RPC 调用了。 + +```go +func main() { + cli, err := client.NewClient( + client.WithClientURL("127.0.0.1:20000"), + ) + if err != nil { + panic(err) + } + + svc, err := greet.NewGreetService(cli) + if err != nil { + panic(err) + } + + resp, err := svc.Greet(context.Background(), &greet.GreetRequest{Name: "hello world"}) + if err != nil { + logger.Error(err) + } + logger.Infof("Greet response: %s", resp.Greeting) +} +``` + +以上即是 dubbo-go rpc 的基本工作原理! + +## 更多内容 +{{< blocks/section color="white" height="auto">}} +
+
+
+
+
+

+ RPC 框架更多特性 +

+

学习 Streaming 通信模型、配置超时时间、传递headers等更多框架配置。

+
+
+
+
+
+
+

+ 服务发现等治理能力 +

+

学习如何使用 dubbo-go 开发微服务,引入服务发现、可观测性、流量管控等服务治理能力。

+
+
+
+
+
+
+{{< /blocks/section >}} + + + + diff --git a/content/zh-cn/overview/mannual/golang-sdk/refer/_index.md b/content/zh-cn/overview/mannual/golang-sdk/refer/_index.md index 705c664f7e4c..c881a44468f8 100644 --- a/content/zh-cn/overview/mannual/golang-sdk/refer/_index.md +++ b/content/zh-cn/overview/mannual/golang-sdk/refer/_index.md @@ -2,7 +2,9 @@ aliases: - /zh/docs3-v2/golang-sdk/refer/ - /zh-cn/docs3-v2/golang-sdk/refer/ -description: Dubbo-go 参考手册 + - /zh-cn/overview/mannual/golang-sdk/tutorial/develop/config-center/ + - /zh-cn/overview/mannual/golang-sdk/tutorial/develop/features/ +description: Dubbo-go 更多参考资料 title: 参考手册 type: docs weight: 5 diff --git a/content/zh-cn/overview/mannual/golang-sdk/refer/basic_concept.md b/content/zh-cn/overview/mannual/golang-sdk/refer/basic_concept.md deleted file mode 100644 index a9bf33eae24a..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/refer/basic_concept.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/refer/basic_concept/ - - /zh-cn/docs3-v2/golang-sdk/refer/basic_concept/ -description: 配置基本概念 -keywords: 配置基本概念 -title: 配置基本概念 -type: docs ---- - - - - - - -## 1. 框架配置 - -Dubbo-go 框架需要依赖配置进行启动。配置中包含了开发者希望使用框架的各种能力。 - -### 配置格式 - -yaml - -### 配置路径 - -默认从 `../conf/dubbogo.yaml ` 加载框架配置 - -可通过指定环境变量:DUBBO_GO_CONFIG_PATH=$(your_config_path)/dubbogo.yaml 来修改配置文件路径。 - -### 配置根结构 - -位于 [dubbo.apache.org/dubbo-go/v3/config/root_config.go: RootConfig](https://github.com/apache/dubbo-go/blob/e00cf8d6fb2be3cd9c6e42cc3d6efa54e10229d3/config/root_config.go#L50) - -框架加载时,任何形式的配置都会被解析成 RootConfig,在 RootConfig.Init 方法中加载。 - -## 2. 配置API - -开发者可以使用 API 的形式构建配置,从而启动框架。该方法较适合 dubbo-go 作为第三方组件引入的情况。 - -## 3. 配置中心 - -开发者可以将配置放置在配置中心,从而便于配置的管理和修改。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/golang-sdk/refer/compatible_version.md b/content/zh-cn/overview/mannual/golang-sdk/refer/compatible_version.md deleted file mode 100644 index 2330954a4339..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/refer/compatible_version.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/refer/compatible_version/ - - /zh-cn/docs3-v2/golang-sdk/refer/compatible_version/ -description: 依赖适配版本号 -title: 版本号 -type: docs -weight: 4 ---- - - - - - - -Dubbo-go 发布新版本时更新当前依赖的的版本。 - -| 依赖 | Dubbo-go | Triple | protoc-gen-go-triple | -| :--: | ------------ | ------ | -------------------- | -| | v3.0.1 | v1.1.8 | v1.0.8 | -| | v3.0.0 | v1.1.6 | v1.0.5 | -| | v3.0.0-rc4-1 | v1.1.3 | v1.0.2 | -| | v3.0.0-rc3 | v1.0.9 | v1.0.0 | diff --git a/content/zh-cn/overview/mannual/golang-sdk/refer/config.md b/content/zh-cn/overview/mannual/golang-sdk/refer/config.md deleted file mode 100644 index 507c4bd3d29b..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/refer/config.md +++ /dev/null @@ -1,130 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/refer/config/ - - /zh-cn/docs3-v2/golang-sdk/refer/config/ -description: Dubbo-go 配置项 -title: 配置项参考指南 -type: docs -weight: 1 ---- - - - - - - -## 根配置 - -## 客户端配置 - -## 服务端配置 - -## 注册中心配置 - -### 使用配置 API - -- 客户端使用配置 API 设置注册中心 - -可通过调用config.NewRegistryConfigWithProtocolDefaultPort方法,快速设置用于调试的注册中心,支持zookeeper(127.0.0.1:2181) 和nacos(127.0.0.1:8848) - -```go -rc := config.NewRootConfigBuilder(). - SetConsumer(config.NewConsumerConfigBuilder(). - SetRegistryIDs("zookeeperID"). // use defined registryID - Build()). - AddRegistry("zookeeperID", config.NewRegistryConfigWithProtocolDefaultPort("zookeeper")). - Build() -``` - -全部接口:可通过调用RegistryConfigBuilder提供的丰富接口进行配置。 - -```go -rc := config.NewRootConfigBuilder(). - SetConsumer(config.NewConsumerConfigBuilder(). - SetRegistryIDs("nacosRegistryID"). // use defined registryID - AddReference("GreeterClientImpl",/*...*/). - Build() - AddRegistry("nacosRegistryID", config.NewRegistryConfigBuilder(). - SetProtocol("nacos"). - SetAddress("127.0.0.1:8848"). - SetGroup("dubbo-go"). - SetNamespace("dubbo"). - SetUsername("admin"). - SetPassword("admin"). - SetTimeout("3s"). - Build()). - Build() -``` - -- 服务端使用配置 API 设置配置中心 - -简易接口 config.NewRegistryConfigWithProtocolDefaultPort - -```go -rc := config.NewRootConfigBuilder(). - SetProvider(config.NewProviderConfigBuilder(). - AddService("GreeterProvider", /*...*/). - SetRegistryIDs("registryKey"). // use defined registryID - Build()). - AddRegistry("registryKey", config.NewRegistryConfigWithProtocolDefaultPort("zookeeper")). - Build() -``` - -全部接口:可通过调用RegistryConfigBuilder提供的丰富接口进行配置。 - -```go -rc := config.NewRootConfigBuilder(). - SetProvider(config.NewProviderConfigBuilder(). - AddService("GreeterProvider",/*...*/) - SetRegistryIDs("registryKey"). // use defined registryID - Build()). - AddRegistry("registryKey", config.NewRegistryConfigBuilder(). - SetProtocol("nacos"). - SetAddress("127.0.0.1:8848"). - SetGroup("dubbo-go"). - SetNamespace("dubbo"). - SetUsername("admin"). - SetPassword("admin"). - SetTimeout("3s"). - Build()). - Build() -``` - -### - -## 网络协议 - -### 配置文件 - -### 使用配置 API - -- 客户端使用配置 API 设置网络协议 - -```go -rc := config.NewRootConfigBuilder(). - SetConsumer(config.NewConsumerConfigBuilder(). - AddReference("GreeterClientImpl", config.NewReferenceConfigBuilder(). - SetInterface("org.apache.dubbo.UserProvider"). - SetProtocol("tri"). // set reference protcol to triple - Build()). - Build()). - Build() -``` - -- 服务端使用配置 API 设置网络协议 - -```go -rc := config.NewRootConfigBuilder(). - SetProvider(config.NewProviderConfigBuilder(). - AddService("GreeterProvider", config.NewServiceConfigBuilder(). - SetInterface("org.apache.dubbo.UserProvider"). - SetProtocolIDs("tripleProtocolKey"). // use protocolID 'tripleProtocolKey' - Build()). - Build()). - AddProtocol("tripleProtocolKey", config.NewProtocolConfigBuilder(). // define protocol config with protocolID 'tripleProtocolKey' - SetName("tri"). // set service protocol to triple - Build()). - Build() -``` - -### diff --git a/content/zh-cn/overview/mannual/golang-sdk/refer/ecology.md b/content/zh-cn/overview/mannual/golang-sdk/refer/ecology.md index aa510b45bdbd..eeaa2d13b06a 100644 --- a/content/zh-cn/overview/mannual/golang-sdk/refer/ecology.md +++ b/content/zh-cn/overview/mannual/golang-sdk/refer/ecology.md @@ -5,19 +5,35 @@ aliases: description: Dubbo-go 生态组件 title: 生态组件 type: docs -weight: 3 +weight: 1 --- - - - - - -### Dubbo-go / Dubbo-go 3.0 +### Dubbo-go [github.com/apache/dubbo-go](https://github.com/apache/dubbo-go) - Apache Dubbo Go 语言实现,架起 Java 和 Golang 之间的桥梁。 +Apache Dubbo Go 语言实现主仓库 + +### Dubbo-go-samples + +[github.com/apache/dubbo-go-samples](https://github.com/apache/dubbo-go-samples) + +dubbo-go 的使用示例: +* config-api: 使用 API 进行配置初始化 +* configcenter: 使用不同的配置中心,目前支持三种:zookeeper、apollo、和 nacos +* context: 如何使用上下文传递 attachment +* direct: 直连模式 +* game: 游戏服务例子 +* generic: 泛化调用 +* rpc: RPC 调用例子, 包含 Triple、Dubbo等协议以及跨语言/gRPC互通示例 +* helloworld: RPC调用入门例子 +* logger: 日志例子 +* registry: 展示与不同注册中心的对接,包含了 zk、nacos、etcd +* metrics: 数据上报 +* filter: 使用提供filter和自定义filter的例子 +* registry/servicediscovery:应用级服务发现例子 +* router: 路由例子 +* tracing: 链路追踪例子 ### Dubbo-go-pixiu @@ -41,15 +57,8 @@ Dubbo-go-hessian2 是一个Go语言 hessian2 序列化协议库 [github.com/dubbogo/tools](https://github.com/dubbogo/tools) -Dubbogo-tools 包括 - -- dubbo-cli 工具 +包括 +- dubbo-cli 工具(废弃) - imports-formatter Go语言 imports 块格式化工具 - protoc-gen-triple PB编译插件 -- protoc-gen-dubbo3grpc PB编译插件 - -### Triple-go - -[github.com/dubbogo/triple](https://github.com/dubbogo/triple) - -Triple-go 为 Go 语言实现的 Triple (Dubbo3) 网络协议库,基于 HTTP2 协议。 +- protoc-gen-dubbo3grpc PB编译插件 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/golang-sdk/refer/generic.md b/content/zh-cn/overview/mannual/golang-sdk/refer/generic.md new file mode 100644 index 000000000000..7a1217db900b --- /dev/null +++ b/content/zh-cn/overview/mannual/golang-sdk/refer/generic.md @@ -0,0 +1,162 @@ +--- +aliases: + - /zh/docs3-v2/golang-sdk/preface/concept/generic/ + - /zh-cn/docs3-v2/golang-sdk/preface/concept/generic/ + - /zh-cn/overview/mannual/golang-sdk/preface/concept/generic/ +description: 泛化调用 +keywords: 泛化调用 +title: 泛化调用 +type: docs +weight: 2 +--- +{{% alert title="废弃警告" color="warning" %}} +dubbo-go 泛化调用仅适用于 dubbo2 协议,不适用 triple 协议 +{{% /alert %}} + +泛化调用是一种 Dubbo-Go 的特殊调用方式,它允许中间节点在没有接口信息的情况下传递调用信息,常被用于测试、网关的场景下。泛化调用支持 Dubbo 和 Triple 协议,但是目前序列化方案只支持 Hessian。 + +## 背景 + +为了便于理解,这篇文档中以网关使用场景介绍泛化调用。我们先来考虑普通调用(非泛化调用)。下图包含了 consumer 和 provider 两个关键角色(后文中用 endpoint 代表一个 consumer 或一个 provider),各自都有一份关于 org.apache.dubbo.sample.User 接口的定义。假定在调用行为中需要使用 org.apache.dubbo.sample.User 接口。 + +![img](/imgs/docs3-v2/golang-sdk/concept/rpc/generic/1631941941270-86ce9845-5a88-4cb5-8c8a-da8ae7eeb4d5.png) + +RPC 需要借助网络介质传输,因此数据不能以 go struct 形式传输,而必须以二进制形式传输。这就要求 consumer 端在传输前,需要将实现 org.apache.dubbo.sample.User 接口的结构体序列化为二进制格式。同样的,对于 provider 端,需要将二进制数据反序列化为结构体信息。**总之,普通调用要求接口信息在每一个 endpoint 必须有相同的定义,这样才能保证数据序列化和反序列化的结果与预期一致**。 + +在网关场景下,网关不可能存储全部接口定义。比如一个网关需要转发 100 个服务调用,每个服务需要的接口数量为 10 个,普通调用要求把 1000 个(100 * 10)接口定义提前全部存储在网关内,这显然是难以做到的。所以有没有一种方式可以既不需要提前存储接口定义,又能正确转发调用呢?答案是肯定的,这就是使用泛化调用的原因。 + +## 原理 + +泛化调用本质上就是把复杂结构转化为通用结构,这里说的通用结构是指 map、string 等,网关是可以顺利解析并传递这些通用结构的。 + +![img](/imgs/docs3-v2/golang-sdk/concept/rpc/generic/1632207075184-25939db4-f384-452e-a0b8-e1deff7971de.png) + +目前,Dubbo-go v3 只支持 Map 泛化方式(default)。我们以 User 接口为例,其定义如下所示。 + +```go +// definition +type User struct { + ID string + Name string + Age int32 +} + +func (u *User) JavaClassName() string { + return "org.apache.dubbo.sample.User" +} +``` + +假定调用一个服务需要一个 user 作为入参,其定义如下所示。 + +```go +// an instance of the User +user := &User{ + ID: "1", + Name: "Zhangsan", + Age: 20, +} +``` + +那么在使用 Map 泛化方式下,user 会被自动转换为 Map 格式,如下所示。 + +```go +usermap := map[interface{}]interface{} { + "iD": "1", + "name": "zhangsan", + "age": 20, + "class": "org.apache.dubbo.sample.User", +} +``` + +需要注意的是: + +- Map 泛化方式会自动将首字母小写,即 ID 会被转换为 iD,如果需要对齐 Dubbo-Java 请考虑将 ID 改为 Id; +- 在 Map 中会自动插入 class 字段,用于标识原有接口类。 + +## 使用 + +泛化调用对 provider 端是透明的,即 provider 端不需要任何显式配置就可以正确处理泛化请求。 + +### 基于 Dubbo URL 泛化调用 + +基于 Filter 泛化调用对 consumer 是透明的,典型应用场景是网关。这种方式需要要求 Dubbo URL 中包含泛化调用标识,如下所示。 + +```plain +dubbo://127.0.0.1:20000/org.apache.dubbo.sample.UserProvider?generic=true&... +``` + +这个 Dubbo URL 表达的语意是: + +- RPC 协议为 dubbo; +- org.apache.dubbo.sample.UserProvider 接口位于 127.0.0.1:20000; +- 使用泛化调用(generic=true)。 + +Consumer 端的 Filter 会自动根据 Dubbo URL 携带的配置自动将普通调用转化为泛化调用,但是需要注意的是,在这种方式下响应结果是以泛化格式返回,不会自动转化为相应的对象。举个例子,在 map 泛化方式下,如果需要返回 User 类,那么 consumer 获得的相应是一个 User 类对应的 map。 + +### 手动泛化调用 + +手动泛化调用发起的请求不经过 filter,所以需要 consumer 端显式地发起泛化调用,典型应用场景是测试。在 [dubbo-go-samples](https://github.com/apache/dubbo-go-samples/tree/f7febed9d686cb940ea55d34b5baa567d7574a44/generic) 中,为了便于测试都是采用手动调用的方式。 + +泛化调用不需要创建配置文件(dubbogo.yaml),但是需要在代码中手动配置注册中心、reference 等信息,初始化方法被封装到 newRefConf 方法中,如下所示。 + +```go +func newRefConf(appName, iface, protocol string) config.ReferenceConfig { + registryConfig := &config.RegistryConfig{ + Protocol: "zookeeper", + Address: "127.0.0.1:2181", + } + + refConf := config.ReferenceConfig{ + InterfaceName: iface, + Cluster: "failover", + Registry: []string{"zk"}, + Protocol: protocol, + Generic: "true", + } + + rootConfig := config.NewRootConfig(config.WithRootRegistryConfig("zk", registryConfig)) + _ = rootConfig.Init() + _ = refConf.Init(rootConfig) + refConf.GenericLoad(appName) + + return refConf +} +``` + +newRefConf 方法接收三个参数,分别是: + +- appName: 应用名; +- iface: 服务接口名; +- protocol: RPC 协议,目前只支持 dubbo 和 tri(triple 协议)。 + +在上述方法中,为了保持函数简单性,把注册中心设置为一个固定值,即使用在 127.0.0.1:2181 的 ZooKeeper 作为注册中心,在实践中可以根据实际情况自由定制。 + +我们可以很容易的获取一个 ReferenceConfig 实例,暂时命名为 refConf。 + +```go +refConf := newRefConf("example.dubbo.io", "org.apache.dubbo.sample.UserProvider", "tri") +``` + +接着我们可以对 org.apache.dubbo.sample.UserProvider 服务的 GetUser 方法发起泛化调用。 + +```go +resp, err := refConf. + GetRPCService().(*generic.GenericService). + Invoke( + context.TODO(), + "GetUser", + []string{"java.lang.String"}, + []hessian.Object{"A003"}, + ) +``` + +GenericService 的 Invoke 方法接收四个参数,分别是: + +- context; +- 方法名: 在这个例子中表示调用 GetUser 方法; +- 参数类型: GetUser 方法接收一个 string 类型的参数,如果目标方法接收多个参数,可以写为 `[]string{"type1", "type2", ...}`,如果目前方法是无参的,则需要填入一个空数组 `[]string{}`; +- 实参: 写法同参数类型,如果是无参函数,依然要填入一个空数组 `[]hessian.Object{}` 占位。 + +注意:在目前版本中,无参调用会出现崩溃问题。 + +相关阅读:[【Dubbo-go 服务代理模型】](https://blog.csdn.net/weixin_39860915/article/details/122738548) diff --git a/content/zh-cn/overview/mannual/golang-sdk/refer/nacos.md b/content/zh-cn/overview/mannual/golang-sdk/refer/nacos.md new file mode 100644 index 000000000000..c343fb0871a8 --- /dev/null +++ b/content/zh-cn/overview/mannual/golang-sdk/refer/nacos.md @@ -0,0 +1,147 @@ +--- +aliases: + - /zh/docs3-v2/golang-sdk/tutorial/develop/registry/nacos/ + - /zh-cn/docs3-v2/golang-sdk/tutorial/develop/registry/nacos/ +description: 使用 Nacos 作为注册中心 +title: 使用 Nacos 作为注册中心 +type: docs +weight: 10 +--- + + + +## 1. 准备工作 + +- dubbo-go cli 工具和依赖工具已安装 +- 创建一个新的 demo 应用 + +## 2. 使用 grpc_cli 工具进行 Dubbo 服务调试 + +### 2.1 开启服务端 +示例:user.go: +```go +func (u *UserProvider) GetUser(ctx context.Context, userStruct *CallUserStruct) (*User, error) { + fmt.Printf("=======================\nreq:%#v\n", userStruct) + rsp := User{"A002", "Alex Stocks", 18, userStruct.SubInfo} + fmt.Printf("=======================\nrsp:%#v\n", rsp) + return &rsp, nil +} + +``` +服务端开启一个服务,名为GetUser,传入一个CallUserStruct的参数,返回一个User参数\ +CallUserStruct参数定义: +```go +type CallUserStruct struct { + ID string + Male bool + SubInfo SubInfo // 嵌套子结构 +} +func (cs CallUserStruct) JavaClassName() string { + return "com.ikurento.user.CallUserStruct" +} + +type SubInfo struct { + SubID string + SubMale bool + SubAge int +} + +func (s SubInfo) JavaClassName() string { + return "com.ikurento.user.SubInfo" +} + +``` +User结构定义: +```go +type User struct { + Id string + Name string + Age int32 + SubInfo SubInfo // 嵌套上述子结构SubInfo +} + +func (u *User) JavaClassName() string { + return "com.ikurento.user.User" +} +``` + +开启服务: + +`cd server `\ +`source builddev.sh`\ +`go run .` + +### 2.2 定义请求体(打解包协议) + +请求体定义为json文件,约定键值均为string\ +键对应go语言struct字段名例如"ID"、"Name" ,值对应"type@val"\ +其中type支持string int bool time,val使用string 来初始化,如果只填写type则初始化为零值。 +约定每个struct必须有JavaClassName字段,务必与server端严格对应 + +见userCall.json: +```json +{ + "ID": "string@A000", + "Male": "bool@true", + "SubInfo": { + "SubID": "string@A001", + "SubMale": "bool@false", + "SubAge": "int@18", + "JavaClassName":"string@com.ikurento.user.SubInfo" + }, + "JavaClassName": "string@com.ikurento.user.CallUserStruct" +} +``` +userCall.json将参数CallUserStruct的结构及子结构SubInfo都定义了出来,并且给请求参数赋值。 + +user.json 同理,作为返回值不需要赋初始值,但JavaClassName字段一定与server端严格对应 +```go +{ + "ID": "string", + "Name": "string", + "Age": "int", + "JavaClassName": "string@com.ikurento.user.User", + "SubInfo": { + "SubID": "string", + "SubMale": "bool", + "SubAge": "int", + "JavaClassName":"string@com.ikurento.user.SubInfo" + } +} +``` + +### 2.3 执行请求 +`dubbogo-cli call --h=localhost --p 20001 --proto=dubbo --i=com.ikurento.user.UserProvider --method=GetUser --sendObj="./userCall.json" --recvObj="./user.json"` + +cli端打印结果: +```log +2020/10/26 20:47:45 Created pkg: +2020/10/26 20:47:45 &{ID:A000 Male:true SubInfo:0xc00006ea20 JavaClassName:com.ikurento.user.CallUserStruct} +2020/10/26 20:47:45 SubInfo: +2020/10/26 20:47:45 &{SubID:A001 SubMale:false SubAge:18 JavaClassName:com.ikurento.user.SubInfo} + + +2020/10/26 20:47:45 Created pkg: +2020/10/26 20:47:45 &{ID: Name: Age:0 JavaClassName:com.ikurento.user.User SubInfo:0xc00006ec90} +2020/10/26 20:47:45 SubInfo: +2020/10/26 20:47:45 &{SubID: SubMale:false SubAge:0 JavaClassName:com.ikurento.user.SubInfo} + + +2020/10/26 20:47:45 connected to localhost:20001! +2020/10/26 20:47:45 try calling interface:com.ikurento.user.UserProvider.GetUser +2020/10/26 20:47:45 with protocol:dubbo + +2020/10/26 20:47:45 After 3ms , Got Rsp: +2020/10/26 20:47:45 &{ID:A002 Name:Alex Stocks Age:18 JavaClassName: SubInfo:0xc0001241b0} +2020/10/26 20:47:45 SubInfo: +2020/10/26 20:47:45 &{SubID:A001 SubMale:false SubAge:18 JavaClassName:}``` +``` +可看到详细的请求体赋值情况,以及返回结果和耗时。支持嵌套结构 + +server端打印结果 +``` +======================= +req:&main.CallUserStruct{ID:"A000", Male:true, SubInfo:main.SubInfo{SubID:"A001", SubMale:false, SubAge:18}} +======================= +``` +可见接收到了来自cli的数据 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/golang-sdk/preface/3.0_feature.md b/content/zh-cn/overview/mannual/golang-sdk/refer/sourcecode/3.0_feature.md similarity index 97% rename from content/zh-cn/overview/mannual/golang-sdk/preface/3.0_feature.md rename to content/zh-cn/overview/mannual/golang-sdk/refer/sourcecode/3.0_feature.md index c95fd53c859e..1fde5e38933b 100644 --- a/content/zh-cn/overview/mannual/golang-sdk/preface/3.0_feature.md +++ b/content/zh-cn/overview/mannual/golang-sdk/refer/sourcecode/3.0_feature.md @@ -2,6 +2,7 @@ aliases: - /zh/docs3-v2/golang-sdk/preface/3.0_feature/ - /zh-cn/docs3-v2/golang-sdk/preface/3.0_feature/ + - /zh-cn/overview/mannual/golang-sdk/preface/3.0_feature/ description: Dubbo-go 3.0 新特性 keywords: 新特性 title: 新特性 diff --git a/content/zh-cn/overview/mannual/golang-sdk/refer/sourcecode/_index.md b/content/zh-cn/overview/mannual/golang-sdk/refer/sourcecode/_index.md new file mode 100644 index 000000000000..2e93b505de11 --- /dev/null +++ b/content/zh-cn/overview/mannual/golang-sdk/refer/sourcecode/_index.md @@ -0,0 +1,10 @@ +--- +aliases: + - /zh/docs3-v2/golang-sdk/sourcecode/ + - /zh-cn/docs3-v2/golang-sdk/sourcecode/ + - /zh-cn/overview/mannual/golang-sdk/sourcecode/ +description: Dubbo-go 源码解读 +title: 源码解读 +type: docs +weight: 4 +--- diff --git a/content/zh-cn/overview/mannual/golang-sdk/preface/design/aop_and_extension.md b/content/zh-cn/overview/mannual/golang-sdk/refer/sourcecode/aop_and_extension.md similarity index 98% rename from content/zh-cn/overview/mannual/golang-sdk/preface/design/aop_and_extension.md rename to content/zh-cn/overview/mannual/golang-sdk/refer/sourcecode/aop_and_extension.md index 936ad6b31565..d7bb5af3a3de 100644 --- a/content/zh-cn/overview/mannual/golang-sdk/preface/design/aop_and_extension.md +++ b/content/zh-cn/overview/mannual/golang-sdk/refer/sourcecode/aop_and_extension.md @@ -2,6 +2,7 @@ aliases: - /zh/docs3-v2/golang-sdk/preface/design/aop_and_extension/ - /zh-cn/docs3-v2/golang-sdk/preface/design/aop_and_extension/ + - /zh-cn/overview/mannual/golang-sdk/preface/design/aop_and_extension/ description: AOP 与可扩展机制 keywords: AOP 与可扩展机制 title: AOP 与可扩展机制 diff --git a/content/zh-cn/overview/mannual/golang-sdk/preface/design/app_and_interface.md b/content/zh-cn/overview/mannual/golang-sdk/refer/sourcecode/app_and_interface.md similarity index 97% rename from content/zh-cn/overview/mannual/golang-sdk/preface/design/app_and_interface.md rename to content/zh-cn/overview/mannual/golang-sdk/refer/sourcecode/app_and_interface.md index 0f4e2bed1541..80561c645b19 100644 --- a/content/zh-cn/overview/mannual/golang-sdk/preface/design/app_and_interface.md +++ b/content/zh-cn/overview/mannual/golang-sdk/refer/sourcecode/app_and_interface.md @@ -2,6 +2,7 @@ aliases: - /zh/docs3-v2/golang-sdk/preface/design/app_and_interface/ - /zh-cn/docs3-v2/golang-sdk/preface/design/app_and_interface/ + - /zh-cn/overview/mannual/golang-sdk/preface/design/app_and_interface/ description: Dubbo的应用和接口 keywords: 基本概念 title: Dubbo的应用和接口 diff --git a/content/zh-cn/overview/mannual/golang-sdk/refer/sourcecode/architecture.md b/content/zh-cn/overview/mannual/golang-sdk/refer/sourcecode/architecture.md new file mode 100644 index 000000000000..261badbc9213 --- /dev/null +++ b/content/zh-cn/overview/mannual/golang-sdk/refer/sourcecode/architecture.md @@ -0,0 +1,31 @@ +--- +aliases: + - /zh/docs3-v2/golang-sdk/preface/design/architecture/ + - /zh-cn/docs3-v2/golang-sdk/preface/design/architecture/ + - /zh-cn/overview/mannual/golang-sdk/preface/design/architecture/ +description: 架构 +keywords: 架构 +title: 架构 +type: docs +--- + + + + + + +### 架构说明 + +![architecture](/imgs/docs3-v2/golang-sdk/concept/more/architecture/architecture.png) + +### 节点说明 + +* `Registry` : dubbo-go中负责服务注册与发现的注册中心 +* `Consumer` : 调用远程服务的服务消费方 +* `Provider` : 暴露服务的服务提供方 + +### 过程说明 +* `0. register` : 当服务提供方在启动的时候,会自动将自己的服务注册到注册中心 +* `1. subscribe` : 服务消费方会在启动的时候,向注册中心订阅自己所需要的服务 +* `2. notify` : 注册中心返回服务注册的信息给到服务消费方,当订阅的服务发生变更,会推送变更的数据给到消费方 +* `3. invoke` : 服务消费者根据从注册中心获得的服务地址,经过负载均衡算法选出一个合适的服务地址发起请求 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/features/generic-2.md b/content/zh-cn/overview/mannual/golang-sdk/refer/sourcecode/generic-2.md similarity index 100% rename from content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/features/generic-2.md rename to content/zh-cn/overview/mannual/golang-sdk/refer/sourcecode/generic-2.md diff --git a/content/zh-cn/overview/mannual/golang-sdk/refer/sourcecode/generic.md b/content/zh-cn/overview/mannual/golang-sdk/refer/sourcecode/generic.md new file mode 100644 index 000000000000..0b73538e8d5c --- /dev/null +++ b/content/zh-cn/overview/mannual/golang-sdk/refer/sourcecode/generic.md @@ -0,0 +1,107 @@ +--- +aliases: + - /zh/docs3-v2/golang-sdk/tutorial/develop/features/generic/ + - /zh-cn/docs3-v2/golang-sdk/tutorial/develop/features/generic/ +description: 泛化调用 +title: 泛化调用 +type: docs +weight: 7 +--- + + + + + + +## 1. Dubbo-go 泛化调用 Java Server + +使用 Triple 协议 + hessian2 序列化方案 + +### 1.1 Java-Server启动 + +1. 传输结构定义 + +```java +package org.apache.dubbo; + +import java.io.Serializable; +import java.util.Date; + +public class User implements Serializable { + private String id; + + private String name; + + private int age; + + private Date time = new Date(); +} +``` + +2. 接口定义 + +```java +package org.apache.dubbo; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +//import org.apache.dubbo.rpc.filter.GenericFilter; + +public interface UserProvider { + User GetUser1(String userId); +} +``` + +### 1.2 Go-Client 泛化调用 + +此处展示以 API 的形式构造泛化接口引用 + +```go +// 初始化 Reference 配置 +refConf := config.NewReferenceConfigBuilder(). + SetInterface("org.apache.dubbo.UserProvider"). + SetRegistryIDs("zk"). + SetProtocol(tripleConst.TRIPLE). + SetGeneric(true). + SetSerialization("hessian2"). + Build() + +// 构造 Root 配置,引入注册中心模块 +rootConfig := config.NewRootConfigBuilder(). + AddRegistry("zk", config.NewRegistryConfigWithProtocolDefaultPort("zookeeper")). + Build() + +// Reference 配置初始化,因为需要使用注册中心进行服务发现,需要传入经过配置的 rootConfig +if err := refConf.Init(rootConfig); err != nil{ + panic(err) +} + +// 泛化调用加载、服务发现 +refConf.GenericLoad(appName) + +time.Sleep(time.Second) + +// 发起泛化调用 +resp, err := refConf.GetRPCService().(*generic.GenericService).Invoke( + context.TODO(), + "getUser1", + []string{"java.lang.String"}, + []hessian.Object{"A003"}, +) + +if err != nil { + panic(err) +} +logger.Infof("GetUser1(userId string) res: %+v", resp) +``` + +GenericService 的 Invoke 方法包括三个参数:context.Context, []string, []hessian.Object, + +其中第二个参数为对应参数的 Java 类名,例如java.lang.String、org.apache.dubbo.User,第三个参数为参数列表,hessian.Object 即为 interface。第二、第三个参数应与方法签名一致,按顺序对应。 + +获得map结构的返回结果 + +``` +INFO cmd/client.go:89 GetUser1(userId string) res: map[age:48 class:org.apache.dubbo.User id:A003 name:Joe sex:MAN time:2021-10-04 14:03:03.37 +0800 CST] +``` \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/golang-sdk/sourcecode/protocol.md b/content/zh-cn/overview/mannual/golang-sdk/refer/sourcecode/protocol.md similarity index 100% rename from content/zh-cn/overview/mannual/golang-sdk/sourcecode/protocol.md rename to content/zh-cn/overview/mannual/golang-sdk/refer/sourcecode/protocol.md diff --git a/content/zh-cn/overview/mannual/golang-sdk/sourcecode/registry.md b/content/zh-cn/overview/mannual/golang-sdk/refer/sourcecode/registry.md similarity index 100% rename from content/zh-cn/overview/mannual/golang-sdk/sourcecode/registry.md rename to content/zh-cn/overview/mannual/golang-sdk/refer/sourcecode/registry.md diff --git a/content/zh-cn/overview/mannual/golang-sdk/refer/use_dubbogo_cli.md b/content/zh-cn/overview/mannual/golang-sdk/refer/use_dubbogo_cli.md index 3fb3d713220c..1524b3def6a0 100644 --- a/content/zh-cn/overview/mannual/golang-sdk/refer/use_dubbogo_cli.md +++ b/content/zh-cn/overview/mannual/golang-sdk/refer/use_dubbogo_cli.md @@ -5,13 +5,11 @@ aliases: description: 使用 dubbogo-cli 工具 title: 使用 dubbogo-cli 工具 type: docs -weight: 2 +weight: 3 --- - - - - - +{{% alert title="废弃警告" color="warning" %}} +自 dubbo-go 3.1.0 版本开始,本工具不再适用。本工具已经停止维护,未来将由 dubboctl 代替,请关注社区动态了解 dubboctl 最新进展。 +{{% /alert %}} ## 1. 安装 diff --git a/content/zh-cn/overview/mannual/golang-sdk/sourcecode/_index.md b/content/zh-cn/overview/mannual/golang-sdk/sourcecode/_index.md deleted file mode 100644 index 677684425148..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/sourcecode/_index.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/sourcecode/ - - /zh-cn/docs3-v2/golang-sdk/sourcecode/ -description: Dubbo-go 源码解读 -title: 源码解读 -type: docs -weight: 4 ---- diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/_index.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/_index.md index 3f4118c54dab..6e598676b958 100755 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/_index.md +++ b/content/zh-cn/overview/mannual/golang-sdk/tutorial/_index.md @@ -2,6 +2,7 @@ aliases: - /zh/docs3-v2/golang-sdk/tutorial/ - /zh-cn/docs3-v2/golang-sdk/tutorial/ + - /zh-cn/overview/mannual/golang-sdk/preface/samples/ description: Dubbo-go 使用教程 linkTitle: 使用教程 title: 使用教程 diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/configuration/_index.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/configuration/_index.md new file mode 100755 index 000000000000..046fe925805a --- /dev/null +++ b/content/zh-cn/overview/mannual/golang-sdk/tutorial/configuration/_index.md @@ -0,0 +1,161 @@ +--- +aliases: + - /zh/docs3-v2/golang-sdk/tutorial/debugging/ + - /zh-cn/docs3-v2/golang-sdk/tutorial/debugging/ + - /zh-cn/overview/mannual/golang-sdk/refer/basic_concept/ + - /zh-cn/overview/mannual/golang-sdk/refer/config/ +description: "使用 dubbogo.yml 配置文件形式开发微服务应用。" +title: 配置文件 +type: docs +weight: 30 +--- + +## 1. 框架配置 + +Dubbo-go 框架需要依赖配置进行启动。配置中包含了开发者希望使用框架的各种能力。 + +### 配置格式 + +yaml + +### 配置路径 + +默认从 `../conf/dubbogo.yaml ` 加载框架配置 + +可通过指定环境变量:DUBBO_GO_CONFIG_PATH=$(your_config_path)/dubbogo.yaml 来修改配置文件路径。 + +### 配置根结构 + +位于 [dubbo.apache.org/dubbo-go/v3/config/root_config.go: RootConfig](https://github.com/apache/dubbo-go/blob/e00cf8d6fb2be3cd9c6e42cc3d6efa54e10229d3/config/root_config.go#L50) + +框架加载时,任何形式的配置都会被解析成 RootConfig,在 RootConfig.Init 方法中加载。 + +## 2. 配置API + +开发者可以使用 API 的形式构建配置,从而启动框架。该方法较适合 dubbo-go 作为第三方组件引入的情况。 + +## 3. 配置中心 + +开发者可以将配置放置在配置中心,从而便于配置的管理和修改。 + + + + + + + +## 根配置 + +## 客户端配置 + +## 服务端配置 + +## 注册中心配置 + +### 使用配置 API + +- 客户端使用配置 API 设置注册中心 + +可通过调用config.NewRegistryConfigWithProtocolDefaultPort方法,快速设置用于调试的注册中心,支持zookeeper(127.0.0.1:2181) 和nacos(127.0.0.1:8848) + +```go +rc := config.NewRootConfigBuilder(). + SetConsumer(config.NewConsumerConfigBuilder(). + SetRegistryIDs("zookeeperID"). // use defined registryID + Build()). + AddRegistry("zookeeperID", config.NewRegistryConfigWithProtocolDefaultPort("zookeeper")). + Build() +``` + +全部接口:可通过调用RegistryConfigBuilder提供的丰富接口进行配置。 + +```go +rc := config.NewRootConfigBuilder(). + SetConsumer(config.NewConsumerConfigBuilder(). + SetRegistryIDs("nacosRegistryID"). // use defined registryID + AddReference("GreeterClientImpl",/*...*/). + Build() + AddRegistry("nacosRegistryID", config.NewRegistryConfigBuilder(). + SetProtocol("nacos"). + SetAddress("127.0.0.1:8848"). + SetGroup("dubbo-go"). + SetNamespace("dubbo"). + SetUsername("admin"). + SetPassword("admin"). + SetTimeout("3s"). + Build()). + Build() +``` + +- 服务端使用配置 API 设置配置中心 + +简易接口 config.NewRegistryConfigWithProtocolDefaultPort + +```go +rc := config.NewRootConfigBuilder(). + SetProvider(config.NewProviderConfigBuilder(). + AddService("GreeterProvider", /*...*/). + SetRegistryIDs("registryKey"). // use defined registryID + Build()). + AddRegistry("registryKey", config.NewRegistryConfigWithProtocolDefaultPort("zookeeper")). + Build() +``` + +全部接口:可通过调用RegistryConfigBuilder提供的丰富接口进行配置。 + +```go +rc := config.NewRootConfigBuilder(). + SetProvider(config.NewProviderConfigBuilder(). + AddService("GreeterProvider",/*...*/) + SetRegistryIDs("registryKey"). // use defined registryID + Build()). + AddRegistry("registryKey", config.NewRegistryConfigBuilder(). + SetProtocol("nacos"). + SetAddress("127.0.0.1:8848"). + SetGroup("dubbo-go"). + SetNamespace("dubbo"). + SetUsername("admin"). + SetPassword("admin"). + SetTimeout("3s"). + Build()). + Build() +``` + +### + +## 网络协议 + +### 配置文件 + +### 使用配置 API + +- 客户端使用配置 API 设置网络协议 + +```go +rc := config.NewRootConfigBuilder(). + SetConsumer(config.NewConsumerConfigBuilder(). + AddReference("GreeterClientImpl", config.NewReferenceConfigBuilder(). + SetInterface("org.apache.dubbo.UserProvider"). + SetProtocol("tri"). // set reference protcol to triple + Build()). + Build()). + Build() +``` + +- 服务端使用配置 API 设置网络协议 + +```go +rc := config.NewRootConfigBuilder(). + SetProvider(config.NewProviderConfigBuilder(). + AddService("GreeterProvider", config.NewServiceConfigBuilder(). + SetInterface("org.apache.dubbo.UserProvider"). + SetProtocolIDs("tripleProtocolKey"). // use protocolID 'tripleProtocolKey' + Build()). + Build()). + AddProtocol("tripleProtocolKey", config.NewProtocolConfigBuilder(). // define protocol config with protocolID 'tripleProtocolKey' + SetName("tri"). // set service protocol to triple + Build()). + Build() +``` + +### diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/configuration/file.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/configuration/file.md new file mode 100644 index 000000000000..cbee4780d318 --- /dev/null +++ b/content/zh-cn/overview/mannual/golang-sdk/tutorial/configuration/file.md @@ -0,0 +1,280 @@ +--- +description: 使用 dubbogo.yml 配置文件开发应用 +title: 使用 dubbogo.yml 配置文件开发应用 +linkTitle: 本地配置文件 +type: docs +weight: 1 +--- + +## 1.介绍 + +本文档演示如何在框架中使用 `yaml` 配置文件进行微服务开发,是相比于 `API` 的另一种微服务开发模式。你可以完全使用 `yml` 配置文件进行开发,也可以将部分全局配置放到配置文件,而只在 API 中完成服务定义。 + +这种模式下,一定要通过 `DUBBO_GO_CONFIG_PATH` 指定配置文件路径: + +```shell +export DUBBO_GO_CONFIG_PATH="../conf/dubbogo.yml" +``` + +## 2. 使用说明 + +可在此查看 完整示例源码。 + +### 2.1 运行示例 +```txt +. +├── go-client +│   ├── cmd +│   │   └── main.go +│   └── conf +│   └── dubbogo.yml +├── go-server +│   ├── cmd +│   │   └── main.go +│   └── conf +│   └── dubbogo.yml +└─── proto +    ├── greet.pb.go +    ├── greet.proto +    └── greet.triple.go + +``` +通过 IDL`./proto/greet.proto` 定义服务 使用triple协议 + + +#### build Proto +```bash +cd path_to_dubbogo-sample/config_yaml/proto +protoc --go_out=. --go-triple_out=. ./greet.proto +``` +#### Server +```bash +export DUBBO_GO_CONFIG_PATH="../conf/dubbogo.yml" +cd path_to_dubbogo-sample/config_yaml/go-server/cmd +go run . +``` +#### Client +```bash +export DUBBO_GO_CONFIG_PATH="../conf/dubbogo.yml" +cd path_to_dubbogo-sample/config_yaml/go-client/cmd +go run . +``` + +### 2.2 客户端使用说明 + +客户端定义的 `yaml` 文件: + +```yaml +# dubbo client yaml configure file +dubbo: + registries: + demoZK: + protocol: zookeeper + timeout: 3s + address: 127.0.0.1:2181 + consumer: + references: + GreetServiceImpl: + protocol: tri + interface: com.apache.dubbo.sample.Greeter + registry: demoZK + retries: 3 + timeout: 3000 +``` +通过 `dubbo.Load()` 调用进行文件的读取以及加载 + +```go +//... +func main() { + //... + if err := dubbo.Load(); err != nil { + //... + } + //... +} +``` + +### 2.3 服务端使用说明 + +服务端定义的 `yaml` 文件 +```yaml +# dubbo server yaml configure file +dubbo: + registries: + demoZK: + protocol: zookeeper + timeout: 10s + address: 127.0.0.1:2181 + protocols: + tripleProtocol: + name: tri + port: 20000 + provider: + services: + GreetTripleServer: + interface: com.apache.dubbo.sample.Greeter +``` + +通过 `dubbo.Load()` 调用进行文件的读取以及加载 + +```go +//... +func main() { + //... + if err := dubbo.Load(); err != nil { + //... + } + //... +} + +``` +## 3.示例详解 + +### 3.1服务端介绍 + +#### 服务端proto文件 + +源文件路径:dubbo-go-sample/context/proto/greet.proto + +```protobuf +syntax = "proto3"; + +package greet; + +option go_package = "github.com/apache/dubbo-go-samples/config_yaml/proto;greet"; + +message GreetRequest { + string name = 1; +} + +message GreetResponse { + string greeting = 1; +} + +service GreetService { + rpc Greet(GreetRequest) returns (GreetResponse) {} +} +``` + +#### 服务端handler文件 + +在服务端中,定义 GreetTripleServer: + +```go +type GreetServiceHandler interface { + Greet(context.Context, *GreetRequest) (*GreetResponse, error) +} +``` + +实现 GreetServiceHandler 接口,通过 `greet.SetProviderService(&GreetTripleServer{})` 进行注册 +,同样使用 `dubbo.Load()` 进行加载配置文件 + + +源文件路径:dubbo-go-sample/config_yaml/go-server/cmd/main.go + +```go + +package main + +import ( + "context" + "errors" + "fmt" + + "dubbo.apache.org/dubbo-go/v3" + _ "dubbo.apache.org/dubbo-go/v3/imports" + greet "github.com/apache/dubbo-go-samples/config_yaml/proto" +) + +type GreetTripleServer struct { +} + +func (srv *GreetTripleServer) Greet(ctx context.Context, req *greet.GreetRequest) (*greet.GreetResponse, error) { + name := req.Name + if name != "ConfigTest" { + errInfo := fmt.Sprintf("name is not right: %s", name) + return nil, errors.New(errInfo) + } + + resp := &greet.GreetResponse{Greeting: req.Name + "-Success"} + return resp, nil +} + +func main() { + greet.SetProviderService(&GreetTripleServer{}) + if err := dubbo.Load(); err != nil { + panic(err) + } + select {} +} +``` + +### 3.2 客户端介绍 + +在客户端中,定义greet.GreetServiceImpl实例,greet.SetConsumerService(svc)进行注册: +通过 `dubbo.Load()` 进行配置文件的加载 + +源文件路径:dubbo-go-sample/config_yaml/go-client/cmd/main.go + +```go +package main + +import ( + "context" + "dubbo.apache.org/dubbo-go/v3" + _ "dubbo.apache.org/dubbo-go/v3/imports" + greet "github.com/apache/dubbo-go-samples/config_yaml/proto" + "github.com/dubbogo/gost/log/logger" +) + +var svc = new(greet.GreetServiceImpl) + +func main() { + greet.SetConsumerService(svc) + if err := dubbo.Load(); err != nil { + panic(err) + } + req, err := svc.Greet(context.Background(), &greet.GreetRequest{Name: "ConfigTest"}) + if err != nil || req.Greeting != "ConfigTest-Success" { + panic(err) + } + logger.Info("ConfigTest successfully") +} + +``` + +### 3.3 案例效果 + +先启动服务端,再启动客户端,可以观察到客户端打印了`ConfigTest successfully`配置加载以及调用成功 + +``` +2024-03-11 15:47:29 INFO cmd/main.go:39 ConfigTest successfully + +``` + +## 4 更多配置 + +### 指定 Filter + +如果要指定多个 filter 时,可用 ',' 分隔 + +- Consumer 端 + + ```yaml + dubbo: + consumer: + filter: echo,token,tps,myCustomFilter # 可指定自定义filter + ``` + + +- Provider 端 + + ```yaml + dubbo: + provider: + services: + GreeterProvider: + filter: myCustomFilter,echo,tps + ``` + + diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/configuration/remote.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/configuration/remote.md new file mode 100644 index 000000000000..c68340283afa --- /dev/null +++ b/content/zh-cn/overview/mannual/golang-sdk/tutorial/configuration/remote.md @@ -0,0 +1,80 @@ +--- +aliases: + - /zh/docs3-v2/golang-sdk/tutorial/develop/config-center/remote_config/ + - /zh-cn/docs3-v2/golang-sdk/tutorial/develop/config-center/remote_config/ +description: 远程加载 dubbogo.yaml 配置文件 +title: 远程配置文件 +type: docs +weight: 3 +--- + +Dubbo 框架支持将配置文件 'dubbogo.yaml' 的内容预先放入配置中心,再通过远程加载的方式与本地配置合并,以此实现一些配置的动态和集中式管理。 + +{{% alert title="注意" color="primary" %}} +凡是正确配置了config-center 地址的应用,都会优先从配置中心加载整个配置文件。 +{{% /alert %}} + +可在此查看 完整示例源码地址,本文使用 zookeeper 演示,nacos 使用方法类似,并且在以上地址中有具体源码示例。 + +### 启用配置中心 +在 dubbo-go 应用通过 `dubbo.WithConfigCenter()` 启用配置中心: + +```go +ins, err := dubbo.NewInstance( + dubbo.WithConfigCenter( + config_center.WithZookeeper(), + config_center.WithDataID("dubbo-go-samples-configcenter-zookeeper-server"), + config_center.WithAddress("127.0.0.1:2181"), + config_center.WithGroup("dubbogo"), + ), +) +if err != nil { + panic(err) +} +``` + +在运行应用之前,提前将以下配置写入 zookeeper 集群,写入路径为 `/dubbo/config/dubbogo/dubbo-go-samples-configcenter-zookeeper-server`: + +```yaml +dubbo: + registries: + demoZK: + protocol: zookeeper + timeout: 3s + address: '127.0.0.1:2181' + protocols: + triple: + name: tri + port: 20000 +``` + +### 启动服务端并注册服务 + +```go +srv, err := ins.NewServer() +if err != nil { + panic(err) +} + +if err := greet.RegisterGreetServiceHandler(srv, &GreetTripleServer{}); err != nil { + panic(err) +} + +if err := srv.Serve(); err != nil { + logger.Error(err) +} +``` + +可以发现,应用已经读取了远端的 dubbogo.yml 文件,并连接到文件中配置的注册中心地址、协议及端口配置。 + +### 启动客户端 + +```shell +$ go run ./go-client/cmd/main.go +``` + +### 预期的输出 + +``` +Greet response: greeting:"hello world" +``` diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/debugging/_index.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/debugging/_index.md deleted file mode 100755 index 482611e85695..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/debugging/_index.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/tutorial/debugging/ - - /zh-cn/docs3-v2/golang-sdk/tutorial/debugging/ -description: Dubbo-go 服务调试 -title: 服务调试 -type: docs -weight: 2 ---- diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/debugging/grpc_cli.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/debugging/grpc_cli.md deleted file mode 100644 index 35f43e00fc43..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/debugging/grpc_cli.md +++ /dev/null @@ -1,84 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/tutorial/debugging/grpc_cli/ - - /zh-cn/docs3-v2/golang-sdk/tutorial/debugging/grpc_cli/ -description: 使用 grpc_cli 调试 Dubbo-go 服务 -title: 使用 grpc_cli 调试 Dubbo-go 服务 -type: docs -weight: 1 ---- - - - - - - -grpc_cli 工具是 gRPC 生态用于调试服务的工具,在 server 开启[反射服务](https://github.com/grpc/grpc/blob/master/doc/server-reflection.md)的前提下,可以获取到服务的 proto 文件、服务名、方法名、参数列表,以及发起 gRPC 调用。 - -Triple 协议兼容 gRPC 生态,并默认开启 gRPC 反射服务,因此可以直接使用 grpc_cli 调试 triple 服务。 - -## 1. 准备工作 - -- dubbo-go cli 工具和依赖工具已安装 -- 创建一个新的 demo 应用 -- 安装grpc_cli,参考 [grpc_cli 文档](https://github.com/grpc/grpc/blob/master/doc/command_line_tool.md) - -## 2. 使用 grpc_cli 工具进行 Triple 服务调试 - -### 2.1 启动 demo 应用 server - -```bash -$ mkdir grpc_cli_test -$ cd grpc_cli_test -$ dubbogo-cli newDemo . -$ go mod tidy -$ cd go-server/cmd -$ go run . -``` - -### 2.2 使用 grpc_cli 进行服务调试 - -1. 查看 triple 服务的接口定义 - -```shell -$ grpc_cli ls localhost:20000 -l -filename: samples_api.proto -package: api; -service Greeter { - rpc SayHello(api.HelloRequest) returns (api.User) {} - rpc SayHelloStream(stream api.HelloRequest) returns (stream api.User) {} -} -``` - -2. 查看请求参数类型 - - 例如开发者期望测试上述端口的 SayHello 方法,尝试获取 HelloRequest 的具体定义,需要执行如下指令,可查看到对应参数的定义。 - -```shell -$ grpc_cli type localhost:20000 api.HelloRequest -message HelloRequest { - string name = 1 [json_name = "name"]; -} -``` - -3. 请求接口 - - 已经知道了请求参数的具体类型,可以发起调用来测试对应服务。查看返回值是否符合预期。 - -```shell -$ grpc_cli call localhost:20000 SayHello "name: 'laurence'" -connecting to localhost:20000 -name: "Hello laurence" -id: "12345" -age: 21 -Received trailing metadata from server: -accept-encoding : identity,gzip -grpc-accept-encoding : identity,deflate,gzip -Rpc succeeded with OK status -``` - -​ 可看到获得了正确的返回值。在 server 侧可以观察到被正确请求的日志: - -```shell -Dubbo3 GreeterProvider get user name = laurence -``` \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/deploy2/_index.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/deploy2/_index.md new file mode 100644 index 000000000000..dfcdc5c34e96 --- /dev/null +++ b/content/zh-cn/overview/mannual/golang-sdk/tutorial/deploy2/_index.md @@ -0,0 +1,10 @@ +--- +aliases: + - /zh/docs3-v2/golang-sdk/tutorial/governance/service-mesh/ + - /zh-cn/docs3-v2/golang-sdk/tutorial/governance/service-mesh/ +description: "学习在 Kubernetes、Service Mesh(Kubernetes Service)、虚拟机(Zookeeper、Nacos)等场景部署 dubbo-go 应用。" +title: 部署应用 +type: docs +weight: 100 +toc_hide: true +--- diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/deploy2/deploy.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/deploy2/deploy.md new file mode 100644 index 000000000000..2e61d43a2c79 --- /dev/null +++ b/content/zh-cn/overview/mannual/golang-sdk/tutorial/deploy2/deploy.md @@ -0,0 +1,430 @@ +--- +aliases: + - /zh/docs3-v2/golang-sdk/tutorial/governance/service-mesh/deploy/ + - /zh-cn/docs3-v2/golang-sdk/tutorial/governance/service-mesh/deploy/ +description: Istio 环境部署 Dubbo-go 应用 +title: Istio 环境部署 Dubbo-go 应用 +type: docs +weight: 2 +--- + +在本章节中,我们将使用应用模板快速创建一组 Dubbo-go Server和 Client 端应用,部署在 Istio 集群中;观察、调试和验证服务发现和调用成功。 + +## 1. 准备工作 + +- dubbo-go cli 工具和依赖工具已安装、grpc_cli (如需本地调试)。 +- docker、helm、kubectl 环境已安装。(arm 机器需支持 docker buildx) +- [任务【istio 环境部署】](../istio/) 已完成 + +## 2. 开发 server 端 Dubbo-go 应用 + +### 2.1 使用 dubbogo-cli 创建项目模板 + +```plain +$ mkdir mesh-app-server +$ cd mesh-app-server +$ dubbogo-cli newApp . +$ tree . +. +├── Makefile +├── api +│ └── api.proto +├── build +│ └── Dockerfile +├── chart +│ ├── app +│ │ ├── Chart.yaml +│ │ ├── templates +│ │ │ ├── _helpers.tpl +│ │ │ ├── deployment.yaml +│ │ │ ├── service.yaml +│ │ │ └── serviceaccount.yaml +│ │ └── values.yaml +│ └── nacos_env +│ ├── Chart.yaml +│ ├── templates +│ │ ├── _helpers.tpl +│ │ ├── deployment.yaml +│ │ └── service.yaml +│ └── values.yaml +├── cmd +│ └── app.go +├── conf +│ └── dubbogo.yaml +├── go.mod +├── go.sum +└── pkg + └── service + └── service.go +``` + +生成项目包括几个目录: + +- api:放置接口文件:proto文件和生成的pb.go文件 +- build:放置构建相关文件 +- chart:放置发布用 chart 仓库、基础环境chart 仓库:nacos、mesh(开发中) +- cmd:程序入口 +- conf:框架配置 +- pkg/service:RPC 服务实现 +- Makefile: + +- - 镜像、Helm 安装名称: + +- - ``` + IMAGE = $(your_repo)/$(namespace)/$(image_name) + TAG = 1.0.0 + HELM_INSTALL_NAME = dubbo-go-app + ``` + +- - 提供脚本,例如: + +- - - make build # 打包镜像并推送 + - make buildx-publish # arm架构本地打包amd64镜像并推送,依赖buildx + - make deploy # 通过 helm 发布应用 + - make remove # 删除已经发布的 helm 应用 + - make proto-gen # api下生成 pb.go 文件 + - ... + +### 2.2 开发和部署 Dubbo-go 应用: + +#### 开发应用 + +- 编译接口 + + 开发人员需要修改 proto 文件,本任务中直接使用默认接口即可。 + + ```bash + $ make proto-gen + protoc --go_out=./api --go-triple_out=./api ./api/api.proto + ``` + +- 拉取依赖 + + ```bash + $ go get dubbo.apache.org/dubbo-go/v3@3.0 + $ make tidy + go mod tidy + ``` + +- 编写业务逻辑 + + 修改 pkg/service/service.go 实现函数, 返回字符串中显示版本为 v1.0.0 + + ```go + func (s *GreeterServerImpl) SayHello(ctx context.Context, in *api.HelloRequest) (*api.User, error) { + return &api.User{Name: "Hello " + in.Name, Id: "v1.0.0"}, nil + } + ``` + +- 修改配置如下字段,从而使用xds协议作为注册中心 + + conf/dubbogo.yaml + + ```yaml + dubbo: + registries: + xds: + protocol: xds + address: istiod.istio-system.svc.cluster.local:15010 + protocols: + triple: + name: tri + port: 20000 + provider: + services: + GreeterServerImpl: + interface: "" # read from stub + + ``` + + 至此,应用开发完成。 + +#### 配置构建和部署参数 + +- 指定需要构建的镜像: + + 修改 Makefile 如下字段,指定好需要构建的镜像地址和版本。 + + 指定好需要通过 helm 安装的名称。 + + ``` + IMAGE = xxx/dubbo-go-server + TAG = 1.0.0 + HELM_INSTALL_NAME = dubbo-go-server-v1 + ``` + +- 指定需要部署的应用和镜像: + + 修改 chart/app/Chart.yaml 如下字段,指定当前应用名为 `dubbo-go-server`,部署时会创建一个名为 dubbo-go-server 的 service ,关联当前应用的所有版本。 + + ```yaml + apiVersion: v1 + name: dubbo-go-server + description: dubbo-go-server + ``` + + 修改 chart/app/values.yaml 如下字段,指定需要部署的镜像以及当前开发的应用版本 dubbogoAppVersion 为 v1。 + + 部署的镜像需要和上述构建的镜像一致。当前应用版本用于 mesh 流量规则控制。 + + ```yaml + image: + repository: xxx/dubbo-go-server + pullPolicy: Always + tag: "1.0.0" + + # Dubbo-go-mesh version control labels + version: + labels: + dubbogoAppVersion: v1 + ``` + + 至此,构建参数和发布参数都已指定好,可以进行构建和部署了。 + +#### 使用模板构建和部署 Dubbo-go 应用 + +- 构建、推送镜像 + + `$ make build ` (本地为 amd64机器) + + 或者 + + `$ make buildx-publish` (本地为 arm64机器,依赖 docker buildx 命令) + +- 发布 Dubbo-go 应用至集群 + + ```bash + $ make deploy + helm install dubbo-go-server-v1 ./chart/app + NAME: dubbo-go-server-v1 + LAST DEPLOYED: Thu Apr 7 11:19:42 2022 + NAMESPACE: default + STATUS: deployed + REVISION: 1 + TEST SUITE: None + $ helm list + NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION + dubbo-go-server-v1 default 1 2022-04-07 11:19:42.350553 +0800 CST deployed dubbo-go-server-0.0.1 1.16.0 + ``` + + 可看到通过 helm 部署成功 + + + +### 2.3 验证应用 + +#### 查看资源部署情况 + +查看部署好的 deployment ,版本为 v1。 + +```bash +$ kubectl get deployment +NAME READY UP-TO-DATE AVAILABLE AGE +dubbo-go-server-v1 1/1 1 1 26s +``` + +查看部署好的 service。 + +```bash +$ kubectl get svc +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +dubbo-go-server ClusterIP 192.168.216.253 20000/TCP 70s +``` + +#### (*可选)本地调试部署好的 Dubbo-go 应用 + +使用 kubectl port-forward Dubbo-go 应用到本地 + +```bash +$ kubectl port-forward svc/dubbo-go-server 20000 +Forwarding from 127.0.0.1:20000 -> 20000 +Forwarding from [::1]:20000 -> 20000 +``` + +使用 grpc_cli 调试集群内的应用,参考任务[【使用 grpc_cli 调试 Dubbo-go 应用】](/zh-cn/overview/mannual/golang-sdk/tutorial/debugging/grpc_cli/) + +```bash +$ grpc_cli ls localhost:20000 -l +filename: api/api.proto +package: api; +service Greeter { + rpc SayHello(api.HelloRequest) returns (api.User) {} + rpc SayHelloStream(stream api.HelloRequest) returns (stream api.User) {} +} +``` + +使用 grpc_cli 发起调用,测试接口 + +```bash +$ grpc_cli call localhost:20000 SayHello "name: 'laurence'" +connecting to localhost:20000 +name: "Hello laurence" +id: "v1.0.0" +Received trailing metadata from server: +accept-encoding : identity,gzip +grpc-accept-encoding : identity,deflate,gzip +Rpc succeeded with OK status +``` + +至此,我们成功开发了一个应用,把它部署在了 istio 集群内。 + +## 3. 开发 Client 端 Dubbo-go 应用 + +### 3.1 使用 dubbogo-cli 创建另一个项目模板 + +```bash +$ dubbogo-cli newApp . +``` + +### 3.2 开发和部署客户端 Dubbo-go 应用: + +#### 编写业务逻辑 + +- 修改 cmd/app.go 的 main 方法,针对下游接口每秒钟发起一次调用 + +```go +func main() { + client := &api.GreeterClientImpl{} + config.SetConsumerService(client) + if err := config.Load(); err != nil { + panic(err) + } + request := &api.HelloRequest{ + Name: "laurence", + } + + for{ + if rsp, err := client.SayHello(context.Background(), request); err != nil{ + logger.Errorf("call server error = %s", err) + }else{ + logger.Infof("call server response = %+v", rsp) + } + time.Sleep(time.Second) + } +} +``` + +- 修改如下配置文件,使用xds协议作为注册中心,加载名为 GreeterClientImpl 的客户端服务。 + + conf/dubbogo.yaml + + ```yaml + dubbo: + registries: + xds: + protocol: xds + address: istiod.istio-system.svc.cluster.local:15010 + consumer: + references: + GreeterClientImpl: + protocol: tri + interface: "" # read from stub + ``` + + 至此,应用开发完成。 + +#### 配置构建和部署参数 + +- 指定需要构建的镜像: + + 修改 Makefile 如下字段,指定好需要构建的镜像地址和版本。 + + 指定好需要通过 helm 安装的名称。 + + ``` + IMAGE = xxx/dubbo-go-client + TAG = 1.0.0 + HELM_INSTALL_NAME = dubbo-go-client + ``` + +- 指定需要部署的应用和镜像: + + 修改 chart/app/Chart.yaml 如下字段,指定当前应用名为 `dubbo-go-client`,部署时会创建一个名为 dubbo-go-client 的 service ,关联当前应用的所有版本。对于一个只有客户端的应用,可以不创建sevice,可以由开发者在模板中修改,本教程中我们默认创建。 + + ```yaml + apiVersion: v1 + name: dubbo-go-client + description: dubbo-go-client + ``` + + 修改 chart/app/values.yaml 如下字段,指定需要部署的镜像以及当前开发的应用版本 dubbogoAppVersion 为 v1。 + + 部署的镜像需要和上述构建的镜像一致。当前应用版本用于 mesh 流量规则控制。 + + ```yaml + image: + repository: xxx/dubbo-go-client + pullPolicy: Always + tag: "1.0.0" + + # Dubbo-go-mesh version control labels + version: + labels: + dubbogoAppVersion: v1 + ``` + + 至此,构建参数和发布参数都已指定好,可以进行构建和部署了。 + +#### 使用模板构建和部署 Dubbo-go 应用 + +- 构建、推送镜像 + + `$ make build ` (本地为 amd64机器) + + 或者 + + `$ make buildx-publish` (本地为 arm64机器,依赖 docker buildx 命令) + +- 发布 Dubbo-go Client 应用至集群 + + ```bash + $ make deploy + helm install dubbo-go-client ./chart/app + NAME: dubbo-go-client + LAST DEPLOYED: Thu Apr 7 11:49:55 2022 + NAMESPACE: default + STATUS: deployed + REVISION: 1 + TEST SUITE: None + $ helm list + NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION + dubbo-go-client default 1 2022-04-07 11:49:55.517898 +0800 CST deployed dubbo-go-client-0.0.1 1.16.0 + dubbo-go-server-v1 default 1 2022-04-07 11:23:18.397658 +0800 CST deployed dubbo-go-server-0.0.1 1.16.0 + ``` + + 可看到通过 helm 部署成功, 目前已经在集群中存在 Client 和 Server 两个应用。 + +### 3.3 验证应用 + +#### 查看资源部署情况 + +查看部署好的 client 和 server 两个 deployment。 + +```bash +$ kubectl get deployment +NAME READY UP-TO-DATE AVAILABLE AGE +dubbo-go-client-v1 1/1 1 1 22m +dubbo-go-server-v1 1/1 1 1 49m +``` + +查看客户端调用日志 + +```bash +$ kubectl get pods | grep client | awk '{print $1}' | xargs kubectl logs +... +2022-04-07T04:13:55.777Z INFO cmd/app.go:29 call server response = name:"Hello laurence" id:"v1.0.0" +2022-04-07T04:13:56.778Z INFO cmd/app.go:29 call server response = name:"Hello laurence" id:"v1.0.0" +2022-04-07T04:13:57.779Z INFO cmd/app.go:29 call server response = name:"Hello laurence" id:"v1.0.0" +2022-04-07T04:13:58.781Z INFO cmd/app.go:29 call server response = name:"Hello laurence" id:"v1.0.0" +2022-04-07T04:13:59.782Z INFO cmd/app.go:29 call server response = name:"Hello laurence" id:"v1.0.0" +2022-04-07T04:14:00.784Z INFO cmd/app.go:29 call server response = name:"Hello laurence" id:"v1.0.0" +2022-04-07T04:14:01.785Z INFO cmd/app.go:29 call server response = name:"Hello laurence" id:"v1.0.0" +``` + +验证调用成功 + +## 4. 小结 + +dubbogo-cli 提供的应用模板可以方便地支持开发者进行镜像的构建、推送、部署。 + +在 Istio 环境中,server 应用将自身服务信息注册在 Isito 上,由客户端监听 xds 资源,查询 istio debug 端口进行接口级别的服务发现。开发人员无需关心 service名、主机名、集群名等概念,只需要引入接口,发起调用即可。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/traffic/graceful_shutdown.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/deploy2/graceful_shutdown.md similarity index 98% rename from content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/traffic/graceful_shutdown.md rename to content/zh-cn/overview/mannual/golang-sdk/tutorial/deploy2/graceful_shutdown.md index fd36daebda89..40fca749bbf2 100644 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/traffic/graceful_shutdown.md +++ b/content/zh-cn/overview/mannual/golang-sdk/tutorial/deploy2/graceful_shutdown.md @@ -8,10 +8,6 @@ title: 优雅下线 type: docs --- - - - - # 优雅下线 ## 背景 @@ -61,8 +57,8 @@ dubbo: ```go extension.AddCustomShutdownCallback(func() { - // 用户自定义操作 - }) + // 用户自定义操作 +}) ``` ## 参考资料 diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/service-mesh/istio.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/deploy2/istio.md similarity index 100% rename from content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/service-mesh/istio.md rename to content/zh-cn/overview/mannual/golang-sdk/tutorial/deploy2/istio.md diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/service-mesh/proxyless_service_mesh.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/deploy2/proxyless_service_mesh.md similarity index 100% rename from content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/service-mesh/proxyless_service_mesh.md rename to content/zh-cn/overview/mannual/golang-sdk/tutorial/deploy2/proxyless_service_mesh.md diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/service-mesh/traffic_management.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/deploy2/traffic_management.md similarity index 100% rename from content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/service-mesh/traffic_management.md rename to content/zh-cn/overview/mannual/golang-sdk/tutorial/deploy2/traffic_management.md diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/deployment/_index.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/deployment/_index.md deleted file mode 100755 index 413a279fe6fa..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/deployment/_index.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/tutorial/deployment/ - - /zh-cn/docs3-v2/golang-sdk/tutorial/deployment/ -description: Dubbo-go 部署服务 -title: 部署服务 -type: docs -weight: 3 ---- diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/deployment/docker/_index.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/deployment/docker/_index.md deleted file mode 100644 index 3568b3c33592..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/deployment/docker/_index.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/tutorial/deployment/docker/ - - /zh-cn/docs3-v2/golang-sdk/tutorial/deployment/docker/ -description: Docker 镜像打包教程 -title: Docker 镜像打包教程 -type: docs -weight: 2 ---- diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/deployment/kubernetes/_index.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/deployment/kubernetes/_index.md deleted file mode 100644 index 8f06950b396b..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/deployment/kubernetes/_index.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/tutorial/deployment/kubernetes/ - - /zh-cn/docs3-v2/golang-sdk/tutorial/deployment/kubernetes/ -description: Kubernetes 部署教程 -title: Kubernetes 部署教程 -type: docs -weight: 3 ---- diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/deployment/practice/_index.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/deployment/practice/_index.md deleted file mode 100644 index 5336df575577..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/deployment/practice/_index.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/tutorial/deployment/practice/ - - /zh-cn/docs3-v2/golang-sdk/tutorial/deployment/practice/ -description: 生产部署的最佳实践介绍 -title: 生产部署的最佳实践介绍 -type: docs -weight: 1 ---- diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/_index.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/_index.md deleted file mode 100755 index 6e822450b432..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/_index.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/tutorial/develop/ - - /zh-cn/docs3-v2/golang-sdk/tutorial/develop/ -description: Dubbo-go 开发服务 -title: 开发服务 -type: docs -weight: 1 ---- diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/config-center/_index.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/config-center/_index.md deleted file mode 100644 index cc2fc27663f8..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/config-center/_index.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/tutorial/develop/config-center/ - - /zh-cn/docs3-v2/golang-sdk/tutorial/develop/config-center/ -description: 配置中心 -title: 配置中心 -type: docs -weight: 5 ---- diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/config-center/config-center-dynamic.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/config-center/config-center-dynamic.md deleted file mode 100644 index c9dbe669eec4..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/config-center/config-center-dynamic.md +++ /dev/null @@ -1,156 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/tutorial/develop/config-center/config-center-dynamic/ - - /zh-cn/docs3-v2/golang-sdk/tutorial/develop/config-center/config-center-dynamic/ -description: Dubbogo 3.0 配置中心和配置监听 -title: Dubbogo 3.0 配置中心和配置监听 -type: docs -weight: 2 ---- - - - - - - -## 1. 配置中心概念 - -配置中心即为在分布式场景下,无法将最新的框架配置文件和应用程序绑定在一起,可以指定好配置中心的信息,例如配置中心类型和地址,并在框架启动时从配置中心拉取相应配置进行启动。 - -## 2. 配置中心的配置 - -参考仓库:[dubbo-go-samples/configcenter](https://github.com/apache/dubbo-go-samples/tree/f7febed9d686cb940ea55d34b5baa567d7574a44/configcenter) - -dubbogo.yml - -```yaml -dubbo: - config-center: - protocol: nacos - address: 127.0.0.1:8848 - data-id: dubbo-go-samples-configcenter-nacos-server - namespace: myNamespaceID # 可选配置 nacos namespace ID, 默认是 public - group: mygroup # 可选配置 nacos group, 默认是 DEFAULT_GROUP -``` - -配置中心 nacos 内 - -group 默认为 `dubbo` - -dataID 为指定的id:`dubbo-go-samples-configcenter-nacos-server` - -写入框架配置例如下面,即可正常启动。 - -```yaml -dubbo: - registries: - demoZK: - protocol: zookeeper - timeout: 3s - address: 127.0.0.1:2181 - protocols: - triple: - name: tri - port: 20000 - provider: - services: - GreeterProvider: - interface: com.apache.dubbo.sample.basic.IGreeter -``` - - - -## 3. Dubbogo 动态配置 API - -Config API 为 dubbogo 3.0 用来操作配置结构的 API。可使用框架提供的 Config API 进行配置结构的初始化,获取组件实例并使用。一个例子如下,包含了动态配置实例的初始化、发布配置、读取配置、订阅配置操作。 - -```go -const configCenterNacosServerConfig = `# set in config center, group is 'dubbo', dataid is 'dubbo-go-samples-configcenter-nacos-server', namespace is default 'public' -dubbo: - registries: - demoZK: - protocol: zookeeper - address: 127.0.0.1:2181 - protocols: - triple: - name: tri - port: 20000 - provider: - services: - GreeterProvider: - interface: com.apache.dubbo.sample.basic.IGreeter # must be compatible with grpc or dubbo-java` - -type GreeterProvider struct { - api.GreeterProviderBase -} - -func (s *GreeterProvider) SayHello(ctx context.Context, in *api.HelloRequest) (*api.User, error) { - logger.Infof("Dubbo3 GreeterProvider get user name = %s\n", in.Name) - return &api.User{Name: "Hello " + in.Name, Id: "12345", Age: 21}, nil -} - -// There is no need to export DUBBO_GO_CONFIG_PATH, as you are using config api to set config -func main() { - // 获取动态配置实例 dynamicConfig - dynamicConfig, err := config.NewConfigCenterConfigBuilder(). - SetProtocol("nacos"). - SetAddress("127.0.0.1:8848"). - SetGroup("dubbo"). - Build().GetDynamicConfiguration() - if err != nil { - panic(err) - } - - // 使用 dynamicConfig 结构来发布配置 - if err := dynamicConfig.PublishConfig("dubbo-go-samples-configcenter-nacos-server", "dubbo", configCenterNacosServerConfig); err != nil { - panic(err) - } - - // 使用 dynamicConfig 结构来读取配置 - data, err := dynamicConfig.GetRule("dubbo-go-samples-configcenter-nacos-server", config_center.WithGroup("dubbo")) - if err != nil{ - panic(err) - } - logger.Infof("get config = %s", data) - - - // 使用 dynamicConfig 结构, 通过自定义listener来订阅配置更新事件 - l := &listener{} - dynamicConfig.AddListener("dubbo-go-samples-configcenter-nacos-server", l) - - time.Sleep(time.Second * 10) - - config.SetProviderService(&GreeterProvider{}) - - // 以 API 的形式来启动框架 - rootConfig := config.NewRootConfigBuilder(). - SetConfigCenter(config.NewConfigCenterConfigBuilder(). - SetProtocol("nacos").SetAddress("127.0.0.1:8848"). // 根据配置结构,设置配置中心 - SetDataID("dubbo-go-samples-configcenter-nacos-server"). // 设置配置ID - SetGroup("dubbo"). - Build()). - Build() - - if err := rootConfig.Init(); err != nil { // 框架启动 - panic(err) - } - select {} -} - -type listener struct { - -} - -func (l listener) Process(event *config_center.ConfigChangeEvent) { - logger.Infof("listener get config = %s", event.Value) -} - -``` - -当然,以 API 的形式来启动框架时,可以直接以API的形式来启动框架。 - -## 4. Dubbogo 配置热更新 - -// todo - -正在开发中ing diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/config-center/desc.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/config-center/desc.md deleted file mode 100644 index 15f13f6f85a1..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/config-center/desc.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/tutorial/develop/config-center/desc/ - - /zh-cn/docs3-v2/golang-sdk/tutorial/develop/config-center/desc/ -description: 配置中心介绍 -title: 配置中心介绍 -type: docs -weight: 1 ---- diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/config-center/remote_config.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/config-center/remote_config.md deleted file mode 100644 index b63ee76a9a76..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/config-center/remote_config.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/tutorial/develop/config-center/remote_config/ - - /zh-cn/docs3-v2/golang-sdk/tutorial/develop/config-center/remote_config/ -description: 远程加载配置启动 -title: 远程加载配置启动 -type: docs -weight: 3 ---- - - - - - - -## 1. 准备工作 - -- dubbo-go cli 工具和依赖工具已安装 -- 创建一个新的 demo 应用 -- 本地/远程启动一个 Nacos 实例,登录控制台 - -## 2. 在配置中心创建配置 - -Dubbogo 服务框架支持将配置文件 'dubbogo.yaml' 的内容预先放入配置中心,再通过配置注册中心的地址。在本地 dubbogo.yaml 配置文件内只需写入配置中心的信息即可,目前支持作为配置中心的中间件有:apollo、nacos、zookeeper - -可参考 [配置中心 samples](https://github.com/apache/dubbo-go-samples/tree/f7febed9d686cb940ea55d34b5baa567d7574a44/configcenter),凡是正确配置了config-center 配置的服务,都会优先从配置中心加载整个配置文件。 - -```yaml -dubbo: - config-center: - protocol: nacos - address: 127.0.0.1:8848 - data-id: dubbo-go-samples-configcenter-nacos-server - group: myGroup # nacos group, default is DEFAULT_GROUP -# namespace: 9fb00abb-278d-42fc-96bf-e0151601e4a1 # nacos namespaceID, default is public namespace - -## set in config center, group is 'dubbo', dataid is 'dubbo-go-samples-configcenter-nacos-server', namespace is default -#dubbo: -# registries: -# demoZK: -# protocol: nacos -# timeout: 3s -# address: 127.0.0.1:8848 -# protocols: -# triple: -# name: tri -# port: 20000 -# provider: -# services: -# GreeterProvider: -# interface: com.apache.dubbo.sample.basic.IGreeter # must be compatible with grpc or dubbo-java -``` diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/features/_index.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/features/_index.md deleted file mode 100644 index c2233ed61313..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/features/_index.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/tutorial/develop/features/ - - /zh-cn/docs3-v2/golang-sdk/tutorial/develop/features/ -description: 高级特性 -title: 高级特性 -type: docs -weight: 6 ---- diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/features/config_api.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/features/config_api.md deleted file mode 100644 index 4f14dfaab794..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/features/config_api.md +++ /dev/null @@ -1,107 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/tutorial/develop/features/config_api/ - - /zh-cn/docs3-v2/golang-sdk/tutorial/develop/features/config_api/ -description: 使用配置 API 启动应用 -title: 使用配置 API 启动应用 -type: docs -weight: 2 ---- - - - - - - -## 1. 准备工作 - -- dubbo-go cli 工具和依赖工具已安装 -- 创建一个新的 demo 应用 - -## 2. 使用配置 API 启动应用 - -用户无需使用配置文件,可直接在代码中以 API 的调用的形式写入配置 - -### 2.1 修改服务端代码: - -```go -func main() { - config.SetProviderService(&GreeterProvider{}) - - protocolConfig := config.NewProtocolConfigBuilder(). - SetPort("20000"). - SetName("tri"). - Build() - - serviceConfig := config.NewServiceConfigBuilder(). - SetInterface(""). // read interface from pb - Build() - - providerConfig := config.NewProviderConfigBuilder(). - AddService("GreeterProvider", serviceConfig). - Build() - - rootConfig := config.NewRootConfigBuilder(). - AddProtocol("triple-protocol-id", protocolConfig). // add protocol, key is custom - SetProvider(providerConfig).Build() - - if err := config.Load(config.WithRootConfig(rootConfig)); err != nil { - panic(err) - } - select {} -} - -``` - -配置 API 看上去写法较为复杂,但单个配置结构的构造过程都是一致的,参考 Java Builder 的设计,我们在配置 API 模块选用 `New().SetA().SetB().Build()`的方式来逐层构造单个配置结构。 - -完成后,可删除掉go-server/conf 文件夹。 - - - -### 2.2 修改客户端代码: - -go-client/cmd/client.go - -```go -func main() { - config.SetConsumerService(grpcGreeterImpl) - - referenceConfig := config.NewReferenceConfigBuilder(). - SetProtocol("tri"). - SetURL("tri://localhost:20000"). - SetInterface(""). // read interface name from pb - Build() - - consumerConfig := config.NewConsumerConfigBuilder(). - AddReference("GreeterClientImpl", referenceConfig). - Build() - - rootConfig := config.NewRootConfigBuilder(). - SetConsumer(consumerConfig).Build() - if err := config.Load(config.WithRootConfig(rootConfig)); err != nil { - panic(err) - } - - logger.Info("start to test dubbo") - req := &api.HelloRequest{ - Name: "laurence", - } - reply, err := grpcGreeterImpl.SayHello(context.Background(), req) - if err != nil { - logger.Error(err) - } - logger.Infof("client response result: %v\n", reply) -} - -``` - -完成后,可删除掉go-client/conf 文件夹。 - -### 2.3 验证 Config API - -分别启动 server 和 client ,查看调用信息。 - -``` -INFO cmd/client.go:62 client response result: name:"Hello laurence" id:"12345" age:21 -``` \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/features/context.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/features/context.md deleted file mode 100644 index 96a68906d615..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/features/context.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/tutorial/develop/features/context/ - - /zh-cn/docs3-v2/golang-sdk/tutorial/develop/features/context/ -description: 使用 ctx 传递上下文信息 -title: 使用 ctx 传递上下文信息 -type: docs -weight: 6 ---- - - - - - - -## 1. 准备工作 - -- dubbo-go cli 工具和依赖工具已安装 -- 创建一个新的 demo 应用 - -## 2. 使用 context 传递附加信息 - -参考 [dubbo-go-samples/context](https://github.com/apache/dubbo-go-samples/tree/f7febed9d686cb940ea55d34b5baa567d7574a44/context) diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/features/custom-logger.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/features/custom-logger.md deleted file mode 100644 index 9e595c7d3a40..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/features/custom-logger.md +++ /dev/null @@ -1,94 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/tutorial/develop/features/custom-logger/ - - /zh-cn/docs3-v2/golang-sdk/tutorial/develop/features/custom-logger/ -description: 日志 -title: 日志 -type: docs -weight: 6 ---- - - - - - - -参考samples [dubbo-go-samples/logger](https://github.com/apache/dubbo-go-samples/tree/f7febed9d686cb940ea55d34b5baa567d7574a44/logger) - -## 1. 日志配置 - -dubbogo 3.0 默认采用 zap 日志库,在配置文件中不添加 logger 配置,日志将会打印到控制默认级别为debug。您也可在配置文件中配置日志级别、, 可参照如下方式来配置zap-config和lumberjack-config,从而定制化日志输出。 - -```yaml -dubbo: - logger: - zap-config: - level: debug # 日志级别 - development: false - disableCaller: false - disableStacktrace: false - encoding: "console" - # zap encoder 配置 - encoderConfig: - messageKey: "message" - levelKey: "level" - timeKey: "time" - nameKey: "logger" - callerKey: "caller" - stacktraceKey: "stacktrace" - lineEnding: "" - levelEncoder: "capitalColor" - timeEncoder: "iso8601" - durationEncoder: "seconds" - callerEncoder: "short" - nameEncoder: "" - outputPaths: - - "stderr" - errorOutputPaths: - - "stderr" - lumberjack-config: - # 写日志的文件名称 - filename: "logs.log" - # 每个日志文件长度的最大大小,单位是 MiB。默认 100MiB - maxSize: 1 - # 日志保留的最大天数(只保留最近多少天的日志) - maxAge: 3 - # 只保留最近多少个日志文件,用于控制程序总日志的大小 - maxBackups: 5 - # 是否使用本地时间,默认使用 UTC 时间 - localTime: true - # 是否压缩日志文件,压缩方法 gzip - compress: false -``` - -## 2. 日志API 和 自定义日志 - -日志Interface - -```go -type Logger interface { - Info(args ...interface{}) - Warn(args ...interface{}) - Error(args ...interface{}) - Debug(args ...interface{}) - Fatal(args ...interface{}) - - Infof(fmt string, args ...interface{}) - Warnf(fmt string, args ...interface{}) - Errorf(fmt string, args ...interface{}) - Debugf(fmt string, args ...interface{}) - Fatalf(fmt string, args ...interface{}) -} -``` - -日志API - -```go -import "dubbo.apache.org/dubbo-go/v3/common/logger" - - -logger.SetLoggerLevel(warn) // 在 main 函数中设置日志级别 -logger.SetLogger(myLogger) // 在 main 函数中设置自定义logger -``` - -- 日志API不可以在Init 阶段使用,否则可能会发生意料之外的问题。 diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/interflow/_index.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/interflow/_index.md deleted file mode 100644 index 2bdf738eb8d6..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/interflow/_index.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/tutorial/develop/interflow/ - - /zh-cn/docs3-v2/golang-sdk/tutorial/develop/interflow/ -description: 异构体系互通 -title: 异构体系互通 -type: docs -weight: 4 ---- diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/interflow/call_grpc.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/interflow/call_grpc.md deleted file mode 100644 index f4503dfa1a93..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/interflow/call_grpc.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/tutorial/develop/interflow/call_grpc/ - - /zh-cn/docs3-v2/golang-sdk/tutorial/develop/interflow/call_grpc/ -description: 与 gRPC 应用互通 -title: 与 gRPC 应用互通 -type: docs -weight: 5 ---- - - - - - - -## 1. 准备工作 - -- dubbo-go cli 工具和依赖工具已安装 -- 创建一个新的 demo 应用 - -## 2. Dubbo-go 应用与 gRPC 应用互通 - -参考 [dubbo-go-samples/rpc/triple/pb/dubbogo-grpc](https://github.com/apache/dubbo-go-samples/tree/f7febed9d686cb940ea55d34b5baa567d7574a44/rpc/triple/pb/dubbogo-grpc) diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/interflow/call_java.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/interflow/call_java.md deleted file mode 100644 index 608f41b78bfe..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/interflow/call_java.md +++ /dev/null @@ -1,851 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/tutorial/develop/interflow/call_java/ - - /zh-cn/docs3-v2/golang-sdk/tutorial/develop/interflow/call_java/ -description: 与 Java 应用跨语言互通 -title: 与 Java 应用跨语言互通 -type: docs -weight: 4 ---- - - - - - - -## 准备工作 - -### 环境 - -JDK 8,Golang >= 1.15,Dubbo 3.0.2,zookeeper 启动, - -### Go- Java 互通前提 - -- Go/Java 定义的传输结构一致 - - - PB 序列化 - - proto for Go - - ```protobuf - // The response message containing the greetings - message User { - string name = 1; - string id = 2; - int32 age = 3; - } - ``` - - proto for Java - - ```protobuf - // The response message containing the greetings - message User { - string name = 1; - string id = 2; - int32 age = 3; - } - ``` - - - Hessian 序列化 - - POJO for Go,需参考 [Dubbogo Hessian 序列化支持文档](https://cn.dubbo.apache.org/zh-cn/overview/mannual/golang-sdk/tutorial/develop/interflow/call_java/) - - ```go - type User struct { - ID string - Name string - Age int32 - } - - func (u *User) JavaClassName() string { - return "org.apache.dubbo.User" - } - - func init(){ - hessian.RegisterPOJO(&User{}) - } - ``` - - POJO for Java - - ```java - package org.apache.dubbo - - public class User { - private String id; - private String name; - private int age; - } - ``` - -- Java 需要互通的方法签名与 Go 一致 - - 例如: - - Java Interface - - ```java - public interface IGreeter { - /** - *
-     *  Sends a greeting
-     * 
- */ - User sayHello(HelloRequest request); - } - ``` - - Go client (由protoc-gen-go-triple 根据 proto 文件自动生成) - - ```go - type GreeterClientImpl struct { - // Sends a greeting - SayHello func(ctx context.Context, in *HelloRequest) (*User, error) - } - ``` - - Go server (由开发者定义) - - ```go - type GreeterProvider struct { - api.GreeterProviderBase - } - - func (s *GreeterProvider) SayHello(ctx context.Context, in *api.HelloRequest) (*api.User, error) { - logger.Infof("Dubbo3 GreeterProvider get user name = %s\n", in.Name) - return &api.User{Name: "Hello " + in.Name, Id: "12345", Age: 21}, nil - } - ``` - - Go 方法需要遵守 [Dubbogo 3.0 用户服务接口定义规范](https://www.yuque.com/docs/share/eff9c51f-a7f4-47d6-87ff-11a2152bdffe?) - - - -- Java 的三元组与Go service/reference 配置的 interface 一致 - - 三元组,即为接口级别配置的:interface, group, version。**其中需要注意,group 和 version 的概念为 dubbo 接口的 group 和vesion,在启动 dubbo-java 服务时配置于 spring cloud 的 properties 文件中,并非pom.xml 中 mvn 依赖的version。** group 和version 默认为空,在 dubbo-go 框架中,可以在service/reference 的对应位置指定 group 和 version。 - - 例如: - - Java 的接口全名:com.apache.dubbo.sample.basic.IGreeter,接口 version 为v1.0.1, group 为 - - Go-client: - - ```yaml - references: - GreeterClientImpl: - protocol: tri - interface: com.apache.dubbo.sample.basic.IGreeter # must be compatible with grpc or dubbo-java - group: dubbogo # 需要与服务端对应 默认为空 - version: v1.0.1 # 需要与服务端对应 默认为空 - ``` - - Go-server: - - ```yaml - services: - GreeterProvider: - protocol-ids: tripleProtocol - interface: com.apache.dubbo.sample.basic.IGreeter # must be compatible with grpc or dubbo-java - group: dubbogo # 需要与服务端对应 默认为空 - version: v1.0.1 # 需要与服务端对应 默认为空 - ``` - - - -## 1. 基于 Triple 协议互通 (PB序列化) - -参考 [dubbo-go-samples/helloworld](https://github.com/apache/dubbo-go-samples/tree/f7febed9d686cb940ea55d34b5baa567d7574a44/helloworld) - -### 1.1 Go-Client -> Java-Server - -#### Java-Server 启动 - -1. 定义 Java 的 PB 文件,可参考 [Dubbo 快速开始](/zh-cn/docs/quick-start/) - -```protobuf -syntax = "proto3"; - -option java_package = "org.apache.dubbo.sample.hello"; - -package helloworld; - -// The request message containing the user's name. -message HelloRequest { - string name = 1; -} - -// The response message containing the greetings -message User { - string name = 1; - string id = 2; - int32 age = 3; -} -``` - -该接口描述文件定义了将会生成的 Java 类 org.apache.dubbo.sample.hello.Helloworld,以及类中包含的传输结构 HelloRequest 和 User 类。 - -2. 定义服务接口: - - com.apache.dubbo.sample.basic.IGreeter - -```java -package com.apache.dubbo.sample.basic; - -// 引入根据 PB 生成的类 -import org.apache.dubbo.sample.hello.Helloworld.User; -import org.apache.dubbo.sample.hello.Helloworld.HelloRequest; - -public interface IGreeter { - /** - *
-     *  Sends a greeting
-     * 
- */ - // 定义接口 - User sayHello(HelloRequest request); -} -``` - -3. 实现服务接口: - - IGreeter1Impl.java - -```java -package com.apache.dubbo.sample.basic; - -import org.apache.dubbo.sample.hello.Helloworld.User; -import org.apache.dubbo.sample.hello.Helloworld.HelloRequest; - -public class IGreeter1Impl implements IGreeter { - @Override - public User sayHello(HelloRequest request) { - System.out.println("receiv: " + request); - User usr = User.newBuilder() - .setName("hello " + request.getName()) - .setAge(18) - .setId("12345").build(); - return usr; - } -} -``` - -4. 使用 Dubbo3 框架启动服务 - - ApiProvider.java - -```java -package com.apache.dubbo.sample.basic; - -import org.apache.dubbo.common.constants.CommonConstants; -import org.apache.dubbo.config.ApplicationConfig; -import org.apache.dubbo.config.ProtocolConfig; -import org.apache.dubbo.config.RegistryConfig; -import org.apache.dubbo.config.ServiceConfig; -import java.util.concurrent.CountDownLatch; - -public class ApiProvider { - public static void main(String[] args) throws InterruptedException { - ServiceConfig service = new ServiceConfig<>(); - service.setInterface(IGreeter.class); - service.setRef(new IGreeter1Impl()); - // 使用 Triple 协议 - service.setProtocol(new ProtocolConfig(CommonConstants.TRIPLE, 50051)); - service.setApplication(new ApplicationConfig("demo-provider")); - // 使用 ZK 作为注册中心 - service.setRegistry(new RegistryConfig("zookeeper://127.0.0.1:2181")); - service.export(); - System.out.println("dubbo service started"); - new CountDownLatch(1).await(); - } -} -``` - -启动服务,可看到输出如下日志,代表 Java Triple Server 启动成功 - -``` -main INFO bootstrap.DubboBootstrap: [DUBBO] DubboBootstrap has started., dubbo version: 3.0.2, current host: 192.168.0.108 -dubbo service started -``` - -#### Go-Client 启动 - -对于已经启动的Dubbo服务,如需要开发与其对应的Go-client,需要进行如下步骤: - -1. 编写与 Java 适配的 proto文件 - - samples_api.proto - -```protobuf -syntax = "proto3"; -package api; // pacakge 名随意指定 - -// necessary -option go_package = "./;api"; - -// The greeting service definition. -service Greeter { - // Sends a greeting - rpc SayHello (HelloRequest) returns (User) {} -} - -// The request message containing the user's name. -message HelloRequest { - string name = 1; -} - -// The response message containing the greetings -message User { - string name = 1; - string id = 2; - int32 age = 3; -} -``` - -2. 使用 protoc-gen-triple 生成接口文件 - -```bash -protoc -I . samples_api.proto --triple_out=plugins=triple:. -``` - -3. 撰写配置文件: dubbogo.yml - -```yaml -dubbo: - registries: - demoZK: - protocol: zookeeper - address: 127.0.0.1:2181 - consumer: - references: - GreeterClientImpl: - protocol: tri - interface: com.apache.dubbo.sample.basic.IGreeter # must be compatible with grpc or dubbo-java -``` - -4. 撰写 main.go 文件,发起调用 - -```go -// 引入生成的接口结构 -var grpcGreeterImpl = new(api.GreeterClientImpl) - -// export DUBBO_GO_CONFIG_PATH=dubbogo.yml -func main() { - config.SetConsumerService(grpcGreeterImpl) - if err := config.Load(); err != nil { - panic(err) - } - time.Sleep(3 * time.Second) - - logger.Info("start to test dubbo") - req := &api.HelloRequest{ - Name: "laurence", - } - reply, err := grpcGreeterImpl.SayHello(context.Background(), req) - if err != nil { - logger.Error(err) - } - logger.Infof("client response result: %v\n", reply) -} -``` - -5. 可查看到调用成功的日志 - -- go-client - -``` -cmd/client.go:53 client response result: name:"hello laurence" id:"12345" age:18 -``` - -- java-server - -``` -receiv: name: "laurence" -``` - -### 1.2 Java-Client -> Go-Server - -#### Go-Server 启动 - -1. 定义配置文件 - -```yaml -dubbo: - registries: - demoZK: - protocol: zookeeper - address: 127.0.0.1:2181 - protocols: - triple: - name: tri - port: 20000 - provider: - services: - GreeterProvider: - interface: com.apache.dubbo.sample.basic.IGreeter # must be compatible with grpc or dubbo-java -``` - -2. 引入传输结构,定义服务 - -```go -type GreeterProvider struct { - api.GreeterProviderBase -} - -func (s *GreeterProvider) SayHello(ctx context.Context, in *api.HelloRequest) (*api.User, error) { - logger.Infof("Dubbo3 GreeterProvider get user name = %s\n", in.Name) - return &api.User{Name: "Hello " + in.Name, Id: "12345", Age: 21}, nil -} -``` - -3. 启动服务 - -```go -// export DUBBO_GO_CONFIG_PATH=dubbogo.yml -func main() { - config.SetProviderService(&GreeterProvider{}) - if err := config.Load(); err != nil { - panic(err) - } - select {} -} -``` - - - -#### Java-Client 启动 - -1. proto 文件编写和接口生成参考上述 java-server 介绍 - -2. 启动Consumer - - ApiCnosumer.java - -```java -public class ApiConsumer { - public static void main(String[] args) throws InterruptedException, IOException { - ReferenceConfig ref = new ReferenceConfig<>(); - ref.setInterface(IGreeter.class); - ref.setCheck(false); - ref.setProtocol(CommonConstants.TRIPLE); - ref.setLazy(true); - ref.setTimeout(100000); - ref.setApplication(new ApplicationConfig("demo-consumer")); - ref.setRegistry(new RegistryConfig("zookeeper://127.0.0.1:2181")); - final IGreeter iGreeter = ref.get(); - - System.out.println("dubbo ref started"); - Helloworld.HelloRequest req = Helloworld.HelloRequest.newBuilder().setName("laurence").build(); - try { - final Helloworld.User reply = iGreeter.sayHello(req); - TimeUnit.SECONDS.sleep(1); - System.out.println("Reply:" + reply); - } catch (Throwable t) { - t.printStackTrace(); - } - System.in.read(); - } -} -``` - -## 2. 基于 Dubbo 协议互通 (Hessian2序列化) - -参考 [dubbo-go-samples/rpc/dubbo](https://github.com/apache/dubbo-go-samples/tree/f7febed9d686cb940ea55d34b5baa567d7574a44/rpc/dubbo) - -### 2.1 Go-Client -> Java-Server - -#### Java-Server 启动 - -1. 定义 Java 接口、参数和返回值,可参考 [Dubbo 快速开始](/zh-cn/docs/quick-start/) - -```java -package org.apache.dubbo; - -// 需要暴露的服务接口 -public interface UserProvider { - User getUser(int usercode); -} - -``` - -```java -package org.apache.dubbo; - -public class User implements Serializable { - - private String id; - - private String name; - - private int age; - - private Date time = new Date(); - /* ... */ -} -``` - -2. 实现服务接口: - -UserProviderImpl.java - -```java -package org.apache.dubbo; -public class UserProviderImpl implements UserProvider { - public User getUser(int userCode) { - return new User(String.valueOf(userCode), "userCode get", 48); - } -} - -``` - -3. 使用SpringBoot 启动 - -Provider.java - -```java -package org.apache.dubbo; - -// use when config by API -/* -import java.util.concurrent.CountDownLatch; - -import org.apache.dubbo.common.constants.CommonConstants; -import org.apache.dubbo.config.ApplicationConfig; -import org.apache.dubbo.config.ProtocolConfig; -import org.apache.dubbo.config.RegistryConfig; -import org.apache.dubbo.config.ServiceConfig; -*/ -import org.springframework.context.support.ClassPathXmlApplicationContext; - -public class Provider { - // main function, config from spring boot - public static void main(String[] args) throws Exception { - ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"META-INF/spring/dubbo.provider.xml"}); - context.start(); - System.in.read(); // press any key to exit - } - - -// config by API -// public static void startComplexService() throws InterruptedException { -// ServiceConfig service = new ServiceConfig<>(); -// service.setInterface(ComplexProvider.class); -// service.setRef(new ComplexProviderImpl()); -// service.setProtocol(new ProtocolConfig(CommonConstants.DUBBO_PROTOCOL, 20001)); -// service.setApplication(new ApplicationConfig("demo-provider")); -// service.setRegistry(new RegistryConfig("zookeeper://127.0.0.1:2181")); -// service.export(); -// System.out.println("dubbo service started"); -// new CountDownLatch(1).await(); -// } -} - -``` - -4. 通过Spring 配置 Dubbo 参数 - - Resources/META-INF.spring/dubbo.provider.xml - -```xml - - - - - - - - - - - - - - - - - - - - -``` - - - -启动Provider类,可看到输出如下日志,代表 Dubbo Server 启动成功 - -``` -[DUBBO] DubboBootstrap is ready., dubbo version: 2.7.7, current host: 127.0.0.1 -[DUBBO] DubboBootstrap has started., dubbo version: 2.7.7, current host: 127.0.0.1 -``` - -#### Go-Client 启动 - -对于已经启动的Dubbo服务,如需要开发与其对应的Go-client,需要进行如下步骤: - -1. 编写与 Java 适配的 POJO 类 User - - -```go -import( - hessian "github.com/apache/dubbo-go-hessian2" -) - -// 字段需要与 Java 侧对应,首字母大写 -type User struct { - ID string - Name string - Age int32 - Time time.Time -} - - -func (u *User) JavaClassName() string { - return "org.apache.dubbo.User" // 需要与 Java 侧 User 类名对应 -} - -func init(){ - hessian.RegisterPOJO(&pkg.User{}) // 注册 POJO -} -``` - -2. 编写与 Java 侧一致的客户端存根类,其接口方法需要与Java侧对应 - - 规定第一个参数必须为 context.Context,最后一个返回值必须为 error - -```go -import( - "dubbo.apache.org/dubbo-go/v3/config" -) - -var ( - userProvider = &pkg.UserProvider{} -) - -// UserProvider 客户端存根类 -type UserProvider struct { - // dubbo标签,用于适配go侧客户端大写方法名 -> java侧小写方法名,只有 dubbo 协议客户端才需要使用 - GetUser func(ctx context.Context, req int32) (*User, error) `dubbo:"getUser"` -} - -func init(){ - // 注册客户端存根类到框架,实例化客户端接口指针 userProvider - config.SetConsumerService(userProvider) -} - -``` - -3. 撰写配置文件: dubbogo.yml - -```yaml -dubbo: - registries: - demoZK: # 定义注册中心ID - protocol: zookeeper - timeout: 3s - address: 127.0.0.1:2181 - consumer: - references: - UserProvider: # 存根类名 - protocol: dubbo # dubbo 协议,默认 hessian2 序列化方式 - interface: org.apache.dubbo.UserProvider # 接口需要与Java侧对应 - logger: - zap-config: - level: info # 日志级别 -``` - -或者使用Triple + Hessian2 序列化请求Server。本例子如果跟Java Server互通则不能用Triple。 - -```yaml -dubbo: - registries: - demoZK: - protocol: zookeeper - timeout: 3s - address: 127.0.0.1:2181 - consumer: - references: - UserProvider: - protocol: tri # triple 协议 - serialization: hessian2 # 序列化方式 hessian2,triple 协议默认为 pb 序列化,不配置会报错 - interface: org.apache.dubbo.UserProvider - logger: - zap-config: - level: info -``` - -4. 撰写 main.go 文件,发起调用 - -```go -func main(){ - config.Load() - var i int32 = 1 - user, err := userProvider.GetUser2(context.TODO(), i) - if err != nil { - panic(err) - } - logger.Infof("response result: %v", user) -} -``` - -5. 可查看到调用成功的日志,符合预期 - -- go-client - -```bash -response result: User{ID:1, Name:userCode get, Age:48, Time:2021-10-21 20:25:26.009 +0800 CST} -``` - -### 2.2 Java-Client -> Go-Server - -#### Go-Server 启动 - -1. 定义配置文件 - -```yaml -dubbo: - registries: - demoZK: - protocol: zookeeper - address: 127.0.0.1:2181 - protocols: - dubbo: - name: dubbo - port: 20000 - provider: - services: - UserProvider: - interface: org.apache.dubbo.UserProvider - logger: - zap-config: - level: info -``` - -2. 引入传输结构,定义服务以及方法名映射 - -```go -type UserProvider struct { -} - -func (u *UserProvider) GetUser(ctx context.Context, req int32) (*User, error) { - var err error - logger.Infof("req:%#v", req) - user := &User{} - user.ID = strconv.Itoa(int(req)) - return user, err -} - -// MethodMapper 定义方法名映射,从 Go 的方法名映射到 Java 小写方法名,只有 dubbo 协议服务接口才需要使用 -func (s *UserProvider) MethodMapper() map[string]string { - return map[string]string{ - "GetUser": "getUser", - } -} - -func init(){ - config.SetProviderService(&pkg.UserProvider{}) -} - -``` - -3. 启动服务 - -```go -// export DUBBO_GO_CONFIG_PATH=dubbogo.yml -func main() { - if err := config.Load(); err != nil { - panic(err) - } - select {} -} -``` - - - -#### Java-Client 启动 - -1. Java 客户端 Spring 配置 - - resources/META-INF.spring/dubbo.consumer.xml - - ```xml - - - - - - - - - - - - - - - - - - - - - - - - - - - ``` - -2. 发起调用 - -```java -public class Consumer { - // Define a private variable (Required in Spring) - private static UserProvider userProvider; - - public static void main(String[] args) throws Exception { - ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"META-INF/spring/dubbo.consumer.xml"}); - userProvider = (UserProvider)context.getBean("userProvider"); - testGetUser(); - } - - - private static void testGetUser() throws Exception { - User user = userProvider.getUser(1); - System.out.println(user.getId()); - } -} -``` diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/protocol/_index.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/protocol/_index.md deleted file mode 100644 index e6636719352b..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/protocol/_index.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/tutorial/develop/protocol/ - - /zh-cn/docs3-v2/golang-sdk/tutorial/develop/protocol/ -description: 协议配置 -title: 协议配置 -type: docs -weight: 3 ---- diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/protocol/choose_protocol.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/protocol/choose_protocol.md deleted file mode 100644 index 4637dbcfe57d..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/protocol/choose_protocol.md +++ /dev/null @@ -1,239 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/tutorial/develop/protocol/choose_protocol/ - - /zh-cn/docs3-v2/golang-sdk/tutorial/develop/protocol/choose_protocol/ -description: 选择使用的网络协议 -keywords: 选择使用的网络协议 -title: 选择使用的网络协议 -type: docs ---- - - - - - - -# 修改使用的协议 - -## 1. 准备工作 - -- dubbo-go cli 工具和依赖工具已安装 -- 创建一个新的 demo 应用 - -## 2. 如何配置网络协议 - -在快速开始章节可以看到,生成的Demo 将 Protocol 设置为 tri,表明使用 Triple 协议进行服务暴露和服务调用。快速开始章节使用的配置 API 进行配置的写入,这样的好处是无需使用配置文件。我们摘取出和网络协议相关的内容进行说明。 - -### 使用配置文件 - -参考 samples/helloworld - -- 客户端使用配置文件设置网络协议 - -```yaml -dubbo: - consumer: - references: - GreeterClientImpl: - protocol: tri # set protcol to tri - interface: com.apache.dubbo.sample.basic.IGreeter -``` - -- 服务端使用配置文件设置网络协议 - -```yaml -dubbo: - protocols: - triple: # define protcol-id 'triple' - name: tri # set protcol to tri - port: 20000 # set port to be listened - provider: - services: - GreeterProvider: - protocol-ids: triple # use protocol-ids named 'triple' - interface: com.apache.dubbo.sample.basic.IGreeter -``` - - - -## 3. 编写 Dubbo 协议的接口和实现 - -### 3.1 定义接口和传输结构,位于api/api.go - -```go -package api - -import ( - "context" - "dubbo.apache.org/dubbo-go/v3/config" - hessian "github.com/apache/dubbo-go-hessian2" - "time" -) - -//1. 定义传输结构, 如需 Java 互通,字段需要与 Java 侧对应,首字母大写 -type User struct { - ID string - Name string - Age int32 - Time time.Time -} - -func (u *User) JavaClassName() string { - return "org.apache.dubbo.User" // 如果与 Java 互通,需要与 Java 侧 User class全名对应, -} - - -var ( - UserProviderClient = &UserProvider{} // 客户端指针 -) - -// 2。 定义客户端存根类:UserProvider -type UserProvider struct { - // dubbo标签,用于适配go侧客户端大写方法名 -> java侧小写方法名,只有 dubbo 协议客户端才需要使用 - GetUser func(ctx context.Context, req int32) (*User, error) //`dubbo:"getUser"` -} - -func init(){ - hessian.RegisterPOJO(&User{}) // 注册传输结构到 hessian 库 - // 注册客户端存根类到框架,实例化客户端接口指针 userProvider - config.SetConsumerService(UserProviderClient) -} -``` - -### 2.2 编写 Go-Server 配置和代码 - -server/dubbogo.yaml - -```yaml -dubbo: - registries: - demoZK: # 定义服务注册发现中心 - protocol: zookeeper - address: 127.0.0.1:2181 - protocols: - dubbo: - name: dubbo # 协议名 dubbo - port: 20000 # 监听端口 - provider: - services: - UserProvider: # 服务提供结构类名 - interface: org.apache.dubbo.UserProvider # 接口需要与 go/java 客户端对应 -``` - -server/server.go - -```go -package main - -import ( - "context" - "dubbo.apache.org/dubbo-go/v3/common/logger" // dubbogo 框架日志 - "dubbo.apache.org/dubbo-go/v3/config" - _ "dubbo.apache.org/dubbo-go/v3/imports" // dubbogo 框架依赖,所有dubbogo进程都需要隐式引入一次 - "dubbo3-demo/api" - "strconv" - "time" -) - -type UserProvider struct { -} - -// 实现接口方法 -func (u *UserProvider) GetUser(ctx context.Context, req int32) (*api.User, error) { - var err error - logger.Infof("req:%#v", req) - user := &api.User{} - user.ID = strconv.Itoa(int(req)) - user.Name = "laurence" - user.Age = 22 - user.Time = time.Now() - return user, err -} - -//// MethodMapper 定义方法名映射,从 Go 的方法名映射到 Java 小写方法名,只有 dubbo 协议服务接口才需要使用 -//// go -> go 互通无需使用 -//func (s *UserProvider) MethodMapper() map[string]string { -// return map[string]string{ -// "GetUser": "getUser", -// } -//} - -func init(){ - config.SetProviderService(&UserProvider{}) // 注册服务提供者类,类名与配置文件中的 service 对应 -} - -// export DUBBO_GO_CONFIG_PATH=dubbogo.yml 运行前需要设置环境变量,指定配置文件位置 -func main() { - if err := config.Load(); err != nil { - panic(err) - } - select {} -} - -``` - - - -### 2.3 编写 Go-Client 配置和代码 - -client/dubbogo.yaml - -```yaml -dubbo: - registries: - demoZK: # 定义服务注册发现中心 - protocol: zookeeper - address: 127.0.0.1:2181 - consumer: - references: - UserProvider: # 存根类名 - protocol: dubbo # dubbo 协议,默认 hessian2 序列化方式 - interface: org.apache.dubbo.UserProvider # 接口需要与 go/java 客户端对应 -``` - -client/client.go - -```go -package main - -import ( - "context" - "dubbo.apache.org/dubbo-go/v3/common/logger" - "dubbo.apache.org/dubbo-go/v3/config" - _ "dubbo.apache.org/dubbo-go/v3/imports" - "dubbo3-demo/api" -) - -func main(){ - // 启动框架 - if err := config.Load(); err != nil{ - panic(err) - } - var i int32 = 1 - // 发起调用 - user, err := api.UserProviderClient.GetUser(context.TODO(), i) - if err != nil { - panic(err) - } - logger.Infof("response result: %+v", user) -} -``` - -## 4. 启动服务 - -开启两个终端,分别进入server client 目录 - -分别执行; - -```shell -export DUBBO_GO_CONFIG_PATH=dubbogo.yml -go run . -``` - -先后启动服务端和客户端, 可在客户端看到输出: - -```shell -response result: &{ID:1 Name:laurence Age:22 Time:2021-11-12 17:59:39.185 +0800 CST} -``` - -调用成功 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/protocol/error.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/protocol/error.md deleted file mode 100644 index 69228ee5722a..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/protocol/error.md +++ /dev/null @@ -1,131 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/tutorial/develop/protocol/error/ - - /zh-cn/docs3-v2/golang-sdk/tutorial/develop/protocol/error/ -description: 异常信息回传 -title: 异常信息回传 -type: docs -weight: 8 ---- - - - - - - -## 1. 准备工作 - -- dubbo-go cli 工具和依赖工具已安装 -- 创建一个新的 demo 应用 - -## 2. 传递异常信息 - -参考samples [dubbo-go-samples/error](https://github.com/apache/dubbo-go-samples/tree/f7febed9d686cb940ea55d34b5baa567d7574a44/error) - -### 用户异常回传介绍 - -用户可以在 provider 端生成用户定义的异常信息,可以记录异常产生堆栈,triple 协议可保证将用户在客户端获取到异常 message ,并可以查看报错堆栈,便于定位问题。 - -注意返回 error 非 nil 时,框架不负责其他返回值的传递。 - -- 在Triple provider 端返回异常,以 pb 序列化为例: - -```go -package main - -import ( - "context" -) - -import ( - "dubbo.apache.org/dubbo-go/v3/common/logger" - - // 使用可以记录堆栈的异常库,此处以 "github.com/pkg/errors" 为例 - "github.com/pkg/errors" -) - -import ( - triplepb "github.com/apache/dubbo-go-samples/api" -) - - -// 一个实现了 pb 接口的服务提供结构 -type ErrorResponseProvider struct { - triplepb.UnimplementedGreeterServer -} - -// 回传错误的接口 -func (s *ErrorResponseProvider) SayHello(ctx context.Context, in *triplepb.HelloRequest) (*triplepb.User, error) { - logger.Infof("Dubbo3 GreeterProvider get user name = %s\n" + in.Name) - // 返回用户自定义异常 - return &triplepb.User{Name: "Hello " + in.Name, Id: "12345", Age: 21}, errors.New("user defined error") -} - -``` - - - -- 客户端打印异常和堆栈 - -```go -package main - -import ( - "context" -) - -import ( - "dubbo.apache.org/dubbo-go/v3/common/logger" - "dubbo.apache.org/dubbo-go/v3/config" - _ "dubbo.apache.org/dubbo-go/v3/imports" - - tripleCommon "github.com/dubbogo/triple/pkg/common" -) - -import ( - triplepb "github.com/apache/dubbo-go-samples/api" -) - -var greeterProvider = new(triplepb.GreeterClientImpl) - -func init() { - config.SetConsumerService(greeterProvider) -} - -func main() { - if err := config.Load(); err != nil { - panic(err) - } - - req := triplepb.HelloRequest{ - Name: "laurence", - } - - // 发起调用 - if user, err := greeterProvider.SayHello(context.TODO(), &req); err != nil { - // 打印异常信息,err.Error() 将返回用户定义的 message,即 user defined error - logger.Infof("response result: %v, error = %s", user, err) - - // 打印异常堆栈,需断言为 tripleCommon.TripleError - logger.Infof("error details = %+v", err.(tripleCommon.TripleError).Stacks()) - } -} - -``` - -```text -2021-11-12T18:36:33.730+0800 INFO cmd/client.go:53 response result: , error = user defined error -2021-11-12T18:36:33.730+0800 INFO cmd/client.go:54 error details = [type.googleapis.com/google.rpc.DebugInfo]:{stack_entries:"user defined error -main.(*ErrorResponseProvider).SayHello - /dubbo-go-samples/error/triple/pb/go-server/cmd/error_reponse.go:40 -reflect.Value.call - /usr/local/go/src/reflect/value.go:543 -reflect.Value.Call - /usr/local/go/src/reflect/value.go:339 -dubbo.apache.org/dubbo-go/v3/common/proxy/proxy_factory.(*ProxyInvoker).Invoke - /Users/laurence/go/pkg/mod/dubbo.apache.org/dubbo-go/v3@v3.0.0-rc4-1/common/proxy/proxy_factory/default.go:145 - ... - -``` - -可看到报错信息和堆栈 diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/protocol/exception_response.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/protocol/exception_response.md deleted file mode 100644 index c529481f9428..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/protocol/exception_response.md +++ /dev/null @@ -1,124 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/tutorial/develop/protocol/exception_response/ - - /zh-cn/docs3-v2/golang-sdk/tutorial/develop/protocol/exception_response/ -description: Triple 异常回传 -title: Triple 异常回传 -type: docs -weight: 5 ---- - - - - - - -参考samples [dubbo-go-samples/error](https://github.com/apache/dubbo-go-samples/tree/f7febed9d686cb940ea55d34b5baa567d7574a44/error) - -## 用户异常回传介绍 - -用户可以在 provider 端生成用户定义的异常信息,可以记录异常产生堆栈,triple 协议可保证将用户在客户端获取到异常 message ,并可以查看报错堆栈,便于定位问题。 - -注意返回 error 非 nil 时,框架不负责其他返回值的传递。 - -- 在Triple provider 端返回异常,以 pb 序列化为例: - -```go -package main - -import ( - "context" -) - -import ( - "dubbo.apache.org/dubbo-go/v3/common/logger" - - // 使用可以记录对战信息的异常库,此处以 "github.com/pkg/errors" 为例 - "github.com/pkg/errors" -) - -import ( - triplepb "github.com/apache/dubbo-go-samples/api" -) - - -// 一个实现了 pb 接口的服务提供结构 -type ErrorResponseProvider struct { - triplepb.UnimplementedGreeterServer -} - -// 回传错误的接口 -func (s *ErrorResponseProvider) SayHello(ctx context.Context, in *triplepb.HelloRequest) (*triplepb.User, error) { - logger.Infof("Dubbo3 GreeterProvider get user name = %s\n" + in.Name) - // 返回用户自定义异常 - return &triplepb.User{Name: "Hello " + in.Name, Id: "12345", Age: 21}, errors.New("user defined error") -} - -``` - - - -- 客户端打印异常和堆栈 - -```go -package main - -import ( - "context" -) - -import ( - "dubbo.apache.org/dubbo-go/v3/common/logger" - "dubbo.apache.org/dubbo-go/v3/config" - _ "dubbo.apache.org/dubbo-go/v3/imports" - - tripleCommon "github.com/dubbogo/triple/pkg/common" -) - -import ( - triplepb "github.com/apache/dubbo-go-samples/api" -) - -var greeterProvider = new(triplepb.GreeterClientImpl) - -func init() { - config.SetConsumerService(greeterProvider) -} - -func main() { - if err := config.Load(); err != nil { - panic(err) - } - - req := triplepb.HelloRequest{ - Name: "laurence", - } - - // 发起调用 - if user, err := greeterProvider.SayHello(context.TODO(), &req); err != nil { - // 打印异常信息,err.Error() 将返回用户定义的 message,即 user defined error - logger.Infof("response result: %v, error = %s", user, err) - - // 打印异常堆栈,需断言为 tripleCommon.TripleError - logger.Infof("error details = %+v", err.(tripleCommon.TripleError).Stacks()) - } -} - -``` - -```text -2021-11-12T18:36:33.730+0800 INFO cmd/client.go:53 response result: , error = user defined error -2021-11-12T18:36:33.730+0800 INFO cmd/client.go:54 error details = [type.googleapis.com/google.rpc.DebugInfo]:{stack_entries:"user defined error -main.(*ErrorResponseProvider).SayHello - /dubbo-go-samples/error/triple/pb/go-server/cmd/error_reponse.go:40 -reflect.Value.call - /usr/local/go/src/reflect/value.go:543 -reflect.Value.Call - /usr/local/go/src/reflect/value.go:339 -dubbo.apache.org/dubbo-go/v3/common/proxy/proxy_factory.(*ProxyInvoker).Invoke - /Users/laurence/go/pkg/mod/dubbo.apache.org/dubbo-go/v3@v3.0.0-rc4-1/common/proxy/proxy_factory/default.go:145 - ... - -``` - -可看到报错信息和堆栈 diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/registry/_index.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/registry/_index.md deleted file mode 100644 index b1a2dce372cf..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/registry/_index.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/tutorial/develop/registry/ - - /zh-cn/docs3-v2/golang-sdk/tutorial/develop/registry/ -description: 注册中心 -title: 注册中心 -type: docs -weight: 2 ---- diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/registry/desc.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/registry/desc.md deleted file mode 100644 index be2b06ddcf6c..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/registry/desc.md +++ /dev/null @@ -1,63 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/tutorial/develop/registry/desc/ - - /zh-cn/docs3-v2/golang-sdk/tutorial/develop/registry/desc/ -description: 了解注册中心 -title: 了解注册中心 -type: docs -weight: 1 ---- - - - - - - -## 什么是注册中心 - -所谓的注册中心,可以简单的理解为手机的通讯录。通讯录的目的是方便我们记录朋友、同事、家人等联系方式。一般的存储方式格式都是:姓名--联系方式,当我们需要联系某个人时,打开我们的通讯,找到他的名字,拨打电话。 - -注册中心要做的事情,也是类似的。它记录了服务和服务地址的映射关系。在分布式架构中,服务会注册到这里,当服务需要调用其它服务时,就到这里找到服务的地址,进行调用。 - - -## 为什么需要注册中心 - -随着单体应用拆分,首当面临的第一份挑战就是服务实例的数量较多,并且服务自身对外暴露的访问地址也具有动态性。以及微服务架构的发展,越来越多的设计中采用微服务架构。在微服务中首先需要面对的问题就是不同的服务之间如何进行通信。在单体服务中如果不同的服务之间需要通信,一般就是服务将接口暴露,然后其他的服务通过配置文件记录依赖服务的地址即可。在分布式系统中,这种方案是明显不合适的。分布式系统会变得更加复杂,比如: - -- 新服务上线后,如何被及时发现 -- 服务宕机后,如何及时下线 -- 服务如何有效的水平扩展 -- 服务发现时,如何进行路由 -- 服务异常时,如何进行降级 - -这里问题的解决都依赖于注册中心。 -为了有效的解决这些问题,我们可以把这些问题全部交给注册中心去解决,这样,不同的服务只需要关注自身的业务和设计实现即可。 - - -## dubbo-go支持的注册中心 - -### Nacos -Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service的首字母简称,一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。 - -Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。 - -Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。 Nacos 是构建以“服务”为中心的现代应用架构 (例如微服务范式、云原生范式) 的服务基础设施。 - -官网:https://nacos.io/ - -### Zookeeper -ZooKeeper 是 Apache 软件基金会的一个软件项目,它为大型分布式计算提供开源的分布式配置服务、同步服务和命名注册。 - -ZooKeeper 的架构通过冗余服务实现高可用性。 - -Zookeeper 的设计目标是将那些复杂且容易出错的分布式一致性服务封装起来,构成一个高效可靠的原语集,并以一系列简单易用的接口提供给用户使用。 - -一个典型的分布式数据一致性的解决方案,分布式应用程序可以基于它实现诸如数据发布/订阅、负载均衡、命名服务、分布式协调/通知、集群管理、Master 选举、分布式锁和分布式队列等功能。 - -官网:https://zookeeper.apache.org/ - -### Polaris -北极星是腾讯开源的服务治理平台,致力于解决分布式和微服务架构中的服务管理、流量管理、配置管理、故障容错和可观测性问题,针对不同的技术栈和环境提供服务治理的标准方案和最佳实践。下面介绍北极星的应用场景、功能特性、系统组件和常见问题。 - - -官网:https://polarismesh.cn/ \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/registry/multi_registry.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/registry/multi_registry.md deleted file mode 100644 index 99d28f55117d..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/registry/multi_registry.md +++ /dev/null @@ -1,125 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/tutorial/develop/registry/multi_registry/ - - /zh-cn/docs3-v2/golang-sdk/tutorial/develop/registry/multi_registry/ -description: 多注册中心 -title: 多注册中心 -type: docs -weight: 100 ---- - - - - - - -一个 Dubbo-go 应用可以配置的多个接口维度的注册中心。 - -## 1. 准备工作 - -- dubbo-go cli 工具和依赖工具已安装 -- 创建一个新的 demo 应用 -- 本地启动Nacos、Zookeeper - -## 2. 使用多注册中心 - -修改服务端配置 go-server/conf/dubbogo.yaml, 同时将服务注册在两个注册中心上。 - -```yaml -dubbo: - registries: - zookeeper: # 指定 zookeeper 注册中心 - protocol: zookeeper - address: 127.0.0.1:2181 - nacos: # 指定 nacos 注册中心 - protocol: nacos - address: 127.0.0.1:8848 - protocols: - triple: - name: tri - port: 20000 - provider: - services: - GreeterProvider: - registry-ids: # 同时注册 - - zookeeper - - nacos - interface: "" -``` - -修改客户端配置 go-client/conf/dubbogo.yaml - -```yaml -dubbo: - registries: - nacos: # 指定 nacos 注册中心 - protocol: nacos - address: 127.0.0.1:8848 - zookeeper: # 指定 zookeeper 注册中心 - protocol: zookeeper - address: 127.0.0.1:2181 - consumer: - references: - GreeterClientImpl: - registry-ids: # 从 nacos 注册中心服务发现 - - nacos - protocol: tri - interface: "" - GreeterClientImpl2: - registry-ids: # 从 zookeeeper 注册中心服务发现 - - zookeeper - protocol: tri - interface: "" -``` - -修改客户端代码,再定义一个客户端存根类,名为GreeterClientImpl2: - -```go -var grpcGreeterImpl2 = new(GreeterClientImpl2) - -type GreeterClientImpl2 struct{ - api.GreeterClientImpl -} -``` - -客户端编写调用代码: - -```go -func main() { - config.SetConsumerService(grpcGreeterImpl) - config.SetConsumerService(grpcGreeterImpl2) - if err := config.Load(); err != nil { - panic(err) - } - - logger.Info("start to test dubbo") - req := &api.HelloRequest{ - Name: "laurence", - } - reply, err := grpcGreeterImpl.SayHello(context.Background(), req) - if err != nil { - logger.Error(err) - } - logger.Infof("nacos server response result: %v\n", reply) - - reply, err = grpcGreeterImpl2.SayHello(context.Background(), req) - if err != nil { - logger.Error(err) - } - logger.Infof("zk server response result: %v\n", reply) -} - -``` - - - -## 3. 多注册中心服务发现验证 - -分别启动 go-server/cmd 和 go-client/cmd 查看两条调用成功的日志: - -``` -INFO cmd/client.go:55 nacos server response result: name:"Hello laurence" id:"12345" age:21 - -INFO cmd/client.go:61 zk server response result: name:"Hello laurence" id:"12345" age:21 - -``` \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/registry/nacos-2.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/registry/nacos-2.md deleted file mode 100644 index 90f680f56d22..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/registry/nacos-2.md +++ /dev/null @@ -1,87 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/tutorial/develop/registry/nacos-2/ - - /zh-cn/docs3-v2/golang-sdk/tutorial/develop/registry/nacos-2/ -description: 使用 Nacos 作为注册中心 -title: 使用 Nacos 作为注册中心 -type: docs -weight: 10 ---- - - - - - - -## 1. 准备工作 - -- dubbo-go cli 工具和依赖工具已安装 -- 创建一个新的 demo 应用 -- 启动一个 Nacos 实例,暴露 8848 端口 - -## 2. 配置注册中心 - -修改服务端配置 go-server/conf/dubbogo.yaml - -```yaml -dubbo: - registries: - nacos: # 配置 Nacos 注册中心 - protocol: nacos - address: 127.0.0.1:8848 # 指定 Nacos 地址 - protocols: - triple: - name: tri - port: 20000 - provider: - services: - GreeterProvider: - interface: "" # read from pb -``` - -修改客户端配置 go-client/conf/dubbogo.yaml - -```yaml -dubbo: - registries: - nacos: - protocol: nacos - address: 127.0.0.1:8848 - consumer: - references: - GreeterClientImpl: - protocol: tri - interface: "" # read from pb -``` - - - -## 3. 使用 Nacos 进行服务发现 - -- 启动go-server/cmd,查看日志 - - ```bash - [Nacos Registry] Registry instance with param ... - ``` - - 日志中包含 Nacos 注册信息,将当前服务接口注册在 Nacos。 - - 可登陆控制台 http://localhost:8848/nacos 查看注册的服务 - -- 启动 go-client/cmd 查看日志 - - ``` - [Nacos Registry] Update begin, service event: ServiceEvent{Action{add}, Path{tri://xxx.xxx.xxx.xxx:20000/api.Greeter ... - ``` - - 日志中包含 Nacos 注册组件的订阅事件信息,获取到服务端 IP 和端口号,显示调用成功。 - - ``` - client response result: name:"Hello laurence" id:"12345" age:21 - ``` - - - -## 4. 更多支持的注册中心 - -参考 [dubbo-go-samples/registry](https://github.com/apache/dubbo-go-samples/tree/f7febed9d686cb940ea55d34b5baa567d7574a44/registry) diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/registry/nacos.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/registry/nacos.md deleted file mode 100644 index 7de9542ef839..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/registry/nacos.md +++ /dev/null @@ -1,150 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/tutorial/develop/registry/nacos/ - - /zh-cn/docs3-v2/golang-sdk/tutorial/develop/registry/nacos/ -description: 使用 Nacos 作为注册中心 -title: 使用 Nacos 作为注册中心 -type: docs -weight: 10 ---- - - - - - - -## 1. 准备工作 - -- dubbo-go cli 工具和依赖工具已安装 -- 创建一个新的 demo 应用 - -## 2. 使用 grpc_cli 工具进行 Dubbo 服务调试 - -### 2.1 开启服务端 -示例:user.go: -```go -func (u *UserProvider) GetUser(ctx context.Context, userStruct *CallUserStruct) (*User, error) { - fmt.Printf("=======================\nreq:%#v\n", userStruct) - rsp := User{"A002", "Alex Stocks", 18, userStruct.SubInfo} - fmt.Printf("=======================\nrsp:%#v\n", rsp) - return &rsp, nil -} - -``` -服务端开启一个服务,名为GetUser,传入一个CallUserStruct的参数,返回一个User参数\ -CallUserStruct参数定义: -```go -type CallUserStruct struct { - ID string - Male bool - SubInfo SubInfo // 嵌套子结构 -} -func (cs CallUserStruct) JavaClassName() string { - return "com.ikurento.user.CallUserStruct" -} - -type SubInfo struct { - SubID string - SubMale bool - SubAge int -} - -func (s SubInfo) JavaClassName() string { - return "com.ikurento.user.SubInfo" -} - -``` -User结构定义: -```go -type User struct { - Id string - Name string - Age int32 - SubInfo SubInfo // 嵌套上述子结构SubInfo -} - -func (u *User) JavaClassName() string { - return "com.ikurento.user.User" -} -``` - -开启服务: - -`cd server `\ -`source builddev.sh`\ -`go run .` - -### 2.2 定义请求体(打解包协议) - -请求体定义为json文件,约定键值均为string\ -键对应go语言struct字段名例如"ID"、"Name" ,值对应"type@val"\ -其中type支持string int bool time,val使用string 来初始化,如果只填写type则初始化为零值。 -约定每个struct必须有JavaClassName字段,务必与server端严格对应 - -见userCall.json: -```json -{ - "ID": "string@A000", - "Male": "bool@true", - "SubInfo": { - "SubID": "string@A001", - "SubMale": "bool@false", - "SubAge": "int@18", - "JavaClassName":"string@com.ikurento.user.SubInfo" - }, - "JavaClassName": "string@com.ikurento.user.CallUserStruct" -} -``` -userCall.json将参数CallUserStruct的结构及子结构SubInfo都定义了出来,并且给请求参数赋值。 - -user.json 同理,作为返回值不需要赋初始值,但JavaClassName字段一定与server端严格对应 -```go -{ - "ID": "string", - "Name": "string", - "Age": "int", - "JavaClassName": "string@com.ikurento.user.User", - "SubInfo": { - "SubID": "string", - "SubMale": "bool", - "SubAge": "int", - "JavaClassName":"string@com.ikurento.user.SubInfo" - } -} -``` - -### 2.3 执行请求 -`dubbogo-cli call --h=localhost --p 20001 --proto=dubbo --i=com.ikurento.user.UserProvider --method=GetUser --sendObj="./userCall.json" --recvObj="./user.json"` - -cli端打印结果: -```log -2020/10/26 20:47:45 Created pkg: -2020/10/26 20:47:45 &{ID:A000 Male:true SubInfo:0xc00006ea20 JavaClassName:com.ikurento.user.CallUserStruct} -2020/10/26 20:47:45 SubInfo: -2020/10/26 20:47:45 &{SubID:A001 SubMale:false SubAge:18 JavaClassName:com.ikurento.user.SubInfo} - - -2020/10/26 20:47:45 Created pkg: -2020/10/26 20:47:45 &{ID: Name: Age:0 JavaClassName:com.ikurento.user.User SubInfo:0xc00006ec90} -2020/10/26 20:47:45 SubInfo: -2020/10/26 20:47:45 &{SubID: SubMale:false SubAge:0 JavaClassName:com.ikurento.user.SubInfo} - - -2020/10/26 20:47:45 connected to localhost:20001! -2020/10/26 20:47:45 try calling interface:com.ikurento.user.UserProvider.GetUser -2020/10/26 20:47:45 with protocol:dubbo - -2020/10/26 20:47:45 After 3ms , Got Rsp: -2020/10/26 20:47:45 &{ID:A002 Name:Alex Stocks Age:18 JavaClassName: SubInfo:0xc0001241b0} -2020/10/26 20:47:45 SubInfo: -2020/10/26 20:47:45 &{SubID:A001 SubMale:false SubAge:18 JavaClassName:}``` -``` -可看到详细的请求体赋值情况,以及返回结果和耗时。支持嵌套结构 - -server端打印结果 -``` -======================= -req:&main.CallUserStruct{ID:"A000", Male:true, SubInfo:main.SubInfo{SubID:"A001", SubMale:false, SubAge:18}} -======================= -``` -可见接收到了来自cli的数据 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/registry/polaris.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/registry/polaris.md deleted file mode 100644 index 783fdf40bf0c..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/registry/polaris.md +++ /dev/null @@ -1,75 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/tutorial/develop/registry/polaris/ - - /zh-cn/docs3-v2/golang-sdk/tutorial/develop/registry/polaris/ -description: 使用 Polaris 作为注册中心 -title: 使用 Polaris 作为注册中心 -type: docs -weight: 12 ---- - - - - - - - -## 1.准备工作 - -- 假设您已经准备好demo工程,如果不清楚,可以参考前面的文章 -- 北极星服务端安装 - - [北极星服务端单机版本安装文档](https://polarismesh.cn/docs/%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97/%E6%9C%8D%E5%8A%A1%E7%AB%AF%E5%AE%89%E8%A3%85/%E5%8D%95%E6%9C%BA%E7%89%88%E5%AE%89%E8%A3%85/) - - [北极星服务端集群版本安装文档](https://polarismesh.cn/docs/%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97/%E6%9C%8D%E5%8A%A1%E7%AB%AF%E5%AE%89%E8%A3%85/%E9%9B%86%E7%BE%A4%E7%89%88%E5%AE%89%E8%A3%85/) - -## 2.使用Polaris作为注册中心 - -### 2.1dubbogo.yaml 配置文件 - -当前 PolarisMesh 已实现了 dubbogo 的注册发现扩展点,因此你只需要调整你的 dubbogo.yaml 文件中的 registries 配置项,新增 protocol 为 polaris 的注册中心配置即可,可以参考下面的样例。 - -```yaml -dubbo: - registries: - polarisMesh: - protocol: polaris - address: ${北极星服务端IP}:8091 - namespace: ${北极星命名空间信息} - token: ${北极星资源鉴权 token} # 如果北极星服务端开启了针对客户端的鉴权,则需要配置该参数 -``` - -### 2.2运行服务提供者 - -进入 go-server 的 cmd 目录,执行以下命令 - -``` - export DUBBO_GO_CONFIG_PATH="../conf/dubbogo.yml" - go run . -``` - -当看到以下日志时即表示 server 端启动成功 - -```log -INFO dubbo/dubbo_protocol.go:84 [DUBBO Protocol] Export service: -``` - - -### 2.3运行服务调用者 - -进入 go-client 的 cmd 目录,执行以下命令 - - -``` - export DUBBO_GO_CONFIG_PATH="../conf/dubbogo.yml" - go run . -``` - -当看到以下日志时即表示 go-client 成功发现 go-server 并发起了 RPC 调用 - -```log -INFO cmd/main.go:75 response: &{A001 Alex Stocks 18 2022-11-19 12:52:38.092 +0800 CST} -``` - -## 3.使用Polaris作为注册中心 -相关源码:[示例源码](https://github.com/apache/dubbo-go-samples/tree/f7febed9d686cb940ea55d34b5baa567d7574a44/polaris/registry) diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/registry/registry.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/registry/registry.md deleted file mode 100644 index ba9d442eecd6..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/registry/registry.md +++ /dev/null @@ -1,118 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/tutorial/develop/registry/registry/ - - /zh-cn/docs3-v2/golang-sdk/tutorial/develop/registry/registry/ -description: 注册中心配置 -title: 注册中心配置 -type: docs -weight: 4 ---- - - - - - - -参考samples [dubbo-go-samples/registry](https://github.com/apache/dubbo-go-samples/tree/f7febed9d686cb940ea55d34b5baa567d7574a44/registry) - -## Registry 注册中心配置 - -- **Nacos 注册中心** - -```yaml -dubbo: - application: # 应用信息,服务启动后会将相关信息注册到注册中心,可被客户端从 url 中识别 - name: myApp # application=myApp; name=myApp - module: opensource # module=opensource - organization: dubbo # organization=dubbo - owner: laurence # owner=laurence - version: myversion # app.version=myversion - environment: pro # environment=pro - registries: - nacosWithCustomGroup: - protocol: nacos # 注册中心选择 nacos - address: 127.0.0.1:8848 # nacos ip - group: myGroup # nacos group, 默认 DEFAULT_GROUP - namespace: 9fb00abb-278d-42fc-96bf-e0151601e4a1 # nacos namespaceID, should be created before. 默认public - username: abc - password: abc - protocols: - dubbo: - name: dubbo - port: 20000 - provider: - services: - UserProviderWithCustomGroupAndVersion: # 接口三元组:接口名、版本号、分组。client 和 server 需要保持一致。 - interface: org.apache.dubbo.UserProvider.Test # 接口名必填 - version: myInterfaceVersion # 默认为空 - group: myInterfaceGroup # 默认为空 -``` - -dubbogo 的注册中心配置的 group、namespace、username、password,均与 nacos 相关概念对应。 - -- **Zookeeper 注册中心** - -```yaml -dubbo: - # application: 与nacos 一致,不再赘述 - registries: - demoZK: - protocol: zookeeper # 注册中心选择 nacos - address: 127.0.0.1:2181 # zookeeper ip - group: myGroup # nacos group, 默认 dubbo - protocols: - triple: - name: tri - port: 20000 - provider: - services: - UserProviderWithCustomGroupAndVersion: # 接口三元组:接口名、版本号、分组。client 和 server 需要保持一致。 - interface: com.apache.dubbo.sample.basic.IGreeter # 接口名必填 - version: myInterfaceVersion # 默认为空 - group: myInterfaceGroup # 默认为空 -``` - -zookeeper 注册时,provider 端将接口信息注册在` /$(group)/$(interface)/providers` 节点,以上面配置为例,注册的 zk path 为 `/myGroup/com.apache.dubbo.sample.basic.IGreeter/providers/` - -consumer 端注册在 /$(group)/$(interface)/consumers 作统计用。 - -- **ETCD 注册中心** - -```yaml -dubbo: - registries: - etcd: - protocol: etcdv3 - timeout: 3s - address: 127.0.0.1:2379 - protocols: - dubbo: - name: dubbo - port: 20000 - provider: - services: - UserProvider: - interface: org.apache.dubbo.UserProvider -``` - -- **应用级服务注册发现** - -```yaml -dubbo: - registries: - demoZK: - protocol: zookeeper # nacos/zookeeper - address: 127.0.0.1:2181 - registry-type: service # 使用应用级服务发现 - metadata-report: # 配置元数据中心 - protocol: zookeeper - address: 127.0.0.1:2181 - protocols: - triple: - name: tri - port: 20000 - provider: - services: - GreeterProvider: - interface: com.apache.dubbo.sample.basic.IGreeter -``` diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/registry/service-discovery.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/registry/service-discovery.md deleted file mode 100644 index 384167cfa384..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/registry/service-discovery.md +++ /dev/null @@ -1,65 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/tutorial/develop/registry/service-discovery/ - - /zh-cn/docs3-v2/golang-sdk/tutorial/develop/registry/service-discovery/ -description: 应用级服务发现 -title: 应用级服务发现 -type: docs -weight: 2 ---- - - - - - - -参考文章[**《Dubbo 迈出云原生重要一步 应用级服务发现解析》**](https://baijiahao.baidu.com/s?id=1669266413887039723&wfr=spider&for=pc) - -参考仓库:[dubbo-go-samples/registry/serivcediscovery](https://github.com/apache/dubbo-go-samples/tree/45a0d843b54e4922c240900e63516176cc7da4f6/registry/servicediscovery) - -## 配置方案 - -- Consumer 端 - -```yaml -dubbo: - registries: - demoZK: - protocol: nacos - address: 127.0.0.1:8848 - registry-type: service # 指定该注册中心为应用级服务发现,不填默认为接口级 - metadata-report: # 定义元数据中心 - protocol: nacos # 元数据中心可选nacos/zk - address: 127.0.0.1:8848 - consumer: - references: - GreeterClientImpl: - protocol: tri - interface: com.apache.dubbo.sample.basic.IGreeter -``` - - - -- Provider 端 - -```yaml -dubbo: - registries: - demoZK: - protocol: nacos - address: 127.0.0.1:8848 - registry-type: service # 指定该注册中心为应用级服务发现,不填默认为接口级 - metadata-report: # 定义元数据中心 - protocol: nacos # 元数据中心可选nacos/zk - address: 127.0.0.1:8848 - protocols: - triple: - name: tri - port: 20000 - provider: - services: - GreeterProvider: - interface: com.apache.dubbo.sample.basic.IGreeter -``` - -相比于常规配置,定义好registry-type: service, 并且定义好元数据中心后,将会使用应用级服务注册/服务发现。 diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/registry/zookeeper.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/registry/zookeeper.md deleted file mode 100644 index 7ec85fbd2771..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/registry/zookeeper.md +++ /dev/null @@ -1,111 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/tutorial/develop/registry/zookeeper/ - - /zh-cn/docs3-v2/golang-sdk/tutorial/develop/registry/zookeeper/ -description: 使用 Zookeeper 作为注册中心 -title: 使用 Zookeeper 作为注册中心 -type: docs -weight: 11 ---- - - - - - - - -## 1. 准备工作 - -- dubbo-go cli 工具和依赖工具已安装 -- 创建一个新的 demo 应用 -- 准备 Zookeeper 实例 - -## 2. 配置注册中心 - -修改服务端配置 go-server/conf/dubbogo.yaml - -```yaml -dubbo: - registries: - demoZK: - protocol: zookeeper - timeout: 3s - address: 127.0.0.1:2181 - group: myGroup # default is dubbo - registry-type: interface - protocols: - triple: - name: tri - port: 20000 - provider: - services: - GreeterProvider: - interface: com.apache.dubbo.sample.basic.IGreeter # must be compatible with grpc or dubbo-java - UserProviderWithCustomGroupAndVersion: - interface: com.apache.dubbo.sample.basic.IGreeter2 - version: myInterfaceVersion # dubbo interface version must be same with client - group: myInterfaceGroup # dubbo interface group must be same with client -``` - -修改客户端配置 go-client/conf/dubbogo.yaml - -```yaml -dubbo: - registries: - demoZK: - protocol: zookeeper - timeout: 3s - address: 127.0.0.1:2181 - group: myGroup - registry-type: interface - consumer: - references: - GreeterClientImpl: - protocol: tri - interface: com.apache.dubbo.sample.basic.IGreeter # must be compatible with grpc or dubbo-java - UserProviderWithCustomGroupAndVersion: - protocol: tri - interface: com.apache.dubbo.sample.basic.IGreeter2 # must be compatible with grpc or dubbo-java - group: myInterfaceGroup # dubbo interface group must be same with server - version: myInterfaceVersion # dubbo interface version must be same with server -``` - - - -## 3. 使用 Zookeeper 进行服务发现 - -- 启动go-server/cmd,查看日志 - - ```bash - INFO zookeeper/registry.go:217 [Zookeeper Registry] Registry instance with root = /myGroup/com.apache.dubbo.sample.basic.IGreeter/providers - ``` - - 日志中包含 Zookeeper 注册信息,将当前服务接口注册在 Zookeeper - - -- 启动 go-client/cmd 查看日志 - - - 日志中包含 Zookeeper 注册组件的订阅事件信息,获取到服务端 IP 和端口号,显示调用成功。 - - ``` - zookeeper/registry.go:217 [Zookeeper Registry] Registry instance with root = /myGroup/com.apache.dubbo.sample.basic.IGreeter/consumers, node = consumer%3A%2F%2F172.22.91.1%2Fcom.apache.dubbo.sample.basic.IGreeter%3Fapp.version%3D%26application%3Ddubbo.io%26async%3Dfalse%26bean.name%3DGreeterClientImpl%26cluster%3Dfailover%26config.tracing%3D%26environment%3D%26generic%3D%26group%3D%26interface%3Dcom.apache.dubbo.sample.basic.IGreeter%26loadbalance%3D%26metadata-type%3Dlocal%26module%3Dsample%26name%3Ddubbo.io%26organization%3Ddubbo-go%26owner%3Ddubbo-go%26protocol%3Dtri%26provided-by%3D%26reference.filter%3Dcshutdown%26registry.role%3D0%26release%3Ddubbo-golang-3.0.4%26retries%3D%26serialization%3D%26side%3Dconsumer%26sticky%3Dfalse%26timestamp%3D1675407574%26version%3D - - - cmd/client.go:54 start to test dubbo - cmd/client.go:62 client response result: name:"Hello laurence" id:"12345" age:21 - cmd/client.go:68 client response result: name:"Hello laurence from UserProviderWithCustomRegistryGroupAndVersion" id:"12345" age:21 - ``` - -- 同时,我们可以直接查看zk中的数据如下: - - ```bash - [zk: localhost:2181(CONNECTED) 6] ls / - [zookeeper, myGroup] - [zk: localhost:2181(CONNECTED) 7] ls /myGroup - [com.apache.dubbo.sample.basic.IGreeter2, com.apache.dubbo.sample.basic.IGreeter] - ``` - -## 4. 更多支持的注册中心 - -参考 [dubbo-go-samples/registry](https://github.com/apache/dubbo-go-samples/tree/f7febed9d686cb940ea55d34b5baa567d7574a44/registry) diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/template.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/template.md deleted file mode 100644 index 554dc3008a3e..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/develop/template.md +++ /dev/null @@ -1,96 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/tutorial/develop/template/ - - /zh-cn/docs3-v2/golang-sdk/tutorial/develop/template/ -description: 应用模板 -title: 应用模板 -type: docs -weight: 1 ---- - - - - - - - -## 1. 准备工作 - -- dubbo-go cli 工具和依赖工具已安装 - -## 2. 使用 dubbogo-cli 创建项目模板 - -运行 `dubbogo-cli newApp .` - -```plain -$ mkdir cli-create-server -$ cd cli-create-server -$ dubbogo-cli newApp . -$ tree . -. -├── Makefile -├── api -│ └── api.proto -├── build -│ └── Dockerfile -├── chart -│ ├── app -│ │ ├── Chart.yaml -│ │ ├── templates -│ │ │ ├── _helpers.tpl -│ │ │ ├── deployment.yaml -│ │ │ ├── service.yaml -│ │ │ └── serviceaccount.yaml -│ │ └── values.yaml -│ └── nacos_env -│ ├── Chart.yaml -│ ├── templates -│ │ ├── _helpers.tpl -│ │ ├── deployment.yaml -│ │ └── service.yaml -│ └── values.yaml -├── cmd -│ └── app.go -├── conf -│ └── dubbogo.yaml -├── go.mod -├── go.sum -└── pkg - └── service - └── service.go -``` - -生成项目包括几个目录: - -- api:放置接口文件:proto文件和生成的pb.go文件 - -- build:放置构建相关文件 - -- chart:放置发布用 chart 包、基础环境 chart 包:nacos、mesh(开发中) - -- cmd:程序入口 - -- conf:框架配置 - -- pkg/service:RPC 服务实现 - -- Makefile: - - - 镜像、应用名: - - - IMAGE = $(your_repo)/$(namespace)/$(image_name) - TAG = 1.0.0 - - - APPNAME = dubbo-go-app # 用于 helm 发布,对应 chart 名、应用名和服务名(service名) - - - 提供脚本,例如: - - - make build # 打包镜像并推送 - - - make buildx-publish # arm 架构本地打包amd64镜像并推送,依赖 docker buildx - - - make deploy # 通过 helm 发布应用 - - - make remove # 删除已经发布的 helm 应用 - - - make proto-gen # api/ 下生成 pb.go 文件 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/gateway/_index.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/gateway/_index.md new file mode 100755 index 000000000000..9f9030beab91 --- /dev/null +++ b/content/zh-cn/overview/mannual/golang-sdk/tutorial/gateway/_index.md @@ -0,0 +1,7 @@ +--- +description: "通过 Higress、APISIX 等网关产品解决前端 http 流量接入后端 RPC 微服务问题。" +linkTitle: HTTP网关接入 +title: HTTP流量接入 +type: docs +weight: 61 +--- diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/service-mesh/pixiu/http_triple.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/gateway/http_triple.md similarity index 100% rename from content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/service-mesh/pixiu/http_triple.md rename to content/zh-cn/overview/mannual/golang-sdk/tutorial/gateway/http_triple.md diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/service-mesh/pixiu/pixiu-nacos-triple.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/gateway/pixiu-nacos-triple.md similarity index 100% rename from content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/service-mesh/pixiu/pixiu-nacos-triple.md rename to content/zh-cn/overview/mannual/golang-sdk/tutorial/gateway/pixiu-nacos-triple.md diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/_index.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/_index.md deleted file mode 100755 index 47721ff0418d..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/_index.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/tutorial/governance/ - - /zh-cn/docs3-v2/golang-sdk/tutorial/governance/ -description: Dubbo-go 服务治理 -title: 服务治理 -type: docs -weight: 4 ---- diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/features/_index.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/features/_index.md deleted file mode 100644 index 7d7a441ecde3..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/features/_index.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/tutorial/governance/features/ - - /zh-cn/docs3-v2/golang-sdk/tutorial/governance/features/ -description: 高级特性 -title: 高级特性 -type: docs -weight: 6 ---- diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/features/aop.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/features/aop.md deleted file mode 100644 index 577a65d0930f..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/features/aop.md +++ /dev/null @@ -1,73 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/tutorial/governance/features/aop/ - - /zh-cn/docs3-v2/golang-sdk/tutorial/governance/features/aop/ -description: 自定义服务调用中间件 -title: 自定义服务调用中间件 -type: docs -weight: 1 ---- - - - - - - -参考samples [dubbo-go-samples/filter](https://github.com/apache/dubbo-go-samples/tree/f7febed9d686cb940ea55d34b5baa567d7574a44/filter) - -## 1. 准备工作 - -- dubbo-go cli 工具和依赖工具已安装 -- 阅读[【组件加载与可扩展性】](/zh-cn/overview/mannual/golang-sdk/preface/design/aop_and_extension/) -- 创建一个新的 demo 应用 - -## 2. 配置指定 Filter - -指定filter时可用','分隔 - -- Consumer 端 - - ```yaml - dubbo: - consumer: - filter: echo,token,tps,myCustomFilter # 可指定自定义filter - ``` - - - -- Provider 端 - - ```yaml - dubbo: - provider: - services: - GreeterProvider: - filter: myCustomFilter,echo,tps - ``` - -## 3. 自定义Filter - -用户可在代码中自定义 Filter,注册到框架上,并在配置中选择使用。 - -```go -func init() { - extension.SetFilter("myCustomFilter", NewMyClientFilter) -} - -func NewMyClientFilter() filter.Filter { - return &MyClientFilter{} -} - -type MyClientFilter struct { -} - -func (f *MyClientFilter) Invoke(ctx context.Context, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result { - fmt.Println("MyClientFilter Invoke is called, method Name = ", invocation.MethodName()) - return invoker.Invoke(ctx, invocation) -} -func (f *MyClientFilter) OnResponse(ctx context.Context, result protocol.Result, invoker protocol.Invoker, protocol protocol.Invocation) protocol.Result { - fmt.Println("MyClientFilter OnResponse is called") - return result -} - -``` diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/features/custom-filter.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/features/custom-filter.md deleted file mode 100644 index 92a607ae7bd1..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/features/custom-filter.md +++ /dev/null @@ -1,115 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/tutorial/governance/features/custom-filter/ - - /zh-cn/docs3-v2/golang-sdk/tutorial/governance/features/custom-filter/ -description: 自定义Filter组件 -title: 自定义Filter组件 -type: docs -weight: 3 ---- - - - - - - -参考samples [dubbo-go-samples/filter](https://github.com/apache/dubbo-go-samples/tree/f7febed9d686cb940ea55d34b5baa567d7574a44/filter) - -## 1. Filter 概念 - -```go -// Filter interface defines the functions of a filter -// Extension - Filter -type Filter interface { - // Invoke is the core function of a filter, it determines the process of the filter - Invoke(context.Context, protocol.Invoker, protocol.Invocation) protocol.Result - // OnResponse updates the results from Invoke and then returns the modified results. - OnResponse(context.Context, protocol.Result, protocol.Invoker, protocol.Invocation) protocol.Result -} -``` - -Filter 可以加载在 Consumer 端或者 Provider端。当加载在 Consumer 端,其Invoke函数调用的下游为网络层,OnResponse 为请求结束从网络层获取到返回结果后被调用。当加载在 Provider 端,其 Invoke 函数调用的下游为用户代码,OnResponse 为用户代码执行结束后向下传递至网络层前被调用。 - -Filter 采用面向切面设计的思路,通过对 Filter 的合理扩展,可以记录日志、设置数据打点,记录 invoker 所对应服务端性能,限流等等工作。 - -## 2. 框架预定义 Filter - -框架预定义了一系列filter,可以在配置中直接使用,其代码实现位于[filter](https://github.com/apache/dubbo-go/tree/release-3.0/filter) - -- accesslog -- active -- sign: AuthConsumerFilter -- auth: AuthProviderFilter -- echo -- execute: ExecuteLimitFilter -- generic: GenericFilter -- generic_service: GenericServiceFilter -- pshutdown: GracefulShutdownProviderFilter -- cshutdown: GracefulShutdownConsumerFilter -- hystrix_consumer: HystrixConsumerFilter -- hystrix_provider: HystrixProviderFilter -- metrics -- seata -- sentinel-provider -- sentinel-consumer -- token -- tps -- tracing - -## 3. 默认加载Filter - -用户在配置文件中配置了将要使用的 Filters 时,框架使用用户配置的 Filters 和默认 Filters,否则仅加载默认 Filters: - -- Consumer: cshutdown -- Provider: echo, metrics, token, accesslog, tps, generic_service, executivete, pshutdown - -## 4. 用户指定 Filter - -指定filter时可用','分隔 - -- Consumer 端 - - ```yaml - dubbo: - consumer: - filter: echo,token,tps,myCustomFilter # 可指定自定义filter - ``` - - - -- Provider 端 - - ```yaml - dubbo: - provider: - services: - GreeterProvider: - filter: myCustomFilter,echo,tps - ``` - -## 5. 自定义Filter - -用户可在代码中自定义 Filter,注册到框架上,并在配置中选择使用。 - -```go -func init() { - extension.SetFilter("myCustomFilter", NewMyClientFilter) -} - -func NewMyClientFilter() filter.Filter { - return &MyClientFilter{} -} - -type MyClientFilter struct { -} - -func (f *MyClientFilter) Invoke(ctx context.Context, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result { - fmt.Println("MyClientFilter Invoke is called, method Name = ", invocation.MethodName()) - return invoker.Invoke(ctx, invocation) -} -func (f *MyClientFilter) OnResponse(ctx context.Context, result protocol.Result, invoker protocol.Invoker, protocol protocol.Invocation) protocol.Result { - fmt.Println("MyClientFilter OnResponse is called") - return result -} - -``` diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/features/timeout.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/features/timeout.md deleted file mode 100644 index d42888d14283..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/features/timeout.md +++ /dev/null @@ -1,66 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/tutorial/governance/features/timeout/ - - /zh-cn/docs3-v2/golang-sdk/tutorial/governance/features/timeout/ -description: 配置调用的超时 -title: 配置调用的超时 -type: docs -weight: 1 ---- - - - - - - -## 1. 准备工作 - -- dubbo-go cli 工具和依赖工具已安装 -- 创建一个新的 demo 应用 - -## 2. 通过配置项修改 RPC 调用相关参数 - -### 2.1 修改调用的超时,并验证 - -```yaml -dubbo: - consumer: - request-timeout: 15s # 配置客户端超时 -``` - -Dubbo-go 应用默认 RPC 超时为 3s,请求超时后,客户端将会返回error 为 context deadline exceeded 的错误。在本任务中,您需要首先修改 demo 应用的 server 函数为较长耗时,然后查看客户端的超时报错;再通过配置客户端超时,使得耗时函数可以正常调用。 - -1. go-server/cmd/server.go: 修改 demo 应用 server 的函数为耗时 10s 的函数 - - ```go - func (s *GreeterProvider) SayHello(ctx context.Context, in *api.HelloRequest) (*api.User, error) { - logger.Infof("Dubbo3 GreeterProvider get user name = %s\n", in.Name) - time.Sleep(time.Second*10) // sleep 10s - return &api.User{Name: "Hello " + in.Name, Id: "12345", Age: 21}, nil - } - ``` - -2. 客户端发起调用,观察错误日志 - - ``` - ERROR cmd/client.go:47 context deadline exceeded - ``` - -3. go-client/conf/dubbogo.yaml: 客户端修改超时 - - ```yaml - dubbo: - consumer: - request-timeout: 15s # 配置客户端超时 - references: - GreeterClientImpl: - protocol: tri - url: "tri://localhost:20000" - interface: "" # read from pb - ``` - -4. 再次通过客户端发起调用,观察日志,正常返回: - - ```bash - client response result: name:"Hello laurence" id:"12345" age:21 - ``` \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/health/_index.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/health/_index.md deleted file mode 100644 index 00f389dfecb7..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/health/_index.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/tutorial/governance/health/ - - /zh-cn/docs3-v2/golang-sdk/tutorial/governance/health/ -description: 健康检查 -title: 健康检查 -type: docs -weight: 3 ---- diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/health/kubernetes.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/health/kubernetes.md deleted file mode 100644 index cb59e4f1b1b4..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/health/kubernetes.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/tutorial/governance/health/kubernetes/ - - /zh-cn/docs3-v2/golang-sdk/tutorial/governance/health/kubernetes/ -description: Kubernetes 探针 -title: Kubernetes 探针 -type: docs -weight: 4 ---- diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/health/start-check.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/health/start-check.md deleted file mode 100644 index a0f4c3c61c79..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/health/start-check.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/tutorial/governance/health/start-check/ - - /zh-cn/docs3-v2/golang-sdk/tutorial/governance/health/start-check/ -description: dubbogo 3.0 启动时检查 -keywords: dubbogo 3.0 启动时检查 -title: dubbogo 3.0 启动时检查 -type: docs -weight: 4 ---- - - - - - - -# 启动时检查 - -在启动时检查依赖的服务是否可用 - -Dubbo-go 缺省会在启动时检查依赖的服务是否可用,不可用时会抛出异常,阻止应用初始化完成,以便上线时,能及早发现问题,默认 check="true",并等待3s。 - -可以通过 check="false" 关闭检查,比如,测试时,有些服务不关心,或者出现了循环依赖,必须有一方先启动。 - -关闭 check 后,请注意 provider数量比较多时, consumer 订阅 provider 生成服务字典可能会有一定延迟,如果 consumer 一启动就对外提供服务, -可能会造成"冷启动"。所以在这个时候,请对服务进行预热。 - -示例: - -```yaml -dubbo: - consumer: - check : false - reference: - myserivce: - check: true -``` \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/health/triple-health-check.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/health/triple-health-check.md deleted file mode 100644 index c5e69ad97e6e..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/health/triple-health-check.md +++ /dev/null @@ -1,114 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/tutorial/governance/health/triple-health-check/ - - /zh-cn/docs3-v2/golang-sdk/tutorial/governance/health/triple-health-check/ -description: 基于Grpc的健康检查 -title: 基于Grpc的健康检查 -type: docs -weight: 2 ---- - - - - - - -## 1. Grpc健康检查 - -Grpc健康检查是通过一个普通的用户rpc调用进行实现,Grpc的健康检查定义了如下的protobuf,这样就能实现所有的Grpc协议健康检查的互通。 - -> Firstly, since it is a GRPC service itself, doing a health check is in the same format as a normal rpc. Secondly, it has rich semantics such as per-service health status. Thirdly, as a GRPC service, it is able reuse all the existing billing, quota infrastructure, etc, and thus the server has full control over the access of the health checking service. - -``` protobuf -syntax = "proto3"; - -package grpc.health.v1; - -message HealthCheckRequest { - string service = 1; -} - -message HealthCheckResponse { - enum ServingStatus { - UNKNOWN = 0; - SERVING = 1; - NOT_SERVING = 2; - SERVICE_UNKNOWN = 3; // Used only by the Watch method. - } - ServingStatus status = 1; -} - -service Health { - rpc Check(HealthCheckRequest) returns (HealthCheckResponse); - - rpc Watch(HealthCheckRequest) returns (stream HealthCheckResponse); -} -``` - -## 2 triple健康检查服务 - -+ Dubbo-go框架在启动后会自动向框架中注册健康检查服务,提供基于grpc health proto的健康检查服务,无需在配置文件中额外配置。 -+ triple健康检查服务可以通过grpc-health-probe检查框架中服务的状态,也可以通过grpc调用该健康检查服务,但是不能通过triple客户端调用该健康检查服务(基于grpc的健康检查服务不通过注册中心注册),调用的服务名为“grpc.health.v1.Health”,接口为check。 - -### 2.1 通过gprc客户端调用健康检查服务: - -+ 启动dubbo-go-samples中的[triple服务](https://github.com/apache/dubbo-go-samples/tree/f7febed9d686cb940ea55d34b5baa567d7574a44/rpc/triple/pb/dubbogo-grpc/go-server),通过下面的grpc客户端便可以查看"org.apache.dubbogo.samples.api.Greeter"的状态。triple健康检查服务与grpc互通,所以可以通过grpc客户端查看基于triple协议服务的健康状态。 - -``` go -package main - -import ( - "context" - "fmt" - "log" -) - -import ( - "google.golang.org/grpc" - "google.golang.org/grpc/credentials/insecure" - healthpb "google.golang.org/grpc/health/grpc_health_v1" -) - -const ( - address = "localhost:20000" -) - -func main() { - // Set up a connection to the server - conn, err := grpc.Dial(address, grpc.WithTransportCredentials(insecure.NewCredentials())) - if err != nil { - log.Fatalf("did not connect: %v", err) - } - - defer func() { - _ = conn.Close() - }() - - checkHealth("org.apache.dubbogo.samples.api.Greeter", conn) -} - -func checkHealth(service string, conn *grpc.ClientConn) { - fmt.Printf(">>>>> gRPC-go check %s status", service) - - req := &healthpb.HealthCheckRequest{ - Service: service, - } - ctx := context.Background() - rsp, err := healthpb.NewHealthClient(conn).Check(ctx, req) - if err != nil { - panic(err) - } - fmt.Printf("get service status = %+v\n", rsp) -} -``` - -### 2.2 grpc-health-probe调试健康检查服务: - -+ 启动dubbo-go-samples中的[triple服务](https://github.com/apache/dubbo-go-samples/tree/f7febed9d686cb940ea55d34b5baa567d7574a44/rpc/triple/pb/dubbogo-grpc/go-server),提供`org.apache.dubbogo.samples.api.Greeter`服务。使用grpc-health-probe检查该服务的健康状态,`grpc-health-probe -addr=localhost:20000 -service "org.apache.dubbogo.samples.api.Greeter"` - -![image-health-check](/imgs/docs3-v2/golang-sdk/tasks/service_management/triple-health-check/health-check.png) - -#### 参考: - -+ https://github.com/grpc/grpc/blob/master/doc/health-checking.md -+ https://github.com/grpc/grpc-go/tree/master/health diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/limit/_index.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/limit/_index.md deleted file mode 100644 index e7fc411534f2..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/limit/_index.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/tutorial/governance/limit/ - - /zh-cn/docs3-v2/golang-sdk/tutorial/governance/limit/ -description: 限流 -title: 限流 -type: docs -weight: 4 ---- diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/limit/adaptive-service.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/limit/adaptive-service.md deleted file mode 100644 index 16b8c9bf2f82..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/limit/adaptive-service.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -title: dubbogo 3.0 柔性服务 -keywords: dubbogo 3.0 柔性服务 -description: dubbogo 3.0 柔性服务 ---- - -# 柔性负载均衡 (柔性服务) - -柔性服务是一种去中心化的智能负载均衡组件,同时也是 Dubbo-go 3.0 版本中重磅新特性之一。柔性服务尚处于早期实验阶段,该特性将在后续版本中持续优化,与 Dubbo 社区共同探索出一套适合微服务场景的最佳实践。 - -传统的负载均衡算法是由随机节点、RoundRobin 等算法实现,他们的局限性在于不知道当前服务提供者的负载情况,算法总是以尽可能公平的概率调用不同的服务提供者。在实践中,公平不等于高性能,集群服务性能还与服务负载、任务复杂度等多因素相关。为解决传统负载均衡算法的不足,Dubbo-go 在 3.0 版本中引入了柔性服务,实现了容量动态评估和分流功能。 - -容量评估是柔性服务的核心,它能动态评估服务端容量水平。在容量评估的过程中,两个核心指标是 TPS 和响应时间,要平衡系统利用率和系统性能两者之间的关系,使整体处于最佳的状态。 - -- TPS 从服务提供者的角度反映系统利用率。在系统压力未饱和前,请求数越大则系统利用率越高,但是进一步加大请求量直至系统过饱和后,出现过载的问题,导致整体效率呈下降趋势。 -- 响应时间是从服务调用者的角度反映系统性能。在系统压力未饱和前,响应时间与请求数成线性增长的关系,但是进一步加大请求量直至系统过饱和后,响应时间与请求数成指数级增长。 - -![img](/imgs/docs3-v2/golang-sdk/samples/adaptive-service/adaptive.png) - - -柔性服务则在调用过程中收集 - -在 Dubbo-go 3.0 版本中,支持服务柔性负载均衡。在微服务场景下,客户端会在调用过程中收集该服务下游 server 实例的硬件资源消耗情况,通过容量评估与筛选策略,选择最合适的下游实例进行调用,从而提升系统整体的性能。 - -服务柔性将在之后的迭代中持续优化,追求与 Dubbo 社区共同探索出最佳实践。 - diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/limit/internally/_index.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/limit/internally/_index.md deleted file mode 100644 index 1ceb360fed34..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/limit/internally/_index.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/tutorial/governance/limit/internally/ - - /zh-cn/docs3-v2/golang-sdk/tutorial/governance/limit/internally/ -description: Dubbo Go 内置的限流使用教程 -title: Dubbo Go 内置的限流使用教程 -type: docs -weight: 1 ---- diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/limit/polaris/_index.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/limit/polaris/_index.md deleted file mode 100644 index 67da04bbc516..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/limit/polaris/_index.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/tutorial/governance/limit/polaris/ - - /zh-cn/docs3-v2/golang-sdk/tutorial/governance/limit/polaris/ -description: 基于 Polaris 的限流教程 -title: 基于 Polaris 的限流教程 -type: docs -weight: 3 ---- diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/limit/sentinel/_index.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/limit/sentinel/_index.md deleted file mode 100644 index 1e1d7ce5c32f..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/limit/sentinel/_index.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/tutorial/governance/limit/sentinel/ - - /zh-cn/docs3-v2/golang-sdk/tutorial/governance/limit/sentinel/ -description: 基于 Sentinel 的限流教程 -title: 基于 Sentinel 的限流教程 -type: docs -weight: 2 ---- diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/limit/tps_limiter.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/limit/tps_limiter.md deleted file mode 100644 index f0f986cc3716..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/limit/tps_limiter.md +++ /dev/null @@ -1,112 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/tutorial/governance/limit/tps_limiter/ - - /zh-cn/docs3-v2/golang-sdk/tutorial/governance/limit/tps_limiter/ -description: 为服务端设置限流 -title: 为服务端设置限流 -type: docs -weight: 3 ---- - - - - - - -## 1. 准备工作 - -- dubbo-go cli 工具和依赖工具已安装 -- 创建一个新的 demo 应用 - -## 2. 修改限流逻辑并验证 - -Dubbo-go 为用户提供了内置的限流拒绝逻辑,并支持用户根据自己的业务场景,定义需要的限流机制、拒绝逻辑。 - -正常情况下,不设置流量限制,当用户在 server 端配置了限流逻辑和参数后,将会 - -### 2.1 配置限流参数 - -go-server/conf/dubbogo.yaml: 配置限流参数 - -```yaml -dubbo: - protocols: - triple: - name: tri - port: 20000 - provider: - services: - GreeterProvider: - interface: "" # read from pb - tps.limiter: "method-service" - tps.limit.strategy: "slidingWindow" - tps.limit.rejected.handler: "default" - tps.limit.interval: 1000 - tps.limit.rate: 3 - -``` - -参数说明: - -- tps.limiter:限流器选择。method-service 为框架内置的一个限流器,可以配置服务和方法级别的限流逻辑,可自定义。 -- tps.limit.strategy:限流策略选择,slidingWindow 为框架内置的一个限流策略,可以按照滑动窗口的形式,拒绝掉窗口内超过流量限制的请求。 -- tps.limit.rejected.handler: 拒绝策略,default 为默认拒绝方式,返回空对象,可自定义 -- tps.limit.interval:限流窗口区间,单位是ms。 -- tps.limit.rate:窗口内流量限制,单位是请求次数。 - -按照上述配置,服务端只允许当前接口在一秒内被调用三次。 - -### 2.2 发起超流请求,验证限流能力 - -将客户端的请求逻辑设置为每秒钟请求五次,并计算成功率。 - -go-client/cmd/client.go - -```go - -func main() { - config.SetConsumerService(grpcGreeterImpl) - if err := config.Load(); err != nil { - panic(err) - } - - logger.Info("start to test dubbo") - req := &api.HelloRequest{ - Name: "laurence", - } - - for { - goodCount := 0 - badCount := 0 - for{ - time.Sleep(time.Millisecond*200) - reply, _ := grpcGreeterImpl.SayHello(context.Background(), req) - if reply.Name == "" { - badCount++ - }else { - goodCount++ - } - if badCount + goodCount ==5{ - break - } - } - logger.Infof("Success rate = %v\n", float64(goodCount)/float64(goodCount + badCount)) - } -} -``` - -可在日志中看到请求成功率为0.6,每秒钟只允许三次请求被执行。 - -```bash -INFO cmd/client.go:62 Success rate = 0.6 - -INFO cmd/client.go:62 Success rate = 0.6 - -INFO cmd/client.go:62 Success rate = 0.6 -``` - -在服务端日志中可以看到拒绝的信息: - -```bash -ERROR tps/filter.go:84 The invocation was rejected due to over the limiter limitation... -``` \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/monitor/_index.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/monitor/_index.md deleted file mode 100644 index 61d6bb05bd68..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/monitor/_index.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/tutorial/governance/monitor/ - - /zh-cn/docs3-v2/golang-sdk/tutorial/governance/monitor/ -description: 服务状态监控 -title: 服务状态监控 -type: docs -weight: 1 ---- diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/monitor/grafana/_index.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/monitor/grafana/_index.md deleted file mode 100644 index 35c395098848..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/monitor/grafana/_index.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/tutorial/governance/monitor/grafana/ - - /zh-cn/docs3-v2/golang-sdk/tutorial/governance/monitor/grafana/ -description: 基于 Grafana 的可视化监控教程 -title: 基于 Grafana 的可视化监控教程 -type: docs -weight: 3 ---- diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/monitor/http/_index.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/monitor/http/_index.md deleted file mode 100644 index ea5b030ef3cf..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/monitor/http/_index.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/tutorial/governance/monitor/http/ - - /zh-cn/docs3-v2/golang-sdk/tutorial/governance/monitor/http/ -description: 基于 http metrics 的指标观测 -title: 基于 http metrics 的指标观测 -type: docs -weight: 1 ---- diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/monitor/logger/_index.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/monitor/logger/_index.md deleted file mode 100644 index 26b6d6502044..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/monitor/logger/_index.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/tutorial/governance/monitor/logger/ - - /zh-cn/docs3-v2/golang-sdk/tutorial/governance/monitor/logger/ -description: Dubbo Go 日志管理 -title: Dubbo Go 日志管理 -type: docs -weight: 4 ---- diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/monitor/metrics.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/monitor/metrics.md deleted file mode 100644 index 7ee6da44f4eb..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/monitor/metrics.md +++ /dev/null @@ -1,214 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/tutorial/governance/monitor/metrics/ - - /zh-cn/docs3-v2/golang-sdk/tutorial/governance/monitor/metrics/ -description: Metrics 数据上报 -title: Metrics 数据上报 -type: docs -weight: 7 ---- - - - - - - -参考Samples: [dubbo-go-samples/metrics](https://github.com/apache/dubbo-go-samples/tree/f7febed9d686cb940ea55d34b5baa567d7574a44/metrics) - -## 1. 数据上报配置 - -在不指定 metrics: 字段的时候,默认开启拉模式 prometheus 数据上报,端口默认为9090,监听path默认为/metrics。可参考如下服务端配置例子来定制化。 - -```yaml -dubbo: - application: - version: 3.0.0-rc3 # 版本号 - metrics: - enable: true # default is true - path: /custom-metrics-path # default is /metrics - port: 9091 # default is 9090 - namespace: dubbo # default is dubbo 作为数据上报 metrics 的前缀 - registries: - myzk: - protocol: zookeeper - address: localhost:2181 - protocols: - triple: - name: tri - port: 20000 - provider: - services: - GreeterProvider: - group: dubbo-go # 所属 group,需要与客户端一致 - interface: com.apache.dubbo.HelloService # 接口名 -``` - -## 2. 默认数据上报指标 - -本地启动上述服务端后,可于 localhost:9091/custom-metrics-path 收集到默认数据指标,包含gc、goroutine数目,内存占用情况等。 - -```yaml -# HELP go_gc_duration_seconds A summary of the pause duration of garbage collection cycles. -# TYPE go_gc_duration_seconds summary -go_gc_duration_seconds{quantile="0"} 3.0916e-05 -go_gc_duration_seconds{quantile="0.25"} 3.0916e-05 -go_gc_duration_seconds{quantile="0.5"} 3.1167e-05 -go_gc_duration_seconds{quantile="0.75"} 0.000164084 -go_gc_duration_seconds{quantile="1"} 0.000164084 -go_gc_duration_seconds_sum 0.000226167 -go_gc_duration_seconds_count 3 -# HELP go_goroutines Number of goroutines that currently exist. -# TYPE go_goroutines gauge -go_goroutines 25 -# HELP go_info Information about the Go environment. -# TYPE go_info gauge -go_info{version="go1.17.2"} 1 -# HELP go_memstats_alloc_bytes Number of bytes allocated and still in use. -# TYPE go_memstats_alloc_bytes gauge -go_memstats_alloc_bytes 6.195808e+06 -# HELP go_memstats_alloc_bytes_total Total number of bytes allocated, even if freed. -# TYPE go_memstats_alloc_bytes_total counter -go_memstats_alloc_bytes_total 9.482768e+06 -# HELP go_memstats_buck_hash_sys_bytes Number of bytes used by the profiling bucket hash table. -# TYPE go_memstats_buck_hash_sys_bytes gauge -go_memstats_buck_hash_sys_bytes 1.449179e+06 -# HELP go_memstats_frees_total Total number of frees. -# TYPE go_memstats_frees_total counter -go_memstats_frees_total 29419 -# HELP go_memstats_gc_cpu_fraction The fraction of this program's available CPU time used by the GC since the program started. -# TYPE go_memstats_gc_cpu_fraction gauge -go_memstats_gc_cpu_fraction 0.022937924367975027 -# HELP go_memstats_gc_sys_bytes Number of bytes used for garbage collection system metadata. -# TYPE go_memstats_gc_sys_bytes gauge -go_memstats_gc_sys_bytes 5.235864e+06 -# HELP go_memstats_heap_alloc_bytes Number of heap bytes allocated and still in use. -# TYPE go_memstats_heap_alloc_bytes gauge -go_memstats_heap_alloc_bytes 6.195808e+06 -# HELP go_memstats_heap_idle_bytes Number of heap bytes waiting to be used. -# TYPE go_memstats_heap_idle_bytes gauge -go_memstats_heap_idle_bytes 3.792896e+06 -# HELP go_memstats_heap_inuse_bytes Number of heap bytes that are in use. -# TYPE go_memstats_heap_inuse_bytes gauge -go_memstats_heap_inuse_bytes 8.036352e+06 -# HELP go_memstats_heap_objects Number of allocated objects. -# TYPE go_memstats_heap_objects gauge -go_memstats_heap_objects 16489 -# HELP go_memstats_heap_released_bytes Number of heap bytes released to OS. -# TYPE go_memstats_heap_released_bytes gauge -go_memstats_heap_released_bytes 3.416064e+06 -# HELP go_memstats_heap_sys_bytes Number of heap bytes obtained from system. -# TYPE go_memstats_heap_sys_bytes gauge -go_memstats_heap_sys_bytes 1.1829248e+07 -# HELP go_memstats_last_gc_time_seconds Number of seconds since 1970 of last garbage collection. -# TYPE go_memstats_last_gc_time_seconds gauge -go_memstats_last_gc_time_seconds 1.635778234064745e+09 -# HELP go_memstats_lookups_total Total number of pointer lookups. -# TYPE go_memstats_lookups_total counter -go_memstats_lookups_total 0 -# HELP go_memstats_mallocs_total Total number of mallocs. -# TYPE go_memstats_mallocs_total counter -go_memstats_mallocs_total 45908 -# HELP go_memstats_mcache_inuse_bytes Number of bytes in use by mcache structures. -# TYPE go_memstats_mcache_inuse_bytes gauge -go_memstats_mcache_inuse_bytes 9600 -# HELP go_memstats_mcache_sys_bytes Number of bytes used for mcache structures obtained from system. -# TYPE go_memstats_mcache_sys_bytes gauge -go_memstats_mcache_sys_bytes 16384 -# HELP go_memstats_mspan_inuse_bytes Number of bytes in use by mspan structures. -# TYPE go_memstats_mspan_inuse_bytes gauge -go_memstats_mspan_inuse_bytes 116144 -# HELP go_memstats_mspan_sys_bytes Number of bytes used for mspan structures obtained from system. -# TYPE go_memstats_mspan_sys_bytes gauge -go_memstats_mspan_sys_bytes 131072 -# HELP go_memstats_next_gc_bytes Number of heap bytes when next garbage collection will take place. -# TYPE go_memstats_next_gc_bytes gauge -go_memstats_next_gc_bytes 7.935184e+06 -# HELP go_memstats_other_sys_bytes Number of bytes used for other system allocations. -# TYPE go_memstats_other_sys_bytes gauge -go_memstats_other_sys_bytes 1.426069e+06 -# HELP go_memstats_stack_inuse_bytes Number of bytes in use by the stack allocator. -# TYPE go_memstats_stack_inuse_bytes gauge -go_memstats_stack_inuse_bytes 753664 -# HELP go_memstats_stack_sys_bytes Number of bytes obtained from system for stack allocator. -# TYPE go_memstats_stack_sys_bytes gauge -go_memstats_stack_sys_bytes 753664 -# HELP go_memstats_sys_bytes Number of bytes obtained from system. -# TYPE go_memstats_sys_bytes gauge -go_memstats_sys_bytes 2.084148e+07 -# HELP go_threads Number of OS threads created. -# TYPE go_threads gauge -go_threads 12 -``` - -## 3. 调用指标 RT - -启动例子中的客户端,经过几次调用后,会发现增加了对应的数据指标,以默认namespace dubbo 为前缀。 - -```yaml -# HELP dubbo_provider_service_rt -# TYPE dubbo_provider_service_rt gauge -dubbo_provider_service_rt{group="dubbo-go",method="SayHello",service="com.apache.dubbo.HelloService",timeout="",version="3.0.0-rc3"} 127542 -``` - -可看到对应接口名、方法名的请求rt时间。该部分调用指标待后续完善。 - -## 4. 手动数据上报 - -可在业务代码中调用API进行手动数据上报。支持Counter、Summary、Gauge 类型,并支持多个标签。上报后即可收集。 - -```go -import "dubbo.apache.org/dubbo-go/v3/metrics/prometheus" - -for { - // metrics refresh per second - time.Sleep(time.Second) - prometheus.IncSummary("test_summary", rand.Float64()) - prometheus.IncSummaryWithLabel("test_summary_with_label", rand.Float64(), map[string]string{ - "summarylabel1": "value1", // label and value for this summary - "summarylabel2": "value2", - }) - - prometheus.IncCounter("test_counter") - prometheus.IncCounterWithLabel("test_counter_with_label", map[string]string{ - "counterlabel1": "value1", // label and value for this counter - "counterlabel2": "value2", - }) - - prometheus.SetGauge("test_gauge", rand.Float64()) - prometheus.SetGaugeWithLabel("test_gauge_with_label", rand.Float64(), map[string]string{ - "gaugelabel1": "value1", - "gaugelabel2": "value2", - }) - } -``` - -运行一段时间后,可以收集到如下用户定义指标 - -```yaml -# HELP dubbo_test_counter -# TYPE dubbo_test_counter counter -dubbo_test_counter 463 -# HELP dubbo_test_counter_with_label -# TYPE dubbo_test_counter_with_label counter -dubbo_test_counter_with_label{counterlabel1="value1",counterlabel2="value2"} 463 -# HELP dubbo_test_gauge -# TYPE dubbo_test_gauge gauge -dubbo_test_gauge 0.7402836247772934 -# HELP dubbo_test_gauge_with_label -# TYPE dubbo_test_gauge_with_label gauge -dubbo_test_gauge_with_label{gaugelabel1="value1",gaugelabel2="value2"} 0.8360973807546456 -# HELP dubbo_test_summary -# TYPE dubbo_test_summary summary -dubbo_test_summary_sum 228.1800106582441 -dubbo_test_summary_count 463 -# HELP dubbo_test_summary_with_label -# TYPE dubbo_test_summary_with_label summary -dubbo_test_summary_with_label{summarylabel1="value1",summarylabel2="value2",quantile="0.5"} 0.5174757569778469 -dubbo_test_summary_with_label{summarylabel1="value1",summarylabel2="value2",quantile="0.75"} 0.734268575017709 -dubbo_test_summary_with_label{summarylabel1="value1",summarylabel2="value2",quantile="0.9"} 0.9059918694279894 -dubbo_test_summary_with_label{summarylabel1="value1",summarylabel2="value2",quantile="0.98"} 0.9761803018478838 -dubbo_test_summary_with_label{summarylabel1="value1",summarylabel2="value2",quantile="0.99"} 0.9820270046489341 -dubbo_test_summary_with_label{summarylabel1="value1",summarylabel2="value2",quantile="0.999"} 0.9986025122460248 -dubbo_test_summary_with_label_sum{summarylabel1="value1",summarylabel2="value2"} 233.609026131067 -dubbo_test_summary_with_label_count{summarylabel1="value1",summarylabel2="value2"} 463 -``` diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/monitor/promethus/_index.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/monitor/promethus/_index.md deleted file mode 100644 index 9827d79ded66..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/monitor/promethus/_index.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/tutorial/governance/monitor/promethus/ - - /zh-cn/docs3-v2/golang-sdk/tutorial/governance/monitor/promethus/ -description: 数据上报 Promethus 教程 -title: 数据上报 Promethus 教程 -type: docs -weight: 2 ---- diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/monitor/rpc_metrics.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/monitor/rpc_metrics.md deleted file mode 100644 index db03525149f0..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/monitor/rpc_metrics.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/tutorial/governance/monitor/rpc_metrics/ - - /zh-cn/docs3-v2/golang-sdk/tutorial/governance/monitor/rpc_metrics/ -description: 查看 RPC 调用的监控信息 -title: 查看 RPC 调用的监控信息 -type: docs -weight: 1 ---- - - - - - - -## 1. 准备工作 - -- dubbo-go cli 工具和依赖工具已安装 -- 创建一个新的 demo 应用 - -## 2. 修改客户端逻辑,重复发起调用 - -go-client/cmd/client.go - -```go -func main() { - config.SetConsumerService(grpcGreeterImpl) - if err := config.Load(); err != nil { - panic(err) - } - - logger.Info("start to test dubbo") - req := &api.HelloRequest{ - Name: "laurence", - } - for{ // 重复发起调用 - reply, err := grpcGreeterImpl.SayHello(context.Background(), req) - if err != nil { - logger.Error(err) - } - logger.Infof("client response result: %v\n", reply) - } -} -``` - -## 3. 查看请求 RT 信息 - -先后启动服务端、客户端服务应用。浏览器查看 localhost:9090/metrics, 搜索 "dubbo", 即可查看服务端暴露接口的请求时延,单位 ns。 - -``` -$ curl localhost:9090/metrics | grep dubbo - -# HELP dubbo_provider_service_rt -# TYPE dubbo_provider_service_rt gauge -dubbo_provider_service_rt{group="",method="SayHello",service="api.Greeter",timeout="",version="3.0.0"} 41084 -``` - -可看到当前最近一次请求 rt 为 41084 ns。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/service-mesh/_index.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/service-mesh/_index.md deleted file mode 100644 index 01b4fb21ed79..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/service-mesh/_index.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/tutorial/governance/service-mesh/ - - /zh-cn/docs3-v2/golang-sdk/tutorial/governance/service-mesh/ -description: 服务网格 -title: 服务网格 -type: docs -weight: 5 ---- diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/service-mesh/deploy.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/service-mesh/deploy.md deleted file mode 100644 index 65b4ea450600..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/service-mesh/deploy.md +++ /dev/null @@ -1,435 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/tutorial/governance/service-mesh/deploy/ - - /zh-cn/docs3-v2/golang-sdk/tutorial/governance/service-mesh/deploy/ -description: Istio 环境部署 Dubbo-go 应用 -title: Istio 环境部署 Dubbo-go 应用 -type: docs -weight: 2 ---- - - - - - - -在本章节中,我们将使用应用模板快速创建一组 Dubbo-go Server和 Client 端应用,部署在 Istio 集群中;观察、调试和验证服务发现和调用成功。 - -## 1. 准备工作 - -- dubbo-go cli 工具和依赖工具已安装、grpc_cli (如需本地调试)。 -- docker、helm、kubectl 环境已安装。(arm 机器需支持 docker buildx) -- [任务【istio 环境部署】](../istio/) 已完成 - -## 2. 开发 server 端 Dubbo-go 应用 - -### 2.1 使用 dubbogo-cli 创建项目模板 - -```plain -$ mkdir mesh-app-server -$ cd mesh-app-server -$ dubbogo-cli newApp . -$ tree . -. -├── Makefile -├── api -│ └── api.proto -├── build -│ └── Dockerfile -├── chart -│ ├── app -│ │ ├── Chart.yaml -│ │ ├── templates -│ │ │ ├── _helpers.tpl -│ │ │ ├── deployment.yaml -│ │ │ ├── service.yaml -│ │ │ └── serviceaccount.yaml -│ │ └── values.yaml -│ └── nacos_env -│ ├── Chart.yaml -│ ├── templates -│ │ ├── _helpers.tpl -│ │ ├── deployment.yaml -│ │ └── service.yaml -│ └── values.yaml -├── cmd -│ └── app.go -├── conf -│ └── dubbogo.yaml -├── go.mod -├── go.sum -└── pkg - └── service - └── service.go -``` - -生成项目包括几个目录: - -- api:放置接口文件:proto文件和生成的pb.go文件 -- build:放置构建相关文件 -- chart:放置发布用 chart 仓库、基础环境chart 仓库:nacos、mesh(开发中) -- cmd:程序入口 -- conf:框架配置 -- pkg/service:RPC 服务实现 -- Makefile: - -- - 镜像、Helm 安装名称: - -- - ``` - IMAGE = $(your_repo)/$(namespace)/$(image_name) - TAG = 1.0.0 - HELM_INSTALL_NAME = dubbo-go-app - ``` - -- - 提供脚本,例如: - -- - - make build # 打包镜像并推送 - - make buildx-publish # arm架构本地打包amd64镜像并推送,依赖buildx - - make deploy # 通过 helm 发布应用 - - make remove # 删除已经发布的 helm 应用 - - make proto-gen # api下生成 pb.go 文件 - - ... - -### 2.2 开发和部署 Dubbo-go 应用: - -#### 开发应用 - -- 编译接口 - - 开发人员需要修改 proto 文件,本任务中直接使用默认接口即可。 - - ```bash - $ make proto-gen - protoc --go_out=./api --go-triple_out=./api ./api/api.proto - ``` - -- 拉取依赖 - - ```bash - $ go get dubbo.apache.org/dubbo-go/v3@3.0 - $ make tidy - go mod tidy - ``` - -- 编写业务逻辑 - - 修改 pkg/service/service.go 实现函数, 返回字符串中显示版本为 v1.0.0 - - ```go - func (s *GreeterServerImpl) SayHello(ctx context.Context, in *api.HelloRequest) (*api.User, error) { - return &api.User{Name: "Hello " + in.Name, Id: "v1.0.0"}, nil - } - ``` - -- 修改配置如下字段,从而使用xds协议作为注册中心 - - conf/dubbogo.yaml - - ```yaml - dubbo: - registries: - xds: - protocol: xds - address: istiod.istio-system.svc.cluster.local:15010 - protocols: - triple: - name: tri - port: 20000 - provider: - services: - GreeterServerImpl: - interface: "" # read from stub - - ``` - - 至此,应用开发完成。 - -#### 配置构建和部署参数 - -- 指定需要构建的镜像: - - 修改 Makefile 如下字段,指定好需要构建的镜像地址和版本。 - - 指定好需要通过 helm 安装的名称。 - - ``` - IMAGE = xxx/dubbo-go-server - TAG = 1.0.0 - HELM_INSTALL_NAME = dubbo-go-server-v1 - ``` - -- 指定需要部署的应用和镜像: - - 修改 chart/app/Chart.yaml 如下字段,指定当前应用名为 `dubbo-go-server`,部署时会创建一个名为 dubbo-go-server 的 service ,关联当前应用的所有版本。 - - ```yaml - apiVersion: v1 - name: dubbo-go-server - description: dubbo-go-server - ``` - - 修改 chart/app/values.yaml 如下字段,指定需要部署的镜像以及当前开发的应用版本 dubbogoAppVersion 为 v1。 - - 部署的镜像需要和上述构建的镜像一致。当前应用版本用于 mesh 流量规则控制。 - - ```yaml - image: - repository: xxx/dubbo-go-server - pullPolicy: Always - tag: "1.0.0" - - # Dubbo-go-mesh version control labels - version: - labels: - dubbogoAppVersion: v1 - ``` - - 至此,构建参数和发布参数都已指定好,可以进行构建和部署了。 - -#### 使用模板构建和部署 Dubbo-go 应用 - -- 构建、推送镜像 - - `$ make build ` (本地为 amd64机器) - - 或者 - - `$ make buildx-publish` (本地为 arm64机器,依赖 docker buildx 命令) - -- 发布 Dubbo-go 应用至集群 - - ```bash - $ make deploy - helm install dubbo-go-server-v1 ./chart/app - NAME: dubbo-go-server-v1 - LAST DEPLOYED: Thu Apr 7 11:19:42 2022 - NAMESPACE: default - STATUS: deployed - REVISION: 1 - TEST SUITE: None - $ helm list - NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION - dubbo-go-server-v1 default 1 2022-04-07 11:19:42.350553 +0800 CST deployed dubbo-go-server-0.0.1 1.16.0 - ``` - - 可看到通过 helm 部署成功 - - - -### 2.3 验证应用 - -#### 查看资源部署情况 - -查看部署好的 deployment ,版本为 v1。 - -```bash -$ kubectl get deployment -NAME READY UP-TO-DATE AVAILABLE AGE -dubbo-go-server-v1 1/1 1 1 26s -``` - -查看部署好的 service。 - -```bash -$ kubectl get svc -NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE -dubbo-go-server ClusterIP 192.168.216.253 20000/TCP 70s -``` - -#### (*可选)本地调试部署好的 Dubbo-go 应用 - -使用 kubectl port-forward Dubbo-go 应用到本地 - -```bash -$ kubectl port-forward svc/dubbo-go-server 20000 -Forwarding from 127.0.0.1:20000 -> 20000 -Forwarding from [::1]:20000 -> 20000 -``` - -使用 grpc_cli 调试集群内的应用,参考任务[【使用 grpc_cli 调试 Dubbo-go 应用】](/zh-cn/overview/mannual/golang-sdk/tutorial/debugging/grpc_cli/) - -```bash -$ grpc_cli ls localhost:20000 -l -filename: api/api.proto -package: api; -service Greeter { - rpc SayHello(api.HelloRequest) returns (api.User) {} - rpc SayHelloStream(stream api.HelloRequest) returns (stream api.User) {} -} -``` - -使用 grpc_cli 发起调用,测试接口 - -```bash -$ grpc_cli call localhost:20000 SayHello "name: 'laurence'" -connecting to localhost:20000 -name: "Hello laurence" -id: "v1.0.0" -Received trailing metadata from server: -accept-encoding : identity,gzip -grpc-accept-encoding : identity,deflate,gzip -Rpc succeeded with OK status -``` - -至此,我们成功开发了一个应用,把它部署在了 istio 集群内。 - -## 3. 开发 Client 端 Dubbo-go 应用 - -### 3.1 使用 dubbogo-cli 创建另一个项目模板 - -```bash -$ dubbogo-cli newApp . -``` - -### 3.2 开发和部署客户端 Dubbo-go 应用: - -#### 编写业务逻辑 - -- 修改 cmd/app.go 的 main 方法,针对下游接口每秒钟发起一次调用 - -```go -func main() { - client := &api.GreeterClientImpl{} - config.SetConsumerService(client) - if err := config.Load(); err != nil { - panic(err) - } - request := &api.HelloRequest{ - Name: "laurence", - } - - for{ - if rsp, err := client.SayHello(context.Background(), request); err != nil{ - logger.Errorf("call server error = %s", err) - }else{ - logger.Infof("call server response = %+v", rsp) - } - time.Sleep(time.Second) - } -} -``` - -- 修改如下配置文件,使用xds协议作为注册中心,加载名为 GreeterClientImpl 的客户端服务。 - - conf/dubbogo.yaml - - ```yaml - dubbo: - registries: - xds: - protocol: xds - address: istiod.istio-system.svc.cluster.local:15010 - consumer: - references: - GreeterClientImpl: - protocol: tri - interface: "" # read from stub - ``` - - 至此,应用开发完成。 - -#### 配置构建和部署参数 - -- 指定需要构建的镜像: - - 修改 Makefile 如下字段,指定好需要构建的镜像地址和版本。 - - 指定好需要通过 helm 安装的名称。 - - ``` - IMAGE = xxx/dubbo-go-client - TAG = 1.0.0 - HELM_INSTALL_NAME = dubbo-go-client - ``` - -- 指定需要部署的应用和镜像: - - 修改 chart/app/Chart.yaml 如下字段,指定当前应用名为 `dubbo-go-client`,部署时会创建一个名为 dubbo-go-client 的 service ,关联当前应用的所有版本。对于一个只有客户端的应用,可以不创建sevice,可以由开发者在模板中修改,本教程中我们默认创建。 - - ```yaml - apiVersion: v1 - name: dubbo-go-client - description: dubbo-go-client - ``` - - 修改 chart/app/values.yaml 如下字段,指定需要部署的镜像以及当前开发的应用版本 dubbogoAppVersion 为 v1。 - - 部署的镜像需要和上述构建的镜像一致。当前应用版本用于 mesh 流量规则控制。 - - ```yaml - image: - repository: xxx/dubbo-go-client - pullPolicy: Always - tag: "1.0.0" - - # Dubbo-go-mesh version control labels - version: - labels: - dubbogoAppVersion: v1 - ``` - - 至此,构建参数和发布参数都已指定好,可以进行构建和部署了。 - -#### 使用模板构建和部署 Dubbo-go 应用 - -- 构建、推送镜像 - - `$ make build ` (本地为 amd64机器) - - 或者 - - `$ make buildx-publish` (本地为 arm64机器,依赖 docker buildx 命令) - -- 发布 Dubbo-go Client 应用至集群 - - ```bash - $ make deploy - helm install dubbo-go-client ./chart/app - NAME: dubbo-go-client - LAST DEPLOYED: Thu Apr 7 11:49:55 2022 - NAMESPACE: default - STATUS: deployed - REVISION: 1 - TEST SUITE: None - $ helm list - NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION - dubbo-go-client default 1 2022-04-07 11:49:55.517898 +0800 CST deployed dubbo-go-client-0.0.1 1.16.0 - dubbo-go-server-v1 default 1 2022-04-07 11:23:18.397658 +0800 CST deployed dubbo-go-server-0.0.1 1.16.0 - ``` - - 可看到通过 helm 部署成功, 目前已经在集群中存在 Client 和 Server 两个应用。 - -### 3.3 验证应用 - -#### 查看资源部署情况 - -查看部署好的 client 和 server 两个 deployment。 - -```bash -$ kubectl get deployment -NAME READY UP-TO-DATE AVAILABLE AGE -dubbo-go-client-v1 1/1 1 1 22m -dubbo-go-server-v1 1/1 1 1 49m -``` - -查看客户端调用日志 - -```bash -$ kubectl get pods | grep client | awk '{print $1}' | xargs kubectl logs -... -2022-04-07T04:13:55.777Z INFO cmd/app.go:29 call server response = name:"Hello laurence" id:"v1.0.0" -2022-04-07T04:13:56.778Z INFO cmd/app.go:29 call server response = name:"Hello laurence" id:"v1.0.0" -2022-04-07T04:13:57.779Z INFO cmd/app.go:29 call server response = name:"Hello laurence" id:"v1.0.0" -2022-04-07T04:13:58.781Z INFO cmd/app.go:29 call server response = name:"Hello laurence" id:"v1.0.0" -2022-04-07T04:13:59.782Z INFO cmd/app.go:29 call server response = name:"Hello laurence" id:"v1.0.0" -2022-04-07T04:14:00.784Z INFO cmd/app.go:29 call server response = name:"Hello laurence" id:"v1.0.0" -2022-04-07T04:14:01.785Z INFO cmd/app.go:29 call server response = name:"Hello laurence" id:"v1.0.0" -``` - -验证调用成功 - -## 4. 小结 - -dubbogo-cli 提供的应用模板可以方便地支持开发者进行镜像的构建、推送、部署。 - -在 Istio 环境中,server 应用将自身服务信息注册在 Isito 上,由客户端监听 xds 资源,查询 istio debug 端口进行接口级别的服务发现。开发人员无需关心 service名、主机名、集群名等概念,只需要引入接口,发起调用即可。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/service-mesh/pixiu/_index.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/service-mesh/pixiu/_index.md deleted file mode 100644 index 5af7336e50a5..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/service-mesh/pixiu/_index.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/tutorial/governance/service-mesh/pixiu/ - - /zh-cn/docs3-v2/golang-sdk/tutorial/governance/service-mesh/pixiu/ -description: 使用 Pixiu 网关接入 Ingress 流量 -title: 使用 Pixiu 网关接入 Ingress 流量 -type: docs -weight: 4 ---- diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/tracing/_index.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/tracing/_index.md deleted file mode 100644 index 8c9d7902003f..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/tracing/_index.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/tutorial/governance/tracing/ - - /zh-cn/docs3-v2/golang-sdk/tutorial/governance/tracing/ -description: 全链路追踪 -title: 全链路追踪 -type: docs -weight: 2 ---- diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/tracing/jaeger/_index.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/tracing/jaeger/_index.md deleted file mode 100644 index 938b0552f1ac..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/tracing/jaeger/_index.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/tutorial/governance/tracing/jaeger/ - - /zh-cn/docs3-v2/golang-sdk/tutorial/governance/tracing/jaeger/ -description: 基于 Jaeger 的链路追踪 -title: 基于 Jaeger 的链路追踪 -type: docs -weight: 1 ---- diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/tracing/opentelmentry/_index.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/tracing/opentelmentry/_index.md deleted file mode 100644 index 419428df40d0..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/tracing/opentelmentry/_index.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/tutorial/governance/tracing/opentelmentry/ - - /zh-cn/docs3-v2/golang-sdk/tutorial/governance/tracing/opentelmentry/ -description: 使用 OpenTelmentry 协议 -title: 使用 OpenTelmentry 协议 -type: docs -weight: 2 ---- diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/tracing/skywalking/_index.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/tracing/skywalking/_index.md deleted file mode 100644 index 2c5328cda199..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/tracing/skywalking/_index.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/tutorial/governance/tracing/skywalking/ - - /zh-cn/docs3-v2/golang-sdk/tutorial/governance/tracing/skywalking/ -description: 基于 Skywalking 的追踪 -title: 基于 Skywalking 的追踪 -type: docs -weight: 3 ---- diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/traffic/_index.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/traffic/_index.md deleted file mode 100644 index 3fab61b3707a..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/traffic/_index.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/tutorial/governance/traffic/ - - /zh-cn/docs3-v2/golang-sdk/tutorial/governance/traffic/ -description: 流量管理 -title: 流量管理 -type: docs -weight: 3 ---- diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/traffic/mesh_router.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/traffic/mesh_router.md deleted file mode 100644 index 1ff6fe80efa1..000000000000 --- a/content/zh-cn/overview/mannual/golang-sdk/tutorial/governance/traffic/mesh_router.md +++ /dev/null @@ -1,153 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/golang-sdk/tutorial/governance/traffic/mesh_router/ - - /zh-cn/docs3-v2/golang-sdk/tutorial/governance/traffic/mesh_router/ -description: 路由规则 -title: 路由规则 -type: docs -weight: 12 ---- - - - - - - -## 路由规则介绍 -[《微服务Mesh路由方案草案V2》](https://www.yuque.com/docs/share/c132d5db-0dcb-487f-8833-7c7732964bd4?# ) - -## 简介 - -路由规则,简单来说就是根据**特定的条件**,将**特定的请求**流量发送到**特定的服务提供者**。从而实现流量的分配。 - -在 Dubbo3 统一路由规则的定义中,需要提供两个yaml格式的资源:virtual service 和 destination rule。其格式和 service mesh 定义的路由规则非常相似。 -- virtual service - -定义host,用于和destination rule建立联系。\ -定义 service 匹配规则\ -定义 match 匹配规则\ -匹配到特定请求后,进行目标集群的查找和验证,对于为空情况,使用 fallback 机制。 - -- destination rule - -定义特定集群子集,以及子集所适配的标签,标签从 provider 端暴露的 url 中获取,并尝试匹配。 - -## 提供能力 -### 基于配置中心的路由配置 - -sample示例参见[Mesh Router](https://github.com/apache/dubbo-go-samples/tree/f7febed9d686cb940ea55d34b5baa567d7574a44/route/meshroute) - -#### 1. 路由规则文件注解 - -路由规则只针对客户端,对于服务端,只需要在服务提供时打好特定的参数标签即可。 - -##### 1.1 virtual-service - -```yaml -apiVersion: service.dubbo.apache.org/v1alpha1 -kind: VirtualService -metadata: {name: demo-route} -spec: - dubbo: - # 使用正则表达式匹配service名,只有个满足该service名的请求才能路由。 - # 就此例子来说,不满足service名的请求会直接找不到provider - # - services: - # - { regex: org.apache.dubbo.UserProvider* } - - routedetail: - - match: - # 匹配规则,如果(sourceLabel)客户端url满足存在参数 `trafficLabel: xxx` 的才能匹配成功 - - sourceLabels: {trafficLabel: xxx} - name: xxx-project - route: # 一旦匹配上述match规则,将选择 dest_rule 里定义的名为 isolation 的子集 - - destination: {host: demo, subset: isolation} - - match: - - sourceLabels: {trafficLabel: testing-trunk} - name: testing-trunk - route: # 一旦匹配上述match规则,将选择 dest_rule 里定义的名为 testing-trunk 的子集 - - destination: {host: demo, subset: testing-trunk} - - name: testing # 没有match,兜底逻辑,上述不满足后一定会被匹配到。 - route: - - destination: {host: demo, subset: testing} - services: - - {exact: com.apache.dubbo.sample.basic.IGreeter} - hosts: [demo] # 匹配dest_rule.yml里面的 host 为demo -``` - -##### 1.2 destination-rule - -```yaml -apiVersion: service.dubbo.apache.org/v1alpha1 -kind: DestinationRule -metadata: { name: demo-route } -spec: - host: demo - subsets: - - labels: { env-sign: xxx, tag1: hello } - name: isolation - - labels: { env-sign: yyy } - name: testing-trunk - - labels: { env-sign: zzz } - name: testing - trafficPolicy: - loadBalancer: { simple: ROUND_ROBIN } -``` - -#### 2. client、server 路由参数设置 - -- client 端 - - dubbogo.yml - - 定义配置中心 - -```yaml - config-center: - protocol: zookeeper - address: 127.0.0.1:2181 - data-id: "dubbo-go-samples-configcenter-zookeeper-client" -``` - -在代码中通过 API 将配置发布至配置中心,也可预先手动配置。 - -```go -dynamicConfiguration, err := config.GetRootConfig().ConfigCenter.GetDynamicConfiguration() -if err != nil { - panic(err) -} - -// publish mesh route config -err = dynamicConfiguration.PublishConfig("dubbo.io.MESHAPPRULE", "dubbo", MeshRouteConf) -if err != nil { - return -} -``` - - - -server 端 - -```yaml -dubbo: - registries: - demoZK: - protocol: zookeeper - timeout: 3s - address: 127.0.0.1:2181 - protocols: - triple: - name: tri - port: 20000 - provider: - services: - GreeterProvider: - interface: com.apache.dubbo.sample.basic.IGreeter # must be compatible with grpc or dubbo-java - params: - env-sign: zzz # server label, 对应 destination Rule中的testing,即兜底逻辑 -``` - -#### 3. 运行方法 - -直接使用goland运行本示例 - - -运行后,可观测到所有客户端流量都路由至 server,根据source label,没有命中的virtualService,因此路由至兜底testing。 diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/interop-dubbo/_index.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/interop-dubbo/_index.md new file mode 100755 index 000000000000..cb383816a580 --- /dev/null +++ b/content/zh-cn/overview/mannual/golang-sdk/tutorial/interop-dubbo/_index.md @@ -0,0 +1,10 @@ +--- +aliases: + - /zh/docs3-v2/golang-sdk/tutorial/debugging/ + - /zh-cn/docs3-v2/golang-sdk/tutorial/debugging/ + - /zh-cn/overview/mannual/golang-sdk/tutorial/develop/interflow/call_java/ +description: "实现 dubbo go 和 dubbo java 应用互通,包括服务发现、协议通信等。" +title: 与dubbo-java互通 +type: docs +weight: 90 +--- diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/interop-dubbo/call_java_protocol_dubbo_non_protobuf.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/interop-dubbo/call_java_protocol_dubbo_non_protobuf.md new file mode 100644 index 000000000000..d181013f460d --- /dev/null +++ b/content/zh-cn/overview/mannual/golang-sdk/tutorial/interop-dubbo/call_java_protocol_dubbo_non_protobuf.md @@ -0,0 +1,77 @@ +--- +aliases: + - /zh/docs3-v2/golang-sdk/tutorial/develop/interflow/call_java/ + - /zh-cn/docs3-v2/golang-sdk/tutorial/develop/interflow/call_java/ +description: "如果您是 dubbo java 的老用户,可能您的 dubbo java 应用并没有使用 protobuf(直接使用 java interface 定义服务),这个时候您需要使用以下方式开发 dubbo go-client,来调用老版本的 dubbo 服务。" +title: 非protoubf模式协议互通(适用于老版本 dubbo java 应用) +linkTitle: 非protoubf模式协议互通 +type: docs +weight: 4 +--- + +{{% alert title="注意" color="warning" %}} +在阅读本文档之前,请记住我们推荐使用 protobuf+triple 的模式编写 java 和 go 语言互通的服务。本文仅当您已经有老版本 dubbo java 应用的情况下适用,否则的话请参考上一篇文档,使用 protobuf+triple 开发服务。 +{{% /alert %}} + + +可在此查看本文档 [完整示例源码](https://github.com/apache/dubbo-go-samples/tree/main/java_interop/non-protobuf-dubbo)。 + + +## go-client 调用 java-server +但如果您是 dubbo java 的老用户,可能您的 dubbo java 应用并没有使用 protobuf(直接使用 java interface 定义服务),这个时候您需要使用以下方式开发 dubbo go-client,来调用老版本的 dubbo 服务。 + +> 以下方案同时支持 triple(non-protobuf) 和 dubbo 协议,你只需要调整协议配置 `client.WithClientProtocolTriple()` 即可。 + +假设我们当前的 java 服务定义如下: + +```java +package org.apache.dubbo.samples.api; + +public interface GreetingsService { + String sayHi(String name); +} +``` + +我们需要这么编写 go-client,以实现服务调用: + +```go +// 生成共享 client,指定 +cliDubbo, _ := client.NewClient( + client.WithClientProtocolDubbo(), + client.WithClientSerialization(constant.Hessian2Serialization), +) + +// 生成服务代理,这里指定 java 服务全路径名 +connDubbo, _ := cliDubbo.Dial("org.apache.dubbo.samples.api.GreetingsService", client.WithURL("tri://localhost:50052")) + +var respDubbo string +// 发起调用,参数以数组形式指定(标准 json 格式,可参考 java 泛化调用) +connDubbo.CallUnary(context.Background(), []interface{}{"hello"}, &respDubbo, "SayHello") +``` + +接下来我们尝试运行示例: + +1. 运行 java server + +```java +./java/java-server/run.sh +``` + +检查服务运行正常: + +```shell +curl \ + --header "Content-Type: application/json" \ + --data '{"name": "Dubbo"}' \ + http://localhost:50052/org.apache.dubbo.sample.Greeter/sayHello +``` + +2. 运行 go client + +```go +go run go/go-server/cmd/client.go +``` + +## java-client 调用 go-server + +这种场景,意味着您要完全从头开发 go server 服务,这时我们建议是直接使用 protbuf 来开发 go server 服务,java client 侧也使用 protobuf 对新增服务发起调用。具体使用示例请参考上一篇文档。 diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/interop-dubbo/call_java_protocol_triple_protobuf.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/interop-dubbo/call_java_protocol_triple_protobuf.md new file mode 100644 index 000000000000..f3d7e1fa350e --- /dev/null +++ b/content/zh-cn/overview/mannual/golang-sdk/tutorial/interop-dubbo/call_java_protocol_triple_protobuf.md @@ -0,0 +1,106 @@ +--- +aliases: + - /zh/docs3-v2/golang-sdk/tutorial/develop/interflow/call_java/ + - /zh-cn/docs3-v2/golang-sdk/tutorial/develop/interflow/call_java/ +description: “基于 protobuf 实现 dubbo-java 与 dubbo-go 的 triple 协议互通。” +title: 基于 protobuf 实现 triple 协议互通(适用于两边都用 protobuf 开发的场景) +linkTitle: protobuf+triple 协议互通 +type: docs +weight: 4 +--- + + +我们这里提供一个示例,演示如何使用 triple 协议实现 dubbo-java 和 dubbo-go 互通,可在此查看 [示例完整源码](https://github.com/apache/dubbo-go-samples/tree/main/java_interop/protobuf-triple)。 + +示例主要内容如下: +- go,go 语言实现的 rpc server 与 client +- java,java 语言实现的 rpc server 与 client + +## 共享 protobuf 服务定义 + +共享服务定义如下,请注意以下 `package`、`go_package `、`java_package` 的具体定义: + +```protobuf +//protoc --go_out=. --go_opt=paths=source_relative --go-triple_out=. greet.proto +syntax = "proto3"; +package org.apache.dubbo.sample; + +option go_package = "github.com/apache/dubbo-go-samples/java_interop/protobuf-triple/go/proto;proto"; +//package of go +option java_package = 'org.apache.dubbo.sample'; +option java_multiple_files = true; +option java_outer_classname = "HelloWorldProto"; +option objc_class_prefix = "WH"; + +// The greeting service definition. +service Greeter { + // Sends a greeting + rpc SayHello(HelloRequest) returns (HelloReply); + // Sends a greeting via stream + // rpc SayHelloStream (stream HelloRequest) returns (stream HelloReply) {} +} + +// The request message containing the user's name. +message HelloRequest { + string name = 1; +} + +// The response message containing the greetings +message HelloReply { + string message = 1; +} +``` + +## java-client调用go-server + +1. 首先启动 go server: + +```shell +go run go/go-server/cmd/server.go +``` + +运行以上命令后,go server 运行在 50052 端口,可通过以下命令测试服务运行正常: + +```shell +curl \ + --header "Content-Type: application/json" \ + --data '{"name": "Dubbo"}' \ + http://localhost:50052/org.apache.dubbo.sample.Greeter/sayHello +``` + +2. 启动 java client + +运行以下命令,启动 java 客户端,可以看到服务调用 go server 正常输出结果: + +```shell +./java/java-client/run.sh +``` + +## go-client调用java-server + +1. 启动 java server + +运行以下命令,启动 java 服务端: + +> 注意,请关闭之前启动的 go server,避免出现端口占用冲突。 + +```shell +./java/java-server/run.sh +``` + +可通过以下命令测试服务运行正常: + +```shell +curl \ + --header "Content-Type: application/json" \ + --data '{"name": "Dubbo"}' \ + http://localhost:50052/org.apache.dubbo.sample.Greeter/sayHello +``` + +2. 运行 go client + +运行以下命令启动 go 客户端,可以看到服务调用 java server 正常输出结果: + +```shell +go run go/go-client/cmd/client.go +``` diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/interop-dubbo/service-discovery.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/interop-dubbo/service-discovery.md new file mode 100644 index 000000000000..183169109f9c --- /dev/null +++ b/content/zh-cn/overview/mannual/golang-sdk/tutorial/interop-dubbo/service-discovery.md @@ -0,0 +1,80 @@ +--- +description: "dubbo-java 和 dubbo-go 使用相同的服务发现模型,本文档演示如何基于应用级服务发现实现地址互通。" +title: 基于应用级服务发现实现地址互通 +linkTitle: 服务发现实现地址互通 +type: docs +weight: 6 +--- + +前面两篇示例我们演示了 dubbo java 和 dubbo go 在协议层面的互通能力,涵盖 triple 和 dubbo 两种协议, +* [非 protoubf 模式协议互通(triple 和 dubbo 协议)](../call_java_protocol_dubbo_non_protobuf) +* [protobuf+triple 协议互通(triple 协议)](../call_java_protocol_triple_protobuf) + +在本篇文档中,我们将演示 dubbo java 和 dubbo go 的服务发现互通能力,这样结合协议兼容性,我们就能实现完整的打通 dubbo java 和 dubbo go 微服务体系。 + + +本文档使用 Nacos 注册中心作为演示,可在此查看本文档 [示例完整源码](https://github.com/apache/dubbo-go-samples/tree/main/java_interop/service_discovery)。 + + +> before run the code , you should Follow this instruction to install and start Nacos server. + +## 应用级别服务发现 + +```shell +cd service +``` +**start java server** +```shell +cd java-server +sh run.sh +``` + +**start go client** +```shell +cd go-client +go run client.go + +``` + +#### go server <-> java client +**start go server** +```shell +cd go-server +go run server.go +``` +**start java client** +```shell +cd java-client +sh run.sh +``` + +## 接口级别服务发现(仅dubbo2用户关注) +### how to run +#### java server <-> go client +```shell +cd interface +``` +**start java server** +```shell +cd java-server +sh run.sh +``` + +**start go client** +```shell +cd go-client +go run client.go + +``` + +#### go server <-> java client +**start go server** +```shell +cd go-server +go run server.go +``` +**start java client** +```shell +cd java-client +sh run.sh +``` diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/interop-grpc/_index.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/interop-grpc/_index.md new file mode 100755 index 000000000000..e60338535880 --- /dev/null +++ b/content/zh-cn/overview/mannual/golang-sdk/tutorial/interop-grpc/_index.md @@ -0,0 +1,10 @@ +--- +aliases: + - /zh/docs3-v2/golang-sdk/tutorial/debugging/ + - /zh-cn/docs3-v2/golang-sdk/tutorial/debugging/ + - /zh-cn/overview/mannual/golang-sdk/tutorial/debugging/grpc_cli/ +description: "实现 dubbo go 与谷歌官方版本 grpc 框架互通。" +title: 与grpc互通 +type: docs +weight: 100 +--- diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/interop-grpc/call_grpc.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/interop-grpc/call_grpc.md new file mode 100644 index 000000000000..1fcee98563f6 --- /dev/null +++ b/content/zh-cn/overview/mannual/golang-sdk/tutorial/interop-grpc/call_grpc.md @@ -0,0 +1,244 @@ +--- +aliases: + - /zh/docs3-v2/golang-sdk/tutorial/develop/interflow/call_grpc/ + - /zh-cn/docs3-v2/golang-sdk/tutorial/develop/interflow/call_grpc/ +description: 与 gRPC 应用互通 +title: 与 gRPC 应用互通 +type: docs +weight: 5 +--- + +## 1.介绍 + +triple 协议 100% 兼容 gRPC,本示例演示使用 dubbo-go 开发与 grpc 互调的应用,可在此查看 完整示例源码地址 + +## 2.如何互通 + +Dubbo-go的Triple协议能够兼容grpc协议 +在创建服务端时,可以设置`protocol.WithTriple()`使用Triple协议 + +```go + srv, err := server.NewServer( + server.WithServerProtocol( + protocol.WithPort(20000), + protocol.WithTriple(), + ), + ) +``` + +## 3.案例 + +### 3.1服务端介绍 + +#### 服务端proto文件 + +源文件路径:dubbo-go-sample/rpc/grpc/proto/greet.proto + +```protobuf +syntax = "proto3"; + +package greet; + +option go_package = "github.com/apache/dubbo-go-samples/rpc/grpc/proto;greet"; + +message GreetRequest { + string name = 1; +} + +message GreetResponse { + string greeting = 1; +} + +service GreetService { + rpc Greet(GreetRequest) returns (GreetResponse) {} +} +``` + +#### dubbo-go服务端 + +源文件路径:dubbo-go-sample/rpc/grpc/go-server/cmd/main.go + +```go +type GreetTripleServer struct { +} + +func (srv *GreetTripleServer) Greet(ctx context.Context, req *greet.GreetRequest) (*greet.GreetResponse, error) { + resp := &greet.GreetResponse{Greeting: "dubbo:" + req.Name} + return resp, nil +} + +func main() { + srv, err := server.NewServer( + server.WithServerProtocol( + protocol.WithPort(20000), + protocol.WithTriple(), + ), + ) + if err != nil { + panic(err) + } + + if err := greet.RegisterGreetServiceHandler(srv, &GreetTripleServer{}); err != nil { + panic(err) + } + + if err := srv.Serve(); err != nil { + logger.Error(err) + } +} +``` + +#### grpc服务端 + +源文件路径: dubbo-go-sample/rpc/grpc/grpc-server/cmd/main.go + +```go +type server struct { + pb.UnimplementedGreetServiceServer +} + +func (s *server) Greet(ctx context.Context, req *pb.GreetRequest) (*pb.GreetResponse, error) { + resp := &pb.GreetResponse{Greeting: "grpc:" + req.Name} + return resp, nil +} + +func main() { + lis, err := net.Listen("tcp", "127.0.0.1:20001") + if err != nil { + logger.Fatalf("failed to listen: %v", err) + } + s := grpc.NewServer() + pb.RegisterGreetServiceServer(s, &server{}) + logger.Infof("server listening at %v", lis.Addr()) + if err := s.Serve(lis); err != nil { + logger.Fatalf("failed to serve: %v", err) + } +} + +``` + +### 3.2客户端介绍 + +#### dubbo-go客户端 + +源文件路径:dubbo-go-sample/rpc/grpc/go-client/cmd/main.go + +```go +package main + +import ( + "context" + + "dubbo.apache.org/dubbo-go/v3/client" + _ "dubbo.apache.org/dubbo-go/v3/imports" + greet "github.com/apache/dubbo-go-samples/rpc/grpc/proto" + "github.com/dubbogo/gost/log/logger" +) + +func main() { + // test connect with dubbo + dubboCli, err := client.NewClient( + client.WithClientURL("127.0.0.1:20000"), + ) + if err != nil { + panic(err) + } + + svc, err := greet.NewGreetService(dubboCli) + if err != nil { + panic(err) + } + + resp, err := svc.Greet(context.Background(), &greet.GreetRequest{Name: "hello world"}) + if err != nil { + logger.Error(err) + } + logger.Infof("Greet response: %s", resp.Greeting) + + // test connect with grpc + grpcCli, err := client.NewClient( + client.WithClientURL("127.0.0.1:20001"), + ) + if err != nil { + panic(err) + } + svc, err = greet.NewGreetService(grpcCli) + if err != nil { + panic(err) + } + resp, err = svc.Greet(context.Background(), &greet.GreetRequest{Name: "hello world"}) + if err != nil { + logger.Error(err) + } + logger.Infof("Greet response: %s", resp.Greeting) +} +``` + +#### grpc客户端 + +源文件路径:dubbo-go-sample/rpc/grpc/grpc-client/cmd/main.go + +```go +package main + +import ( + "context" + "time" + + "github.com/dubbogo/gost/log/logger" + + pb "github.com/apache/dubbo-go-samples/rpc/grpc/proto" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" +) + +func main() { + // test connect with grpc + grpcConn, err := grpc.Dial("127.0.0.1:20001", grpc.WithTransportCredentials(insecure.NewCredentials())) + if err != nil { + logger.Fatalf("did not connect: %v", err) + } + defer grpcConn.Close() + c := pb.NewGreetServiceClient(grpcConn) + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + resp, err := c.Greet(ctx, &pb.GreetRequest{Name: "hello world"}) + if err != nil { + logger.Fatalf("could not greet: %v", err) + } + logger.Infof("Greet response: %s", resp.Greeting) + + // test connect with dubbo + dubboConn, err := grpc.Dial("127.0.0.1:20000", grpc.WithTransportCredentials(insecure.NewCredentials())) + if err != nil { + logger.Fatalf("did not connect: %v", err) + } + defer dubboConn.Close() + c = pb.NewGreetServiceClient(dubboConn) + ctx, cancel = context.WithTimeout(context.Background(), time.Second) + defer cancel() + resp, err = c.Greet(ctx, &pb.GreetRequest{Name: "hello world"}) + if err != nil { + logger.Fatalf("could not greet: %v", err) + } + logger.Infof("Greet response: %s", resp.Greeting) +} +``` + +### 3.3案例效果 + +先启动dubbo-go服务端和grpc服务端,然后启动dubbo-go客户端和grpc客户端,观察控制台输出 + +Dubbo-go客户端输出: + +```shell +Greet response: dubbo:hello world +Greet response: grpc:hello world +``` + +grpc客户端输出: + +```shell +Greet response: grpc:hello world +Greet response: dubbo:hello world +``` diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/load-balance/_index.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/load-balance/_index.md new file mode 100755 index 000000000000..04bf7fe15e90 --- /dev/null +++ b/content/zh-cn/overview/mannual/golang-sdk/tutorial/load-balance/_index.md @@ -0,0 +1,6 @@ +--- +description: "框架支持的负载均衡策略与配置方法。" +title: 负载均衡 +type: docs +weight: 23 +--- diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/load-balance/loadbalance.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/load-balance/loadbalance.md new file mode 100644 index 000000000000..81bf94c7d4ec --- /dev/null +++ b/content/zh-cn/overview/mannual/golang-sdk/tutorial/load-balance/loadbalance.md @@ -0,0 +1,61 @@ +--- +description: "Dubbo 支持的消费端负载均衡策略及其使用方法。" +linkTitle: 负载均衡 +title: 负载均衡策略与配置细节 +type: docs +weight: 1 +--- + +Dubbo-go 内置了 client-based 负载均衡机制,如下是当前支持的负载均衡算法,结合上文提到的自动服务发现机制,消费端会自动使用 `Weighted Random LoadBalance 加权随机负载均衡策略` 选址调用。 + +如果要调整负载均衡算法,以下是 Dubbo 框架内置的负载均衡策略: + +| 算法 | 特性 | 备注 | 配置值 | +| :-------------------------- | :---------------------- | :---------------------------------------------- | :---------------------------------------------- | +| Weighted Random LoadBalance | 加权随机 | 默认算法,默认权重相同 | random (默认) | +| RoundRobin LoadBalance | 加权轮询 | 借鉴于 Nginx 的平滑加权轮询算法,默认权重相同 | roundrobin | +| LeastActive LoadBalance | 最少活跃优先 + 加权随机 | 背后是能者多劳的思想 | leastactive | +| Consistent Hash LoadBalance | 一致性哈希 | 确定的入参,确定的提供者,适用于有状态请求 | consistenthashing | +| P2C LoadBalance | Power of Two Choice | 随机选择两个节点后,继续选择“连接数”较小的那个节点。 | p2c | +| Interleaved Weighted Round Robin | 一种加权轮训算法 | https://en.wikipedia.org/wiki/Weighted_round_robin#Interleaved_WRR | interleavedweightedroundrobin | +| Alias Method Round Robin | | https://en.wikipedia.org/wiki/Alias_method | aliasmethod | + +## 全局配置 +Dubbo 框架的默认策略是 `random` 加权随机负载均衡。如果要调整策略,只需要设置 `loadbalance` 相应取值即可,每种负载均衡策略取值请参见文档最上方表格。 + +为所有服务调用指定全局配置: + +```go +cli, err := client.NewClient( + client.WithClientLoadBalance("roundrobin"), +) +``` + +或者一些常用的策略: + +```go +cli, err := client.NewClient( + client.WithClientLoadBalanceRoundRobin(), +) +``` + +## 接口级配置 +```go +cli, err := client.NewClient( + //... +) + +svc, err := greet.NewGreetService(cli, client.WithLoadBalance("roundrobin")) +``` + +或者一些常用的策略: + +```go +cli, err := client.NewClient( + //... +) + +svc, err := greet.NewGreetService(cli, client.WithLoadBalanceRoundRobin()) +``` + + diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/observability/_index.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/observability/_index.md new file mode 100755 index 000000000000..3ebc15411dc7 --- /dev/null +++ b/content/zh-cn/overview/mannual/golang-sdk/tutorial/observability/_index.md @@ -0,0 +1,10 @@ +--- +aliases: + - /zh/docs3-v2/golang-sdk/tutorial/debugging/ + - /zh-cn/docs3-v2/golang-sdk/tutorial/debugging/ + - /zh-cn/overview/mannual/golang-sdk/tutorial/governance/monitor/ +description: "可视化查看应用内部状态,包括日志、metrics指标监控、全链路追踪等" +title: 可视化观测 +type: docs +weight: 40 +--- diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/observability/logger.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/observability/logger.md new file mode 100644 index 000000000000..3d5fd32cd1ab --- /dev/null +++ b/content/zh-cn/overview/mannual/golang-sdk/tutorial/observability/logger.md @@ -0,0 +1,77 @@ +--- +aliases: + - /zh-cn/overview/mannual/golang-sdk/tutorial/develop/features/custom-logger/ +description: logger +title: 配置和管理框架日志 +linkTitle: 框架日志 +type: docs +weight: 1 +--- + +本示例演示如何配置 dubbo-go 框架日志组件,将框架运行态日志保存到指定的位置。可在此查看 完整示例源码地址。 + +{{% alert title="注意" color="info" %}} +这里配置的只是 dubbo-go 框架自身的日志组件行为,即框架内部使用的日志,不影响业务日志框架的使用! +{{% /alert %}} + +## 1. 日志配置 +如下所示,可以通过 `log.WithZap()`、`log.WithLevel("warn")` 设置 dubbo 框架日志行为: + +```go +ins, err := dubbo.NewInstance( + dubbo.WithLogger( + log.WithLevel("warn"), + log.WithZap(), + ), +) +``` + +## 2. 应用共享日志组件 +注意,这里配置的只是 dubbo-go 框架自身的日志组件行为(即框架内部使用的日志),不影响业务日志框架的使用! + +**通过以下方式,业务应用也可以选择复用这个日志组件:** + +```go +import app_logger "github.com/dubbogo/gost/log/logger" + +app_logger.Info("hello") +``` + +日志 Interface + +```go +type Logger interface { + Info(args ...interface{}) + Warn(args ...interface{}) + Error(args ...interface{}) + Debug(args ...interface{}) + Fatal(args ...interface{}) + + Infof(fmt string, args ...interface{}) + Warnf(fmt string, args ...interface{}) + Errorf(fmt string, args ...interface{}) + Debugf(fmt string, args ...interface{}) + Fatalf(fmt string, args ...interface{}) +} +``` + +{{% alert title="注意" color="info" %}} +日志API不可以在Init 阶段使用,否则可能会发生意料之外的问题。 +{{% /alert %}} + +## 2. 完全自定义日志 +当前 dubbo-go 框架支持 zap、logrus 两个日志框架,如果您想让 dubbo 框架内核使用其他日志框架打印日志,推荐以标准扩展形式增加支持,具体可参考核心库中内置的 [源码实现](https://github.com/apache/dubbo-go/tree/main/logger)。 + +## 3. 访问日志 + +可以通过以下方式配置开启访问日志: + +```go +srv, err := server.NewServer( + server.WithAccesslog("true"), + // server.WithAccesslog("default"), + // server.WithAccesslog("/your/path/to/store/the/log/logfile"), +) +``` + +对于 `true` 和 `default` 而言,访问日志会使用 Dubbo 中的 logger 组件打印出来。如果指定了具体的日志文件路径,则直接写入到该文件。 diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/observability/rpc_metrics.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/observability/rpc_metrics.md new file mode 100644 index 000000000000..79f58b00ddb2 --- /dev/null +++ b/content/zh-cn/overview/mannual/golang-sdk/tutorial/observability/rpc_metrics.md @@ -0,0 +1,147 @@ +--- +aliases: + - /zh/docs3-v2/golang-sdk/tutorial/governance/monitor/rpc_metrics/ + - /zh-cn/docs3-v2/golang-sdk/tutorial/governance/monitor/rpc_metrics/ +description: "采集运行态 Metrics 指标并接入 Prometheus、Grafana 系统" +title: metrics监控 +type: docs +weight: 2 +--- + +Dubbo 支持采集运行态 Metrics 指标并接入 Prometheus、Grafana 系统,实现对微服务集群的可视化监控,以下是一个具体的使用示例,可查看 [示例完整源码](https://github.com/apache/dubbo-go-samples/tree/main/metrics)。 + +## Contents + +- server/main.go - is the main definition of the service, handler and rpc server +- client/main.go - is the rpc client +- proto - contains the protobuf definition of the API + +## How to run + +### Run server +```shell +go run ./go-server/cmd/main.go +``` + +test server work as expected: +```shell +curl \ + --header "Content-Type: application/json" \ + --data '{"name": "Dubbo"}' \ + http://localhost:20000/greet.GreetService/Greet +``` + +### Run client +```shell +go run ./go-client/cmd/main.go +``` + +## deploy to local +install prometheus and open prometheus config file `prometheus.yml`, write the config like this + +```yaml +global: + evaluation_interval: 15s + scrape_interval: 15s +scrape_configs: +- job_name: dubbo-provider + scrape_interval: 15s + scrape_timeout: 5s + metrics_path: /prometheus + static_configs: + - targets: ['localhost:9099'] +- job_name: dubbo-consumer + scrape_interval: 15s + scrape_timeout: 5s + metrics_path: /prometheus + static_configs: + - targets: ['localhost:9097'] +``` + +install grafana and open grafana web page like `localhost:3000` + +open: 【Home / Connections / Data sources】 + +click 【Add new data source】 + +select Prometheus + +enter 【Prometheus server URL】 like `http://localhost:9090` and click 【Save & test】 + +![datasource.png](/imgs/golang/metrics/dashboard.png) + +open 【Home / Dashboards 】click 【New】【import】and enter 19294 click Load + +![import](/imgs/golang/metrics/import.png) + +if your grafana can't access internet you can open `https://grafana.com/grafana/dashboards/19294-dubbo-observability/` and click 【Download JSON】 + +paste the JSON + +![json.png](/imgs/golang/metrics/import-json.png) + +![datasource.png](/imgs/golang/metrics/import-datasource.png) + +click 【Import】button and you will see the Dubbo Observability dashboard,enjoy it + +![databoard](/imgs/golang/metrics/dashboard.png) + +## Deploy to Kubernetes + +#### kube-prometheus + +install prometheus in k8s [kube-prometheus](https://github.com/prometheus-operator/kube-prometheus) + +Set `prometheus-service.yaml` type to NodePort + +1. add `dubboPodMoitor.yaml` to `kube-prometheus` `manifests` dir, The content is as follows + ```yaml +apiVersion: monitoring.coreos.com/v1 +kind: PodMonitor +metadata: + name: podmonitor + labels: + app: podmonitor + namespace: monitoring +spec: + namespaceSelector: + matchNames: + - dubbo-system + selector: + matchLabels: + app-type: dubbo + podMetricsEndpoints: + - port: metrics # ref to dubbo-app port name metrics + path: /prometheus +--- +# rbac +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + namespace: dubbo-system + name: pod-reader +rules: + - apiGroups: [""] + resources: ["pods"] + verbs: ["get", "list", "watch"] + +--- +# rbac +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: pod-reader-binding + namespace: dubbo-system +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: pod-reader +subjects: + - kind: ServiceAccount + name: prometheus-k8s + namespace: monitoring +``` +2. `kubectl apply -f Deployment.yaml` +3. open prometheus web page such as http://localhost:9090/targets + ![podmonitor.png](/imgs/golang/metrics/podmonitor.png) + diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/observability/tracing.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/observability/tracing.md new file mode 100644 index 000000000000..7f2940334491 --- /dev/null +++ b/content/zh-cn/overview/mannual/golang-sdk/tutorial/observability/tracing.md @@ -0,0 +1,85 @@ +--- +description: 全链路追踪 +title: 链路追踪 +linkTitle: 全链路追踪 +type: docs +weight: 3 +--- + +Dubbo-go 支持基于 [OpenTelemetry](https://opentelemetry.io/) 标准的全链路追踪埋点,同时支持通过以下 exporter 导出到不同的 tracing 后端系统。 + +- [Stdout exporter](./stdout) +- [Jaeger exporter](./jaeger) +- [Zipkin exporter](./zipkin) +- [OTLP-HTTP exporter](./otlp-http) +- [OTLP-gRPC exporter](./otlp-grpc) + +## 使用方式 + +请注意,仅支持通过 `dubbo.NewInstance` 方式创建 dubbo 应用时开启 tracing 功能,也就是我们快速开始中提到的 [微服务应用模式](),对于 [轻量 RPC API]() 暂时不支持开启 tracing。 + +## 示例详解 +可在此查看 完整示例源码地址。 + +使用 `dubbo.WithTracing()` 开启 tracing,可以通过多个参数控制 tracing 行为: + +```go +package main + +import ( + "dubbo.apache.org/dubbo-go/v3" + _ "dubbo.apache.org/dubbo-go/v3/imports" + "dubbo.apache.org/dubbo-go/v3/otel/trace" +) + +func main() { + instance, err := dubbo.NewInstance( + dubbo.WithTracing( + // add tracing options here + trace.WithEnabled(), // enable tracing feature + trace.WithStdoutExporter(), + trace.WithW3cPropagator(), + trace.WithAlwaysMode(), + trace.WithRatioMode(), // use ratio mode + trace.WithRatio(0.5), // sample ratio, only active when use ratio mode + ), + ) +} + +``` + +如果你在 `dubbo.WithTracing()` 调用中不指定任何 option 参数,则会使用默认行为: + +```yaml +# default tracing config +enable: false +exporter: stdout +endpoint: "" +propagator: w3c +sample-mode: ratio +sample-ratio: 0.5 +``` + +## TracingOptions详解 + +- enable: enable tracing or not + - `trace.WithEnabled()` means enable tracing +- exporter: tracing exporter backends, support stdout, jaeger, zipkin, otlp-http, otlp-grpc + - `trace.WithStdoutExporter()` + - `trace.WithJaegerExporter()` + - `trace.WithZipkinExporter()` + - `trace.WithOtlpHttpExporter()` + - `trace.WithOtlpGrpcExporter()` +- endpoint: exporter backend endpoint, for example, jaeger exporter's endpoint is `http://localhost:14268/api/traces` + - `trace.WithEndpoint(string)` +- propagator: context propagator type, support w3c, b3, more details you can see [here](https://opentelemetry.io/docs/concepts/context-propagation/) + - `trace.WithW3cPropagator()` + - `trace.WithB3Propagator()` zipkin exporter default use this +- sample-mode: sample mode, support ratio, always, never + - `trace.WithAlwaysMode()` + - `trace.WithNeverMode()` + - `trace.WithRatioMode()` +- sample-ratio: sample ratio, only used when sample-mode is ratio, range between 0 and 1 + - `trace.WithRatio(float64)` + + diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/rpc/_index.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/rpc/_index.md new file mode 100755 index 000000000000..2ad00452f7bb --- /dev/null +++ b/content/zh-cn/overview/mannual/golang-sdk/tutorial/rpc/_index.md @@ -0,0 +1,9 @@ +--- +aliases: + - /zh/docs3-v2/golang-sdk/tutorial/debugging/ + - /zh-cn/docs3-v2/golang-sdk/tutorial/debugging/ +description: "rpc 框架通信常用的一些功能与配置方式,包括流式通信、超时时间、Filter拦截器、附加参数、健康检查等。" +title: RPC框架 +type: docs +weight: 10 +--- diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/rpc/attachments.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/rpc/attachments.md new file mode 100644 index 000000000000..30fd431ce455 --- /dev/null +++ b/content/zh-cn/overview/mannual/golang-sdk/tutorial/rpc/attachments.md @@ -0,0 +1,181 @@ +--- +description: 传递附加参数 attachment +title: 传递附加参数 +type: docs +weight: 4 +--- + +**理解隐式参数传递的最直接方式 http header,它的工作方式与 http header 完全一致,在 GET 或 POST 请求体之外可以传递任意多个 header 参数**。而对于 RPC 调用而言,context就是在方法签名的参数之外提供附加参数传递能力,在实现原理上,对于不同的协议,attachment 的实现方式略有不同: +* 对于 triple 协议,attachment 会转换为标准的 http header 进行传输。 +* 对于 dubbo 协议,attachment 是编码在协议体的固定位置进行传输,具体请参见 dubbo 协议规范。、 + +![/user-guide/images/context.png](/imgs/user/context.png) + +{{% alert title="注意" color="primary" %}} +* 在使用 triple 协议时,由于 http header 的限制,仅支持小写的 ascii 字符 +* path, group, version, dubbo, token, timeout 等一些 key 是保留字段,传递 attachment 时应避免使用,尽量通过业务前缀等确保 key 的唯一性。 +{{% /alert %}} + +## 1.介绍 + +本文档演示如何在 Dubbo-go 框架中使用 context 上下文传递和读取附加参数,来实现上下文信息传递,可在此查看 完整示例源码地址 + +## 2.使用说明 +### 2.1客户端使用说明 + +在客户端中,使用下述方式传递字段, 示例中 key 为 `constant.AttachmentKey` 即 "attachment": + +```go + ctx := context.Background() + ctx = context.WithValue(ctx, constant.AttachmentKey, map[string]interface{}{ + "key1": "user defined value 1", + "key2": "user defined value 2" + }) +``` + +### 2.2服务端使用说明 + +在服务端中,使用下述方式获取字段, value的类型为 map[string]interface{}: +```go + attachments := ctx.Value(constant.AttachmentKey).(map[string]interface{}) + logger.Infof("Dubbo attachment key1 = %s", value1.([]string)[0]) + logger.Infof("Dubbo attachment key2 = %s", value2.([]string)[0]) +``` + +## 3.示例详解 + +### 3.1服务端介绍 + +#### 服务端proto文件 + +源文件路径:dubbo-go-sample/context/proto/greet.proto + +```protobuf +syntax = "proto3"; + +package greet; + +option go_package = "github.com/apache/dubbo-go-samples/context/proto;greet"; + +message GreetRequest { + string name = 1; +} + +message GreetResponse { + string greeting = 1; +} + +service GreetService { + rpc Greet(GreetRequest) returns (GreetResponse) {} +} +``` + +#### 服务端handler文件 + +源文件路径:dubbo-go-sample/context/go-server/main.go + +```go +package main + +import ( + "context" + "dubbo.apache.org/dubbo-go/v3/common/constant" + _ "dubbo.apache.org/dubbo-go/v3/imports" + "dubbo.apache.org/dubbo-go/v3/protocol" + "dubbo.apache.org/dubbo-go/v3/server" + greet "github.com/apache/dubbo-go-samples/context/proto" + "github.com/dubbogo/gost/log/logger" +) + +type GreetTripleServer struct { +} + +func (srv *GreetTripleServer) Greet(ctx context.Context, req *greet.GreetRequest) (*greet.GreetResponse, error) { + attachments := ctx.Value(constant.AttachmentKey).(map[string]interface{}) + if value1, ok := attachments["key1"]; ok { + logger.Infof("Dubbo attachment key1 = %s", value1.([]string)[0]) + } + if value2, ok := attachments["key2"]; ok { + logger.Infof("Dubbo attachment key2 = %s", value2.([]string)[0]) + } + + resp := &greet.GreetResponse{Greeting: req.Name} + return resp, nil +} + +func main() { + srv, err := server.NewServer( + server.WithServerProtocol( + protocol.WithPort(20000), + protocol.WithTriple(), + ), + ) + if err != nil { + panic(err) + } + + if err := greet.RegisterGreetServiceHandler(srv, &GreetTripleServer{}); err != nil { + panic(err) + } + + if err := srv.Serve(); err != nil { + logger.Error(err) + } +} +``` + +### 3.2客户端介绍 + +客户端client文件,创建客户端,在context写入变量,发起调用并打印结果 + +源文件路径:dubbo-go-sample/context/go-client/main.go + +```go +package main + +import ( + "context" + + "dubbo.apache.org/dubbo-go/v3/client" + "dubbo.apache.org/dubbo-go/v3/common/constant" + _ "dubbo.apache.org/dubbo-go/v3/imports" + greet "github.com/apache/dubbo-go-samples/context/proto" + "github.com/dubbogo/gost/log/logger" +) + +func main() { + cli, err := client.NewClient( + client.WithClientURL("127.0.0.1:20000"), + ) + if err != nil { + panic(err) + } + + svc, err := greet.NewGreetService(cli) + if err != nil { + panic(err) + } + + ctx := context.Background() + ctx = context.WithValue(ctx, constant.AttachmentKey, map[string]interface{}{ + "key1": "user defined value 1", + "key2": "user defined value 2", + }) + + resp, err := svc.Greet(ctx, &greet.GreetRequest{Name: "hello world"}) + if err != nil { + logger.Error(err) + } + logger.Infof("Greet response: %s", resp.Greeting) +} + +``` + +### 3.3 案例效果 + +先启动服务端,再启动客户端,可以观察到服务端打印了客户端通过context传递的参数值,说明参数被成功传递并获取 + +``` +2024-02-26 11:13:14 INFO logger/logging.go:42 Dubbo attachment key1 = [user defined value 1] +2024-02-26 11:13:14 INFO logger/logging.go:42 Dubbo attachment key2 = [user defined value 2] +``` diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/rpc/error.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/rpc/error.md new file mode 100644 index 000000000000..33f590772cfb --- /dev/null +++ b/content/zh-cn/overview/mannual/golang-sdk/tutorial/rpc/error.md @@ -0,0 +1,156 @@ +--- +aliases: + - /zh-cn/overview/mannual/golang-sdk/tutorial/develop/protocol/exception_response/ +description: "当服务端请求处理失败时,dubbo 会支持返回 error 类型值,本示例演示如何处理异常类型返回值。" +title: 异常类型返回值 +linkTitle: 异常类型返回值 +type: docs +weight: 3 +--- + +## 1.介绍 + +本文档演示如何在 RPC 调用过程中处理 error 错误类型响应,可在此查看 完整示例源码地址。 + +## 2.示例详解 + +### 2.1 服务端 + +#### 服务端proto文件 + +源文件路径:dubbo-go-sample/error/proto/greet.proto + +```protobuf +syntax = "proto3"; + +package greet; + +option go_package = "github.com/apache/dubbo-go-samples/error/proto;greet"; + +message GreetRequest { + string name = 1; +} + +message GreetResponse { + string greeting = 1; +} + +service GreetService { + rpc Greet(GreetRequest) returns (GreetResponse) {} +} +``` + +#### 服务端handler文件 + +请注意,在本程序设计中,Greet方法只有接收到 `name="right name"` 时才会认为是正确请求,否则会返回错误。 + +源文件路径:dubbo-go-sample/context/go-server/main.go + +```go +package main + +import ( + "context" + "fmt" + "github.com/pkg/errors" + + _ "dubbo.apache.org/dubbo-go/v3/imports" + "dubbo.apache.org/dubbo-go/v3/protocol" + "dubbo.apache.org/dubbo-go/v3/server" + greet "github.com/apache/dubbo-go-samples/helloworld/proto" + "github.com/dubbogo/gost/log/logger" +) + +type GreetTripleServer struct { +} + +func (srv *GreetTripleServer) Greet(ctx context.Context, req *greet.GreetRequest) (*greet.GreetResponse, error) { + name := req.Name + if name != "right name" { + errInfo := fmt.Sprintf("name is not right: %s", name) + logger.Error(errInfo) + return nil, errors.New(errInfo) + } + + resp := &greet.GreetResponse{Greeting: req.Name} + return resp, nil +} + +func main() { + srv, err := server.NewServer( + server.WithServerProtocol( + protocol.WithPort(20000), + protocol.WithTriple(), + ), + ) + if err != nil { + panic(err) + } + + if err = greet.RegisterGreetServiceHandler(srv, &GreetTripleServer{}); err != nil { + panic(err) + } + + if err = srv.Serve(); err != nil { + logger.Error(err) + } +} + +``` + +从 rpc 方法签名中,我们可以看到 `func (srv *GreetTripleServer) Greet(ctx context.Context, req *greet.GreetRequest) (*greet.GreetResponse, error)` 包含 error 返回值。 + +### 2.2 客户端 + +客户端分别发起两次调用,一次是正确的请求,一次是错误的请求 + +源文件路径:dubbo-go-sample/context/go-client/main.go + +```go +package main + +import ( + "context" + + "dubbo.apache.org/dubbo-go/v3/client" + _ "dubbo.apache.org/dubbo-go/v3/imports" + greet "github.com/apache/dubbo-go-samples/helloworld/proto" + "github.com/dubbogo/gost/log/logger" +) + +func main() { + cli, err := client.NewClient( + client.WithClientURL("127.0.0.1:20000"), + ) + if err != nil { + panic(err) + } + + svc, err := greet.NewGreetService(cli) + if err != nil { + panic(err) + } + + resp, err := svc.Greet(context.Background(), &greet.GreetRequest{Name: "right name"}) + if err != nil { + logger.Error(err) + } + logger.Infof("call Greet success: %s", resp.Greeting) + + resp, err = svc.Greet(context.Background(), &greet.GreetRequest{Name: "wrong name"}) + if err != nil { + logger.Errorf("call Greet failed, err: %s", err.Error()) + } +} +``` + +### 2.3 案例效果 + +先启动服务端,再启动客户端,可以观察到客户端的第一次调用成功,第二次调用失败并且服务端返回了 error + +``` +2024-02-28 17:49:40 INFO logger/logging.go:42 call Greet success: [right name] +2024-02-28 17:49:40 ERROR logger/logging.go:52 call Greet failed, err: [Failed to invoke the method Greet in the service greet.GreetService. Tried 2 times of the providers [tri://:@127.0.0.1:20000/?interface=greet.GreetService&group=&version= tri://:@127.0.0.1:20000/?interface=greet.GreetService&group=&version= tri://:@127.0.0.1:20000/?interface=greet.GreetService&group=&version=] (3/1)from the registry tri://127.0.0.1:20000/greet.GreetService?app.version=&application=dubbo.io&async=false&bean.name=greet.GreetService&cluster=failover&config.tracing=&environment=&generic=&group=&interface=greet.GreetService&loadbalance=&metadata-type=local&module=sample&name=dubbo.io&organization=dubbo-go&owner=dubbo-go&peer=true&provided-by=&reference.filter=cshutdown®istry.role=0&release=dubbo-golang-3.2.0&remote.timestamp=&retries=&serialization=protobuf&side=consumer&sticky=false×tamp=1709113780&version= on the consumer 30.221.146.234 using the dubbo version 3.2.0. Last error is unknown: name is not right: wrong name.: unknown: name is not right: wrong name] +``` + + diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/rpc/filter.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/rpc/filter.md new file mode 100644 index 000000000000..999f21a90d12 --- /dev/null +++ b/content/zh-cn/overview/mannual/golang-sdk/tutorial/rpc/filter.md @@ -0,0 +1,97 @@ +--- +aliases: + - /zh-cn/overview/mannual/golang-sdk/tutorial/governance/features/custom-filter/ +description: filter拦截器 +title: filter拦截器 +type: docs +weight: 7 +--- + +Filter 过滤器动态拦截请求(request)或响应(response)以转换或使用请求或响应中包含的信息。过滤器本身通常不会创建响应,而是提供可以“附加”到任何一次 RPC 请求的通用函数。Dubbo Filter 是可插拔的,我们可以在一次 RPC 请求中插入任意类型的、任意多个 Filter。 + +Filter 工作原理如下图所示: + + + + +## 使用方式 +### 1. Filter 拦截器概念 + +Filter 定义如下: + +```go +// Filter interface defines the functions of a filter +// Extension - Filter +type Filter interface { + // Invoke is the core function of a filter, it determines the process of the filter + Invoke(context.Context, protocol.Invoker, protocol.Invocation) protocol.Result + // OnResponse updates the results from Invoke and then returns the modified results. + OnResponse(context.Context, protocol.Result, protocol.Invoker, protocol.Invocation) protocol.Result +} +``` + +Filter 可以加载在 Consumer 端或者 Provider端。当加载在 Consumer 端,其Invoke函数调用的下游为网络层,OnResponse 为请求结束从网络层获取到返回结果后被调用。当加载在 Provider 端,其 Invoke 函数调用的下游为用户代码,OnResponse 为用户代码执行结束后向下传递至网络层前被调用。 + +Filter 采用面向切面设计的思路,通过对 Filter 的合理扩展,可以记录日志、设置数据打点,记录 invoker 所对应服务端性能,限流等等工作。 + +### 2. 框架预定义 Filter + +框架预定义了一系列filter,可以在配置中直接使用,其代码实现位于 [filter](https://github.com/apache/dubbo-go/tree/main/filter) + +- accesslog +- active +- sign: AuthConsumerFilter +- auth: AuthProviderFilter +- echo +- execute: ExecuteLimitFilter +- generic: GenericFilter +- generic_service: GenericServiceFilter +- pshutdown: GracefulShutdownProviderFilter +- cshutdown: GracefulShutdownConsumerFilter +- hystrix_consumer: HystrixConsumerFilter +- hystrix_provider: HystrixProviderFilter +- metrics +- seata +- sentinel-provider +- sentinel-consumer +- token +- tps +- tracing + +### 3. 默认加载Filter + +用户在配置文件中配置了自定义 Filter 加载策略时,框架将同时加载用户配置的 filters 和默认 filters,否则仅加载默认 filters。当前版本默认激活的 filter 列表如下: + +- Consumer: cshutdown +- Provider: echo, metrics, token, accesslog, tps, generic_service, executivete, pshutdown + +### 4. 自定义Filter + +用户可在代码中自定义 Filter,注册到框架上,并在配置中选择使用。 + +```go +func init() { + extension.SetFilter("myCustomFilter", NewMyClientFilter) +} + +func NewMyClientFilter() filter.Filter { + return &MyClientFilter{} +} + +type MyClientFilter struct { +} + +func (f *MyClientFilter) Invoke(ctx context.Context, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result { + fmt.Println("MyClientFilter Invoke is called, method Name = ", invocation.MethodName()) + return invoker.Invoke(ctx, invocation) +} +func (f *MyClientFilter) OnResponse(ctx context.Context, result protocol.Result, invoker protocol.Invoker, protocol protocol.Invocation) protocol.Result { + fmt.Println("MyClientFilter OnResponse is called") + return result +} +``` + +## 完整示例 +可通过以下链接学习如何使用 API 配置和启用 Filter 的 完整示例源码地址 + + diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/rpc/healthcheck.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/rpc/healthcheck.md new file mode 100644 index 000000000000..ec9b82a65f1f --- /dev/null +++ b/content/zh-cn/overview/mannual/golang-sdk/tutorial/rpc/healthcheck.md @@ -0,0 +1,95 @@ +--- +description: 健康检查 +title: 健康检查 +type: docs +weight: 3 +--- + +## 背景 + +Dubbo-go 内置了基于 triple 协议的健康检查服务,帮助用户管理和监测服务健康状态,可在此查看 完整示例源码。 + +## 使用方法 + +- 框架在通过 `instance` 启动后会自动向框架中注册健康检查服务 `grpc.health.v1.Health`,用于记录并对外暴露每个triple服务的健康状态。 +- 健康检查服务可以通过发起 http 请求检查框架中服务的状态,也可以通过客户端调用该健康检查服务,调用的接口为`grpc.health.v1.Health`,方法为 `check`。 + +## 1、通过客户端调用健康检查服务 + +启动 dubbo-go-samples/healthcheck/go-server 中的服务,通过下方客户端即可查看 `greet.GreetService` 的状态。 + +```go +package main + +import ( + "context" + "dubbo.apache.org/dubbo-go/v3/client" + _ "dubbo.apache.org/dubbo-go/v3/imports" + health "dubbo.apache.org/dubbo-go/v3/protocol/triple/health/triple_health" + "github.com/dubbogo/gost/log/logger" +) + +func main() { + cli, err := client.NewClient( + client.WithClientURL("tri://127.0.0.1:20000"), + ) + if err != nil { + panic(err) + } + svc, err := health.NewHealth(cli) + if err != nil { + panic(err) + } + check, err := svc.Check(context.Background(), &health.HealthCheckRequest{Service: "greet.GreetService"}) + if err != nil { + logger.Error(err) + } else { + logger.Info("greet.GreetService's health", check.String()) + } + watch, err := svc.Watch(context.Background(), &health.HealthCheckRequest{Service: "greet.GreetService"}) + if err != nil { + logger.Error(err) + } else { + if watch.Recv() { + logger.Info("greet.GreetService's health", watch.Msg().String()) + } + } +} +``` + +启动后会有以下输出 + +```sh +[greet.GreetService's health status:SERVING] +[greet.GreetService's health status:SERVING] +``` + +## 2.通过发起http请求检查服务健康状态 + +启动 dubbo-go-samples/healthcheck/go-server 中的服务,发起下方http请求即可查看 `greet.GreetService` 的状态: + +```http +POST /grpc.health.v1.Health/Check +Host: 127.0.0.1:20000 +Content-Type: application/json + +{"service":"greet.GreetService"} +``` + +将会有以下输出 + +```http +{ + "status": "SERVING" +} +``` + + +## 更多内容 +值得注意的是,当前框架中尚未建立完整的服务状态管理机制,dubbo-go 框架会将所有加载的服务设置为 `SERVING` 状态,但尚没有 `NOT SERVING` 设置机制(在满足某个特定条件的情况下将服务状态设置为 NOT SERVING)。 + +如果有需要,用户可通过扩展 dubbo-go 框架的方式,提供完整的服务状态管理能力,这样就可以查询到实时更新的服务状态,并根据服务状态进行流量转发。 + +部分参考资料: ++ https://github.com/grpc/grpc/blob/master/doc/health-checking.md ++ https://github.com/grpc/grpc-go/tree/master/health diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/rpc/protocol.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/rpc/protocol.md new file mode 100644 index 000000000000..d45d451e844b --- /dev/null +++ b/content/zh-cn/overview/mannual/golang-sdk/tutorial/rpc/protocol.md @@ -0,0 +1,143 @@ +--- +description: 配置通信协议 +title: 通信协议 +linkTitle: 通信协议 +type: docs +weight: 3 +--- + +Dubbo-go 框架内置提供了两款协议:triple、dubbo,除此之外,框架还提供了多种协议扩展接入方式。 +* triple,基于 HTTP/1、HTTP/2 的高性能通信协议,100% 兼容 gRPC,支持 Unary、Streming 等通信模式;支持发布 REST 风格的 HTTP 服务。 + * dubbo,基于 TCP 的高性能私有通信协议,缺点是通用性较差,更适合在 Dubbo SDK 间使用; + * 任意协议扩展,通过扩展 protocol 可以之前任意 RPC 协议,官方生态库提供 JsonRPC、thrift 等支持。 + +本篇文档中,我们将介绍关于 triple 协议的使用方式、如何实现与已有 dubbo2 系统的互相调用、扩展更多协议支持等。更多原理性介绍请参考 [协议规范](/zh-cn/overview/reference/protocols/triple-spec/) 或者 [dubbo java 中相关描述文档](/zh-cn/overview/mannual/java-sdk/tasks/protocols/protocol/)。 + +## triple 协议 +triple 协议支持使用 protobuf 和 non-protobuf 两种开发模式,我们 **推荐使用 protobuf 模式开发服务**。 + +目前我们大部分示例都是使用这个模式开发,可查看 [快速开始](/zh-cn/overview/mannual/golang-sdk/quickstart/rpc/) 学习完整开发示例,以下是基本步骤: + +1. 先使用 protobuf 定义服务 + +```protobuf +syntax = "proto3"; +package greet; +option go_package = "github.com/apache/dubbo-go-samples/helloworld/proto;greet"; + +message GreetRequest { + string name = 1; +} + +message GreetResponse { + string greeting = 1; +} + +service GreetService { + rpc Greet(GreetRequest) returns (GreetResponse) {} +} +``` + +2. [安装 protoc 插件](/zh-cn/overview/mannual/golang-sdk/quickstart/rpc/#前置条件),编译生成代码: +```shell +protoc --go_out=. --go_opt=paths=source_relative \ + --go-triple_out=. --go-triple_opt=paths=source_relative \ + proto/greet.proto +``` + +3. server 端发布服务 +```go +srv, err := server.NewServer( + server.WithServerProtocol( + protocol.WithPort(20000), + protocol.WithTriple(), + ), +) + +greet.RegisterGreetServiceHandler(srv, &GreetTripleServer{}) +``` + +4. client 端调用服务 +```go +cli, err := client.NewClient( + client.WithClientURL("127.0.0.1:20000"), +) + +svc, err := greet.NewGreetService(cli) +resp, err := svc.Greet(context.Background(), &greet.GreetRequest{Name: "hello world"}) +``` + +## dubbo-java 体系互调 + +如果 java 和 go 都使用 triple+protobuf 模式,很明显他们是可以直接互调通信的。 + +但问题是很多 java 用户是使用的 triple non-protobuf 模式,还有一些老版本用户是使用的 dubbo tcp 协议。对于这部分业务,我们要可以使用 dubbo-go 框架的以下编码模式实现协议互调: + +1. 定义服务 + +直接使用 struct 定义服务: + +```go +type GreetProvider struct { +} + +func (*GreetProvider) SayHello(req string, req1 string, req2 string) (string, error) { + return req + req1 + req2, nil +} +``` + +2. server 发布服务 + +指定要发布的协议,可以是 dubbo、triple 或其他协议,请注意 `WithInterface("GreetProvider")` 要保持和 dubbo-java 侧的服务名一致(如保持 java 全路径名): + +```go +ins, err := dubbo.NewInstance( + dubbo.WithName("dubbo_server"), + dubbo.WithProtocol( + protocol.WithTriple(), + protocol.WithPort(20001)), +) + +srvDubbo, err := ins.NewServer() +if err != nil { + panic(err) +} +if err = srvDubbo.Register(&GreetProvider{}, nil, server.WithInterface("GreetProvider")); err != nil { + panic(err) +} +if err = srvDubbo.Serve(); err != nil { + logger.Error(err) +} +``` + +3. client 调用服务 + +指定要调用的协议,可以是 dubbo、triple 或其他协议,请注意 `WithInterface("GreetProvider")` 要保持和 dubbo-java 侧的服务名一致(如保持 java 全路径名): + +```go +cliDubbo, _ := client.NewClient( + client.WithClientProtocolTriple(), + client.WithClientSerialization(constant.Hessian2Serialization), +) + +connDubbo, _ := cliDubbo.Dial("GreetProvider") +ipanic(err) +} +var respDubbo string +if err = connDubbo.CallUnary(context.Background(), []interface{}{"hello", "new", "dubbo"}, &respDubbo, "SayHello"); err != nil { + logger.Errorf("GreetProvider.Greet err: %s", err) + return +} +``` + +## 协议扩展 + +Dubbo 框架支持协议扩展,目前官方生态支持的协议包括: +* triple +* dubbo +* jsonrpc + + +在一些场景下,你可以在一个应用内同时发布多个协议的服务,或者同时以不同的协议调用服务,这里有一个 [多协议发布的使用示例](https://github.com/apache/dubbo-go-samples/tree/main/multirpc) 供参考。 + + diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/rpc/retry.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/rpc/retry.md new file mode 100644 index 000000000000..f8d37d326dce --- /dev/null +++ b/content/zh-cn/overview/mannual/golang-sdk/tutorial/rpc/retry.md @@ -0,0 +1,185 @@ +--- +description: 请求重试 +title: 请求重试 +type: docs +weight: 3 +--- + +当一次服务调用失败时,我们可以让框架选择自动重试几次,这样能提高用户侧看到的请求成功率。在 failover cluster 模式下 dubbo-go 支持自动重试。 + +## 1.介绍 + +本示例演示如何在 client 端调用失败时配置重试功能,完整示例源码地址 + +## 2.如何使用重试功能 + +在使用 `client.NewClient()` 创建客户端时,可以使用 `client.WithClientRetries()` 方法设置重试次数。 + +```go +cli, err := client.NewClient( + client.WithClientURL("tri://127.0.0.1:20000"), + client.WithClientRetries(3), +) +``` + +或者,可以使用 `client.WithRequestTimeout()` 设置服务粒度的超时时间(以下配置对服务 `svc` 起作用)。 + +```go +svc, err := greet.NewGreetService(cli, client.WithClientRetries(5)) +``` + +也可以在调用发起时,使用 `client.WithCallRetries()` 指定重试次数 + +```go +resp, err := svc.Greet(context.Background(), &greet.GreetRequest{Name: "hello world"}, client.WithCallRetries(6)) +``` + +从上往下,以上三种方式的优先级逐步提高,`client.WithCallRetries()` 指定的重试次数优先级最高。 + + +## 3.示例解读 + +### 3.1服务端介绍 + +#### 服务端proto文件 + +源文件路径:dubbo-go-sample/retry/proto/greet.proto + +```protobuf +syntax = "proto3"; + +package greet; + +option go_package = "github.com/apache/dubbo-go-samples/retry/proto;greet"; + +message GreetRequest { + string name = 1; +} + +message GreetResponse { + string greeting = 1; +} + +service GreetService { + rpc Greet(GreetRequest) returns (GreetResponse) {} + rpc GreetTimeout(GreetRequest) returns (GreetResponse) {} +} +``` + +#### 服务端handler文件 + +`Greet`方法直接响应,`GreetRetry`方法用于模拟重试。 +```go +package main + +import ( + "context" + "github.com/pkg/errors" + + _ "dubbo.apache.org/dubbo-go/v3/imports" + "dubbo.apache.org/dubbo-go/v3/protocol" + "dubbo.apache.org/dubbo-go/v3/server" + greet "github.com/apache/dubbo-go-samples/retry/proto" + "github.com/dubbogo/gost/log/logger" +) + +type GreetTripleServer struct { + requestTime int +} + +func (srv *GreetTripleServer) Greet(ctx context.Context, req *greet.GreetRequest) (*greet.GreetResponse, error) { + resp := &greet.GreetResponse{Greeting: req.Name} + logger.Info("Not need retry, request success") + return resp, nil +} + +func (srv *GreetTripleServer) GreetRetry(ctx context.Context, req *greet.GreetRequest) (*greet.GreetResponse, error) { + if srv.requestTime < 3 { + srv.requestTime++ + logger.Infof("retry %d times", srv.requestTime) + return nil, errors.New("retry") + } + resp := &greet.GreetResponse{Greeting: req.Name} + logger.Infof("retry success, current request time is %d", srv.requestTime) + srv.requestTime = 0 + return resp, nil +} + +func main() { + srv, err := server.NewServer( + server.WithServerProtocol( + protocol.WithPort(20000), + ), + ) + if err != nil { + panic(err) + } + if err := greet.RegisterGreetServiceHandler(srv, &GreetTripleServer{ + requestTime: 0, + }); err != nil { + panic(err) + } + if err := srv.Serve(); err != nil { + logger.Error(err) + } +} + +``` + +### 3.2客户端介绍 + +客户端client文件,创建客户端,设置重试次数为3,分别请求`Greet`和`GreetRetry`,观察服务端日志输出。 + +```go +package main + +import ( + "context" + + "dubbo.apache.org/dubbo-go/v3/client" + _ "dubbo.apache.org/dubbo-go/v3/imports" + greet "github.com/apache/dubbo-go-samples/retry/proto" + "github.com/dubbogo/gost/log/logger" +) + +func main() { + cli, err := client.NewClient( + client.WithClientURL("tri://127.0.0.1:20000"), + client.WithClientRetries(3), + ) + if err != nil { + panic(err) + } + + svc, err := greet.NewGreetService(cli) + if err != nil { + panic(err) + } + + // request normal + resp, err := svc.Greet(context.Background(), &greet.GreetRequest{Name: "hello world"}) + if err != nil { + logger.Error(err) + } + logger.Infof("Greet response: %s", resp.Greeting) + + // request need retry + resp, err = svc.GreetRetry(context.Background(), &greet.GreetRequest{Name: "hello world"}) + if err != nil { + logger.Error(err) + } + logger.Infof("Greet response: %s", resp.Greeting) +} +``` + +### 3.3案例效果 + +先启动服务端,再启动客户端,访问`GreetRetry`时观察到服务端日志输出了重试次数。 + +``` +2024-01-23 22:39:11 INFO logger/logging.go:22 [Not need retry, request success] +2024-01-23 22:39:11 INFO logger/logging.go:42 retry [1] times +2024-01-23 22:39:11 INFO logger/logging.go:42 retry [2] times +2024-01-23 22:39:11 INFO logger/logging.go:42 retry [3] times +2024-01-23 22:39:11 INFO logger/logging.go:42 retry success, current request time is [3] +``` \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/rpc/start-check.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/rpc/start-check.md new file mode 100644 index 000000000000..3925a17a2b63 --- /dev/null +++ b/content/zh-cn/overview/mannual/golang-sdk/tutorial/rpc/start-check.md @@ -0,0 +1,43 @@ +--- +aliases: + - /zh/docs3-v2/golang-sdk/tutorial/governance/health/start-check/ + - /zh-cn/docs3-v2/golang-sdk/tutorial/governance/health/start-check/ + - /zh-cn/overview/mannual/golang-sdk/tutorial/governance/health/start-check/ +description: "缺省会在启动时检查依赖的服务是否可用(注册中心是否有可用地址),不可用时会抛出异常,阻止应用初始化完成。" +keywords: 启动时检查 +title: 启动时检查 +type: docs +weight: 4 +--- + +Dubbo 框架缺省会在启动时检查依赖的服务是否可用(注册中心是否有可用地址),不可用时会抛出异常,阻止应用初始化完成,以便上线时,能及早发现问题,默认 check="true",并等待3s。 + +可以通过 check="false" 关闭检查,比如,测试时,有些服务不关心,或者出现了循环依赖,必须有一方先启动。 + +关闭 check 后,请注意 provider数量比较多时, consumer 订阅 provider 生成服务地址可能会有一定延迟,如果 consumer 一启动就对外提供服务,可能会造成"冷启动"。所以在这个时候,请对服务进行预热。 + +示例: + +```yaml +dubbo: + consumer: + check : false + reference: + myserivce: + check: true +``` + +或者 + +```go +cli, err := client.NewClient( + client.WithClientCheck(false), +) +``` + +或者 + +```go +svc, err := health.NewHealth(cli) +svc.Check(context.Background(), &health.HealthCheckRequest{Service: "greet.GreetService"}, client.WithCheck(false)) +``` diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/rpc/streaming.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/rpc/streaming.md new file mode 100644 index 000000000000..54d704db18d5 --- /dev/null +++ b/content/zh-cn/overview/mannual/golang-sdk/tutorial/rpc/streaming.md @@ -0,0 +1,216 @@ +--- +description: 流式通信 streaming +title: 流式通信 +type: docs +weight: 1 +--- +Streaming 流式通信是 Dubbo3 新提供的一种 RPC 数据传输模式,适用于以下场景: + +- 接口需要发送大量数据,这些数据无法被放在一个 RPC 的请求或响应中,需要分批发送,但应用层如果按照传统的多次 RPC 方式无法解决顺序和性能的问题,如果需要保证有序,则只能串行发送 +- 流式场景,数据需要按照发送顺序处理, 数据本身是没有确定边界的 +- 推送类场景,多个消息在同一个调用的上下文中被发送和处理 + +Streaming 流式通信类型分为以下三种: +- SERVER_STREAM(服务端流) +- CLIENT_STREAM(客户端流) +- BIDIRECTIONAL_STREAM(双向流) + +## 1.介绍 + +本文档演示如何在 Dubbo-go 中使用流式通信,可在此查看 完整示例源码地址。 + +## 2.如何使用Dubbo-go流式通信 + +在proto文件中需要流式通信的方法的参数前面添加stream,使用proto-gen-triple生成相应文件 + +```protobuf +service GreetService { + rpc Greet(GreetRequest) returns (GreetResponse) {} + rpc GreetStream(stream GreetStreamRequest) returns (stream GreetStreamResponse) {} + rpc GreetClientStream(stream GreetClientStreamRequest) returns (GreetClientStreamResponse) {} + rpc GreetServerStream(GreetServerStreamRequest) returns (stream GreetServerStreamResponse) {} +} +``` + +编写服务端handler文件 + +源文件路径: dubbo-go-sample/streaming/go-server/cmd/server.go + +```go +type GreetTripleServer struct { +} + +func (srv *GreetTripleServer) Greet(ctx context.Context, req *greet.GreetRequest) (*greet.GreetResponse, error) { + resp := &greet.GreetResponse{Greeting: req.Name} + return resp, nil +} + +func (srv *GreetTripleServer) GreetStream(ctx context.Context, stream greet.GreetService_GreetStreamServer) error { + for { + req, err := stream.Recv() + if err != nil { + if triple.IsEnded(err) { + break + } + return fmt.Errorf("triple BidiStream recv error: %s", err) + } + if err := stream.Send(&greet.GreetStreamResponse{Greeting: req.Name}); err != nil { + return fmt.Errorf("triple BidiStream send error: %s", err) + } + } + return nil +} + +func (srv *GreetTripleServer) GreetClientStream(ctx context.Context, stream greet.GreetService_GreetClientStreamServer) (*greet.GreetClientStreamResponse, error) { + var reqs []string + for stream.Recv() { + reqs = append(reqs, stream.Msg().Name) + } + if stream.Err() != nil && !triple.IsEnded(stream.Err()) { + return nil, fmt.Errorf("triple ClientStream recv err: %s", stream.Err()) + } + resp := &greet.GreetClientStreamResponse{ + Greeting: strings.Join(reqs, ","), + } + + return resp, nil +} + +func (srv *GreetTripleServer) GreetServerStream(ctx context.Context, req *greet.GreetServerStreamRequest, stream greet.GreetService_GreetServerStreamServer) error { + for i := 0; i < 5; i++ { + if err := stream.Send(&greet.GreetServerStreamResponse{Greeting: req.Name}); err != nil { + return fmt.Errorf("triple ServerStream send err: %s", err) + } + } + return nil +} +``` + +编写客户端client文件 + +源文件路径: dubbo-go-sample/streaming/go-client/cmd/client.go + +```go +func main() { + cli, err := client.NewClient( + client.WithClientURL("tri://127.0.0.1:20000"), + ) + if err != nil { + panic(err) + } + + svc, err := greet.NewGreetService(cli) + if err != nil { + panic(err) + } + TestClient(svc) +} + +func TestClient(cli greet.GreetService) { + if err := testUnary(cli); err != nil { + logger.Error(err) + } + + if err := testBidiStream(cli); err != nil { + logger.Error(err) + } + + if err := testClientStream(cli); err != nil { + logger.Error(err) + } + + if err := testServerStream(cli); err != nil { + logger.Error(err) + } +} + +func testUnary(cli greet.GreetService) error { + logger.Info("start to test TRIPLE unary call") + resp, err := cli.Greet(context.Background(), &greet.GreetRequest{Name: "triple"}) + if err != nil { + return err + } + logger.Infof("TRIPLE unary call resp: %s", resp.Greeting) + return nil +} + +func testBidiStream(cli greet.GreetService) error { + logger.Info("start to test TRIPLE bidi stream") + stream, err := cli.GreetStream(context.Background()) + if err != nil { + return err + } + if sendErr := stream.Send(&greet.GreetStreamRequest{Name: "triple"}); sendErr != nil { + return err + } + resp, err := stream.Recv() + if err != nil { + return err + } + logger.Infof("TRIPLE bidi stream resp: %s", resp.Greeting) + if err := stream.CloseRequest(); err != nil { + return err + } + if err := stream.CloseResponse(); err != nil { + return err + } + return nil +} + +func testClientStream(cli greet.GreetService) error { + logger.Info("start to test TRIPLE client stream") + stream, err := cli.GreetClientStream(context.Background()) + if err != nil { + return err + } + for i := 0; i < 5; i++ { + if sendErr := stream.Send(&greet.GreetClientStreamRequest{Name: "triple"}); sendErr != nil { + return err + } + } + resp, err := stream.CloseAndRecv() + if err != nil { + return err + } + logger.Infof("TRIPLE client stream resp: %s", resp.Greeting) + return nil +} + +func testServerStream(cli greet.GreetService) error { + logger.Info("start to test TRIPLE server stream") + stream, err := cli.GreetServerStream(context.Background(), &greet.GreetServerStreamRequest{Name: "triple"}) + if err != nil { + return err + } + for stream.Recv() { + logger.Infof("TRIPLE server stream resp: %s", stream.Msg().Greeting) + } + if stream.Err() != nil { + return err + } + if err := stream.Close(); err != nil { + return err + } + return nil +} +``` + +## 3.运行效果 + +运行服务端和客户端,可以看到请求正常返回 + +``` +[start to test TRIPLE unary call] +TRIPLE unary call resp: [triple] +[start to test TRIPLE bidi stream] +TRIPLE bidi stream resp: [triple] +[start to test TRIPLE client stream] +TRIPLE client stream resp: [triple,triple,triple,triple,triple] +[start to test TRIPLE server stream] +TRIPLE server stream resp: [triple] +TRIPLE server stream resp: [triple] +TRIPLE server stream resp: [triple] +TRIPLE server stream resp: [triple] +TRIPLE server stream resp: [triple] +``` + diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/rpc/timeout.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/rpc/timeout.md new file mode 100644 index 000000000000..2b709287ffb1 --- /dev/null +++ b/content/zh-cn/overview/mannual/golang-sdk/tutorial/rpc/timeout.md @@ -0,0 +1,155 @@ +--- +description: 配置超时时间 +title: 超时时间 +type: docs +weight: 2 +--- + +## 1.介绍 + +本示例演示如何在 Dubbo-go 客户端发起调用时设置请求超时时间。可在此查看 完整示例源码地址 + +## 2.如何设置请求超时时间 + +在创建客户端时,可以使用 `client.WithRequestTimeout()` 方法设置全局超时时间(所有使用改 client 的服务代理共享)。 + +```go + cli, err := client.NewClient( + client.WithClientURL("tri://127.0.0.1:20000"), + client.WithClientRequestTimeout(3 * time.Second), + ) +``` + +可以使用 `client.WithRequestTimeout()` 创建服务粒度的超时时间(以下服务代理 `svc` 发起的方法调用都使用这个时间)。 + +```go + svc, err := greet.NewGreetService(cli, client.WithRequestTimeout(5 * time.Second)) +``` + +也可以在调用发起时,使用 `client.WithCallRequestTimeout()` 指定一个超时时间 + +```go +resp, err := svc.GreetTimeout(context.Background(), &greet.GreetRequest{Name: "hello world"}, client.WithCallRequestTimeout(10 * time.Second)) +``` + +从上往下,以上三种方式的优先级逐步提高,`client.WithCallRequestTimeout()` 指定的超时时间优先级最高。 + +## 3.示例详解 + +### 3.1服务端介绍 + +#### 服务端proto文件 + +源文件路径:dubbo-go-sample/timeout/proto/greet.proto + +```protobuf +syntax = "proto3"; + +package greet; + +option go_package = "github.com/apache/dubbo-go-samples/timeout/proto;greet"; + +message GreetRequest { + string name = 1; +} + +message GreetResponse { + string greeting = 1; +} + +service GreetService { + rpc Greet(GreetRequest) returns (GreetResponse) {} + rpc GreetTimeout(GreetRequest) returns (GreetResponse) {} +} +``` + +#### 服务端handler文件 + +`Greet`方法直接响应,`GreetTimeout`方法等待五秒后响应(模拟超时)。 + +源文件路径:dubbo-go-sample/timeout/go-server/handler.go + +```go +package main + +import ( + "context" + "time" + + greet "github.com/apache/dubbo-go-samples/timeout/proto" +) + +type GreetTripleServer struct { +} + +func (srv *GreetTripleServer) Greet(ctx context.Context, req *greet.GreetRequest) (*greet.GreetResponse, error) { + resp := &greet.GreetResponse{Greeting: req.Name} + return resp, nil +} + +func (srv *GreetTripleServer) GreetTimeout(ctx context.Context, req *greet.GreetRequest) (*greet.GreetResponse, error) { + time.Sleep(5 * time.Second) + resp := &greet.GreetResponse{Greeting: req.Name} + return resp, nil +} +``` + +### 3.2客户端介绍 + +客户端client文件,创建客户端,设置超时时间为3s,分别请求`Greet`和`GreetTimeout`,输出响应结果。 + +源文件路径:dubbo-go-sample/timeout/go-client/client.go + +```go +package main + +import ( + "context" + "time" + + "dubbo.apache.org/dubbo-go/v3/client" + _ "dubbo.apache.org/dubbo-go/v3/imports" + greet "github.com/apache/dubbo-go-samples/timeout/proto" + "github.com/dubbogo/gost/log/logger" +) + +func main() { + cli, err := client.NewClient( + client.WithClientURL("tri://127.0.0.1:20000"), + client.WithClientRequestTimeout(3*time.Second), + ) + if err != nil { + panic(err) + } + + svc, err := greet.NewGreetService(cli) + if err != nil { + panic(err) + } + + // test timeout + resp, err := svc.GreetTimeout(context.Background(), &greet.GreetRequest{Name: "hello world"}) + if err != nil { + logger.Error("call [greet.GreetService.GreetTimeout] service timeout") + logger.Error(err) + } else { + logger.Infof("Greet response: %s", resp.Greeting) + } + + // test normal + resp, err = svc.Greet(context.Background(), &greet.GreetRequest{Name: "hello world"}) + if err != nil { + logger.Error(err) + } + logger.Infof("Greet response: %s", resp.Greeting) +} +``` + +### 3.3案例效果 + +先启动服务端,再启动客户端,可以观察到`GreetTimeout`请求响应超时,`Greet`请求响应正常 + +``` +[call [greet.GreetService.GreetTimeout] service timeout] +Greet response: [hello world] +``` diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/service-discovery/_index.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/service-discovery/_index.md new file mode 100755 index 000000000000..ebd30961f991 --- /dev/null +++ b/content/zh-cn/overview/mannual/golang-sdk/tutorial/service-discovery/_index.md @@ -0,0 +1,11 @@ +--- +aliases: + - /zh/docs3-v2/golang-sdk/tutorial/debugging/ + - /zh-cn/docs3-v2/golang-sdk/tutorial/debugging/ + - /zh-cn/overview/mannual/golang-sdk/tutorial/develop/registry/ + - /zh-cn/overview/mannual/golang-sdk/tutorial/develop/registry/service-discovery/ +description: "使用 Nacos、Zookeeper 等作为注册中心,实现地址变更的自动发现。" +title: 地址发现 +type: docs +weight: 20 +--- diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/service-discovery/multi_registry.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/service-discovery/multi_registry.md new file mode 100644 index 000000000000..33e7090a585c --- /dev/null +++ b/content/zh-cn/overview/mannual/golang-sdk/tutorial/service-discovery/multi_registry.md @@ -0,0 +1,86 @@ +--- +aliases: + - /zh/docs3-v2/golang-sdk/tutorial/develop/registry/multi_registry/ + - /zh-cn/docs3-v2/golang-sdk/tutorial/develop/registry/multi_registry/ +description: 多注册中心 +title: 多注册中心 +type: docs +weight: 100 +--- + +一个 Dubbo 应用可以配置的多个接口维度的注册中心,多注册中心可用于集群隔离、迁移等多种场景,关于这部分更详细的说明可参考 Dubbo Java 多注册中心说明。 + +## API配置方式 + +```go +ins, _ := dubbo.NewInstance( + dubbo.WithRegistry( + registryWithID("nacos"), + registry.WithNacos(), + registry.WithAddress("127.0.0.1:8848"), + ), + dubbo.WithRegistry( + registryWithID("zookeeper"), + registry.WithZookeeper(), + registry.WithAddress("127.0.0.1:2181"), + ), +) + +``` + +指定某个 server 下的服务注册到哪个注册中心: +```go +// 指定 server 下的服务注册到 zookeeper 注册中心 +srv, _ := ins.NewServer(server.WithServerRegistryIDs([]string{"zookeeper"})) + +// 指定 server 下的服务注册到 nacos 注册中心 +srv2, _ := ins.NewServer(server.WithServerRegistryIDs([]string{"nacos"})) +``` + +指定某个特定服务注册到哪个注册中心: +```go +srv, _ := ins.NewServer() + +greet.RegisterGreetServiceHandler(srv, &GreetTripleServer{}, server.WithRegistryIDs([]string{"zookeeper"})) +``` + +以上使用方式对 client 侧类似。 + +## YAML配置方式 + +修改服务端配置 go-server/conf/dubbogo.yaml, 同时将服务注册在两个注册中心上。 + +```yaml +dubbo: + registries: + zookeeper: # 指定 zookeeper 注册中心 + protocol: zookeeper + address: 127.0.0.1:2181 + nacos: # 指定 nacos 注册中心 + protocol: nacos + address: 127.0.0.1:8848 + protocols: + triple: + name: tri + port: 20000 +``` + +## 支持的注册中心 +* Nacos +* Zookeeper +* Polaris +* Kubernetes + +比如使用 Polaris 作为注册中心时,你需要指定以下内容,使用 API 或 YAML 配置文件均可以: + +```yaml +dubbo: + registries: + polarisMesh: + protocol: polaris + address: ${北极星服务端IP}:8091 + namespace: ${北极星命名空间信息} + token: ${北极星资源鉴权 token} # 如果北极星服务端开启了针对客户端的鉴权,则需要配置该参数 +``` + +对于 Kubernetes 注册中心的使用方式,请参考 [控制面](/zh-cn/overview/mannual/control-plane/) 文档。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/service-discovery/nacos.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/service-discovery/nacos.md new file mode 100644 index 000000000000..f5369961011d --- /dev/null +++ b/content/zh-cn/overview/mannual/golang-sdk/tutorial/service-discovery/nacos.md @@ -0,0 +1,58 @@ +--- +aliases: + - /zh/docs3-v2/golang-sdk/tutorial/develop/registry/nacos-2/ + - /zh-cn/docs3-v2/golang-sdk/tutorial/develop/registry/nacos-2/ +description: 使用 Nacos 作为注册中心 +title: 使用 Nacos 作为注册中心 +type: docs +weight: 10 +--- + + +This example shows dubbo-go's service discovery feature with Nacos as registry. + +## 使用方式 + +通过以下方式指定注册中心地址: + +```go +ins, _ := dubbo.NewInstance( + dubbo.WithName("dubbo_registry_nacos_server"), + dubbo.WithRegistry( + registry.WithNacos(), + registry.WithAddress("127.0.0.1:8848"), + ), + dubbo.WithProtocol( + protocol.WithTriple(), + protocol.WithPort(20000), + ), +) + +srv, err := ins.NewServer() +``` + +## How to run + +### Start Nacos server +Follow this instruction to [install and start Nacos server](/zh-cn/overview/reference/integrations/nacos/). + +### Run server +```shell +$ go run ./go-server/cmd/server.go +``` + +test rpc server work as expected: +```shell +$ curl \ + --header "Content-Type: application/json" \ + --data '{"name": "Dubbo"}' \ + http://localhost:20000/greet.GreetService/Greet +``` + +Open `https://localhost:8848/nacos/` with browser, check url address successfully registered into Nacos. + +### Run client +```shell +$ go run ./go-client/cmd/client.go +hello world +``` \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/service-discovery/zookeeper.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/service-discovery/zookeeper.md new file mode 100644 index 000000000000..257c969da340 --- /dev/null +++ b/content/zh-cn/overview/mannual/golang-sdk/tutorial/service-discovery/zookeeper.md @@ -0,0 +1,68 @@ +--- +aliases: + - /zh/docs3-v2/golang-sdk/tutorial/develop/registry/zookeeper/ + - /zh-cn/docs3-v2/golang-sdk/tutorial/develop/registry/zookeeper/ +description: 使用 Zookeeper 作为注册中心 +title: 使用 Zookeeper 作为注册中心 +type: docs +weight: 11 +--- + + +This example shows dubbo-go's service discovery feature with Zookeeper as registry. + +## 使用方式 + +通过以下方式指定注册中心地址: + +```go +ins, _ := dubbo.NewInstance( + dubbo.WithName("dubbo_registry_nacos_server"), + dubbo.WithRegistry( + registry.WithZookeeper(), + registry.WithAddress("127.0.0.1:2181"), + ), + dubbo.WithProtocol( + protocol.WithTriple(), + protocol.WithPort(20000), + ), +) + +srv, err := ins.NewServer() +``` + +## How to run + +### Start Zookeeper server +This example relies on zookeeper as registry, follow the steps below to start a zookeeper server first. + +1. Start zookeeper with docker, run `docker run --rm -p 2181:2181 zookeeper` or `make -f $DUBBO_GO_SAMPLES_ROOT_PATH/build/Makefile docker-up`. +2. [Download and start zookeeper](https://zookeeper.apache.org/releases.html#download) locally on your machine. + +### Run server +```shell +$ go run ./go-server/cmd/server.go +``` + +test rpc server work as expected: +```shell +$ curl \ + --header "Content-Type: application/json" \ + --data '{"name": "Dubbo"}' \ + http://localhost:20000/greet.GreetService/Greet +``` + +check url address successfully registered into zookeeper: +```shell +# enter zookeeper bin directory, for example '$HOST_PATH/apache-zookeeper-3.5.9-bin/bin' +$ ./zkCli.sh +[zk: localhost:2181(CONNECTED) 0] ls /services/dubbo_registry_zookeeper_server +[30.221.147.198:20000] +``` + +### Run client +```shell +$ go run ./go-client/cmd/client.go +hello world +``` + diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/traffic/_index.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/traffic/_index.md new file mode 100755 index 000000000000..7556e4519c4d --- /dev/null +++ b/content/zh-cn/overview/mannual/golang-sdk/tutorial/traffic/_index.md @@ -0,0 +1,9 @@ +--- +aliases: + - /zh/docs3-v2/golang-sdk/tutorial/debugging/ + - /zh-cn/docs3-v2/golang-sdk/tutorial/debugging/ +description: "通过下发路由规则实现流量管控,包括按比例流量转发、参数路由、灰度发布、动态调整超时时间等。" +title: 流量管控 +type: docs +weight: 60 +--- diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/traffic/router.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/traffic/router.md new file mode 100644 index 000000000000..31b2e5b3190f --- /dev/null +++ b/content/zh-cn/overview/mannual/golang-sdk/tutorial/traffic/router.md @@ -0,0 +1,11 @@ +--- +aliases: + - /zh/docs3-v2/golang-sdk/tutorial/governance/traffic/mesh_router/ + - /zh-cn/docs3-v2/golang-sdk/tutorial/governance/traffic/mesh_router/ + - /zh-cn/overview/mannual/golang-sdk/tutorial/governance/traffic/mesh_router/ +description: 路由规则 +title: 路由规则 +type: docs +weight: 1 +--- + diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/traffic/sentinel.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/traffic/sentinel.md new file mode 100644 index 000000000000..852b183f0ef5 --- /dev/null +++ b/content/zh-cn/overview/mannual/golang-sdk/tutorial/traffic/sentinel.md @@ -0,0 +1,35 @@ +--- +description: "基于 Sentinel 的流量" +title: Sentinel限流降级 +type: docs +weight: 3 +--- + +Dubbo-go 中提供了内置的限流组件,用户可根据自己的业务场景调整限流值、限流后的行为等,具体可 [TpsLimiter](https://github.com/apache/dubbo-go/blob/main/filter/tps_limiter.go#L52) 定义与具体实现。用户可通过类似以下方式在服务端设置简单的限流策略: + +```go +server.WithTpsLimiter("method-service") // 目前支持 method-service、polaris 等几个实现 +server.WithTpsLimiterXxx() // 设置限流相关阈值,请根据具体方法填写 +//tps.limit.strategy: "slidingWindow" +//tps.limit.rejected.handler: "default" +//tps.limit.interval: 1000 +//tps.limit.rate: 3 +``` + +Dubbo-go 内置限流策略相对简单,对于一些更复杂的场景,我们建议通过使用 Sentinel 等专业的第三方框架可以实现更丰富、更灵活的限流策略。 + +可在此查看 [本示例完整源码](https://github.com/apache/dubbo-go-samples/tree/main/filter/sentinel),也可以参考 [Dubbo+Sentinel 的 Java 示例](/zh-cn/overview/mannual/java-sdk/tasks/rate-limit/sentinel/) 获得更多灵感。 + +## Provider 限流 + +### 基于 QpS 限流 + +### 基于并发任务数限流(当前在运行任务数) + +## Consumer 限流 + +### 熔断策略 + + + +### 基于并发请求数限流(未收到响应的请求数) \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/transaction/_index.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/transaction/_index.md new file mode 100755 index 000000000000..618f9655b669 --- /dev/null +++ b/content/zh-cn/overview/mannual/golang-sdk/tutorial/transaction/_index.md @@ -0,0 +1,7 @@ +--- +description: "Dubbo 分布式事务解决方案。" +title: 分布式事务 +type: docs +weight: 62 +--- + diff --git a/content/zh-cn/overview/mannual/golang-sdk/tutorial/transaction/seata.md b/content/zh-cn/overview/mannual/golang-sdk/tutorial/transaction/seata.md new file mode 100644 index 000000000000..63fb1bfc8792 --- /dev/null +++ b/content/zh-cn/overview/mannual/golang-sdk/tutorial/transaction/seata.md @@ -0,0 +1,18 @@ +--- +description: "使用 Seata 分布式事务解决方案解决 Dubbo 数据一致性问题。" +title: Seata分布式事务 +type: docs +weight: 1 +--- + +1. 先执行以下命令,启动 seata-server。 + + ```shell + cd ../dockercompose + docker-compose -f docker-compose.yml up -d seata-server + ``` + +2. 再执行 triple/client/cmd 和 triple/server/cmd 目录下的 main()方法。 + + +完整示例源码地址 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/golang-sdk/versions.md b/content/zh-cn/overview/mannual/golang-sdk/versions.md new file mode 100644 index 000000000000..e5e5c394f6bd --- /dev/null +++ b/content/zh-cn/overview/mannual/golang-sdk/versions.md @@ -0,0 +1,41 @@ +--- +aliases: + - /zh/docs3-v2/golang-sdk/refer/compatible_version/ + - /zh-cn/docs3-v2/golang-sdk/refer/compatible_version/ + - /zh-cn/overview/mannual/golang-sdk/preface/refer/compatible_version/ +description: 依赖适配版本号 +title: 版本信息 +type: docs +weight: 1 +--- + +## 推荐版本 +当前网站文档适用于以下版本,如果您正使用 dubbo-go 其他版本,请参考对应历史版本文档。 + +| Go | Dubbo-go | protoc-gen-go-triple | 说明 | +| :--: | ------------ | -------------------- | -------------------- | +| 1.20 | v3.2.0-rc1(当前文档) | v3.0.0 | 当前最新稳定版本,推荐使用 | + +## 历史版本 + +### 3.x +查看 3.1.x 及之前版本文档: + +| Go | Dubbo-go | protoc-gen-go-triple | 说明 | +| :--: | ------------ | -------------------- | -------------------- | +| 1.16 | v3.1.1 | v3.0.0 | 请参考 README 说明,了解如何生成老版本兼容的服务 stub 代码 | +| 1.16 | v3.1.0 | v3.0.0 | 请参考 README 说明,了解如何生成老版本兼容的服务 stub 代码 | +| 1.16 | v3.0.4 | v3.0.0 | 请参考 README 说明,了解如何生成老版本兼容的服务 stub 代码 | +| 1.16 | v3.0.3 | v3.0.0 | 请参考 README 说明,了解如何生成老版本兼容的服务 stub 代码 | +| 1.16 | v3.0.2 | v3.0.0 | 请参考 README 说明,了解如何生成老版本兼容的服务 stub 代码 | +| 1.16 | v3.0.1 | v3.0.0 | 请参考 README 说明,了解如何生成老版本兼容的服务 stub 代码 | +| 1.16 | v3.0.0 | v1.0.5 | | +| 1.16 | v3.0.0-rc4-1 | v1.0.2 | | +| 1.16 | v3.0.0-rc3 | v1.0.0 | | + +### 1.x + +| Go | Dubbo-go | Triple | protoc-gen-go-triple | 说明 | +| :--: | ------------ | ------ | -------------------- | -------------------- | +| | v1.5.0 | v1.1.8 | v1.0.8 | 停止维护,请升级到最新 3.x 版本 | + diff --git a/content/zh-cn/overview/mannual/java-sdk/_index.md b/content/zh-cn/overview/mannual/java-sdk/_index.md index 3d8c8d8b90a4..a2b522b0789d 100755 --- a/content/zh-cn/overview/mannual/java-sdk/_index.md +++ b/content/zh-cn/overview/mannual/java-sdk/_index.md @@ -5,7 +5,7 @@ aliases: content: - 快速开始: - description: 快速体验 Dubbo Java 微服务开发 - name: '[Spring Boot 快速开发 Dubbo 服务](quick-start/spring-boot/)' + name: '[Spring Boot 快速开发 Dubbo 服务](quick-start/starter/)' - description: 配置参考手册 name: '[配置参考手册](reference-manual/config/)' - 高级特性: @@ -15,8 +15,8 @@ content: - description: 注册中心配置指南 name: '[注册中心配置指南](reference-manual/registry/)' - 升级与兼容性: - - description: 3.0 迁移指南 - name: '[3.0 迁移指南](upgrades-and-compatibility/)' + - description: 版本迁移指南 + name: '[版本迁移指南](reference-manual/upgrades-and-compatibility/)' - 历史版本文档: - description: 历史版本文档 name: '[2.x 及早期版本文档](/zh-cn/docsv2.7/)' diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/_index.md b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/_index.md deleted file mode 100755 index b8cb090f2cd9..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/_index.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/ -description: 以下是 Dubbo 支持的所有功能列表,在此页面直接浏览或通过左侧菜单分类查看。 -hide_summary: true -linkTitle: 高级特性和用法 -no_list: true -title: 高级特性和用法 -type: docs -weight: 3 ---- - -{{% docs/section_list %}} \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/observability/_index.md b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/observability/_index.md deleted file mode 100755 index 39655bf053d4..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/observability/_index.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/observability/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/observability/ -description: 可观测性 -linkTitle: 可观测性 -title: 可观测性 -type: docs -weight: 2 ---- - - - - - - -## 什么是可观测性 -可观测性是从外部观察正在运行的系统的内部状态的能力。它由日志记录、指标和跟踪三大支柱组成。 - -## Dubbo 可观测性 -为了深入观察Dubbo内部的运行状况,Dubbo可观测性包括许多附加功能,帮助您在将应用程序推向生产时监视和管理应用程序。您可以选择使用HTTP端点或JMX来管理和监视应用程序。审计、运行状况和度量收集也可以自动应用于应用程序。 - -## Dubbo Java 可观测性实现 -- [如何开启指标采集](./meter/) -- [如何开启链路追踪](./tracing/) -- [日志管理](./logging/) \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/observability/logging.md b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/observability/logging.md deleted file mode 100644 index a8aa882545da..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/observability/logging.md +++ /dev/null @@ -1,172 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/observability/logging/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/observability/logging/ -description: 日志管理 -hide_summary: true -linkTitle: 日志管理 -no_list: true -title: 日志管理 -type: docs -weight: 3 ---- - -在 Dubbo 框架内所有的日志输出都是通过 LoggerFactory 这个静态工厂类来获得 Logger 的对象实体,并且抽离了一个 LoggerAdapter 用于对接第三方日志框架,所以就有了JDKLoggerAdapter, Log4jLoggerAdapter, SLF4JLoggerAdapter等一些实现子类,分别对接了不同 Log 第三方实现。既然 Dubbo 能够支持这么多log实现,那么这些实现在 Dubbo 中优先级是在呢么样的呢?这里的优先级是指未配置指定的 logger 提供方的情况下,由 Dubbo 框架自己选择。优先级如下: - -| 第三方日志框架 | 优先级 | -| ------------------------------------- | ------------------------------------------ | -| Log4j | 最高(默认就用这个) | -| SLF4J | 次高(上面没有采用这个) | -| Common Logging(jcl就是common logging) | 次低(Log4j和SLF4J在项目中均没有就用这个) | -| JDK log | 最低(最后的选择) | - -Dubbo 日志的调用方式,针对不同的日志打印系统,采用统一的 API 调用及输出,如: - -```java -/** - * ChannelListenerDispatcher - */ -public class ChannelHandlerDispatcher implements ChannelHandler { - - private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(ChannelHandlerDispatcher.class); -``` - -Dubbo 采用的日志输出方式是首先从 dubbo.application.logger 系统变量中获取属性值,来判断到底采用哪种日志输出方式,如果没设置则按照默认的加载顺序加载相应的日志输出类,直到成功加载: - -顺序为:log4jLogger > slf4jLogger > JclLogger > JdkLogger - -LoggerFactory 在类加载过程中变量的初始化过程: - -```java -// search common-used logging frameworks -static { - String logger = System.getProperty("dubbo.application.logger", ""); - switch (logger) { - case Slf4jLoggerAdapter.NAME: - setLoggerAdapter(new Slf4jLoggerAdapter()); - break; - case JclLoggerAdapter.NAME: - setLoggerAdapter(new JclLoggerAdapter()); - break; - case Log4jLoggerAdapter.NAME: - setLoggerAdapter(new Log4jLoggerAdapter()); - break; - case JdkLoggerAdapter.NAME: - setLoggerAdapter(new JdkLoggerAdapter()); - break; - case Log4j2LoggerAdapter.NAME: - setLoggerAdapter(new Log4j2LoggerAdapter()); - break; - default: - List> candidates = Arrays.asList( - Log4jLoggerAdapter.class, - Slf4jLoggerAdapter.class, - Log4j2LoggerAdapter.class, - JclLoggerAdapter.class, - JdkLoggerAdapter.class - ); - boolean found = false; - // try to use the first available adapter - for (Class clazz : candidates) { - try { - LoggerAdapter loggerAdapter = clazz.getConstructor().newInstance(); - loggerAdapter.getLogger(LoggerFactory.class); - if (loggerAdapter.isConfigured()) { - setLoggerAdapter(loggerAdapter); - found = true; - break; - } - } catch (Exception | LinkageError ignored) { - // ignore - } - } - if (found) { - break; - } - - System.err.println("Dubbo: Unable to find a proper configured logger to log out."); - for (Class clazz : candidates) { - try { - LoggerAdapter loggerAdapter = clazz.getConstructor().newInstance(); - loggerAdapter.getLogger(LoggerFactory.class); - setLoggerAdapter(loggerAdapter); - found = true; - break; - } catch (Throwable ignored) { - // ignore - } - } - if (found) { - System.err.println("Dubbo: Using default logger: " + loggerAdapter.getClass().getName() + ". " + - "If you cannot see any log, please configure -Ddubbo.application.logger property to your preferred logging framework."); - } else { - System.err.println("Dubbo: Unable to find any available logger adapter to log out. Dubbo logs will be ignored. " + - "Please configure -Ddubbo.application.logger property and add corresponding logging library to classpath."); - } - } -} -``` - -上面这段静态块是在LoggerFactory里面,说明只要LoggerFactory类一加载就会去选择对应的日志提供方。大家可能会发现对日志的提供方其实是可以通过配置来指定的,因为静态块一开始是从当前jvm环境中获取dubbo.application.logger,这个参数是同java -Ddubbo.application.logger=xxxx去指定的,如果是放在容器里面,就需要配置在容器启动的jvm参数里面。 - -## 使用Log4j来提供日志输出 - -你不用做过多的处理就可以开启dubbo的日志,因为dubbo默认就是使用log4j。你唯一需要做的就是配置一个name是"com.alibaba.dubbo"的logger就可以了,然后关联到对应的appender。如下: - -```xml - - - - - - - - - - - -``` - -## 使用logback来提供日志输出 - -这种情况,默认是看不到dubbo的日志输出的,除非出现异常,被你当前系统的日志框架拦截住了。我这里就拿当前使用最多的日志框架logback来做示例。我们知道logback天生和slf4j进行了集成,所以要在项目里面使用logback,调用slf4j暴露的接口就可以。所以要把dubbo的日志输出切换到logback,也就变成了切换到slf4j了。 - -```xml - - - - UTF-8 - ${LOG_HOME_DUBBO}/MTP-DUBBO.log - - ${LOG_HOME_DUBBO}/DEMO-%d{yyyy-MM-dd}.%i-DUBBO.zip - 30 - - 100MB - - - - %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n - true - - - - - -``` - -Dubbo 也可以将日志信息记录或者保存到文件中。 - -1. 使用`accesslog`输出到`log4j` - -```xml - - -``` - -2. 输出到文件 - -```xml - - -``` \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/observability/tracing.md b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/observability/tracing.md deleted file mode 100644 index 20d4fc6f76a8..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/observability/tracing.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/observability/tracing/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/observability/tracing/ -description: 链路追踪 -hide_summary: true -linkTitle: 链路追踪 -no_list: true -title: 链路追踪 -type: docs -weight: 2 ---- - -## 概述 -Dubbo 内置了全链路追踪能力,你可以通过引入 spring-boot-starter 或者相关依赖开启链路跟踪能力,通过将跟踪数据导出到一些主流实现如 Zipkin、Skywalking、Jaeger 等后端系统,可以实现全链路跟踪数据的分析与可视化展示。 - -Dubbo 目前借助 Micrometer Observation 完成 Tracing 的所有埋点工作,依赖 Micrometer 提供的各种 Bridge 适配,我们可以实现将 Tracing 导入各种后端系统,具体工作原理如下。 - -![micrometer-bridge](/imgs/docs3-v2/java-sdk/observability/micrometer-bridge.png) - -## 使用方式 - -以 Dubbo Spring Boot 应用为例,通过加入如下依赖即可开启链路追踪,并使用 zipkin exporter bridge 将链路追踪数据导入 Zipkin 后端系统。 - -```xml - - org.apache.dubbo - dubbo-spring-boot-tracing-otel-zipkin-starter - 3.2.1-SNAPSHOT - -``` - -更多完整示例请参见: -* [使用 Zipkin 实现 Dubbo 全链路追踪](/zh-cn/overview/tasks/observability/tracing/zipkin/) -* [使用 Skywalking 实现 Dubbo 全链路追踪](/zh-cn/overview/tasks/observability/tracing/skywalking/) - -## 关联日志 - -Dubbo Tracing 还实现了与日志系统的自动关联,即将 tracing-id、span-id 等信息自动置入日志 MDC 上下文,你只需要设置日志输出格式中包含类似 `%X{traceId:-},%X{spanId:-}]`,即可实现业务日志与 tracing 系统的自动关联,具体可参见 [Tracing 日志上下文配置示例](https://github.com/apache/dubbo-samples/blob/master/4-governance/dubbo-samples-tracing/dubbo-samples-spring-boot-tracing-otel-otlp/provider/src/main/resources/application.yml)。 - diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/others/_index.md b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/others/_index.md deleted file mode 100755 index e107c49e454b..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/others/_index.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/others/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/others/ -description: 其他 -linkTitle: 其他 -title: 其他 -type: docs -weight: 5 ---- diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/others/docker.md b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/others/docker.md deleted file mode 100644 index 6d70eea3f222..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/others/docker.md +++ /dev/null @@ -1,78 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/others/docker/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/others/docker/ -description: 将 Dubbo 部署到 Docker 环境 -linkTitle: Dubbo 部署 Docker 环境 -title: Dubbo 部署 Docker 环境 -type: docs -weight: 6 ---- - - - - - -## 特性说明 -一些部署场景需要动态地指定服务注册地址。例如,docker bridge网络模式需要为外部网络通信指定一个注册主机IP。Dubbo在启动阶段提供了两对系统属性,用于设置外部通信的IP和端口地址。 -* DUBBO_IP_TO_REGISTRY --- 注册到注册中心的IP地址 -* DUBBO_PORT_TO_REGISTRY --- 注册到注册中心的端口 -* DUBBO_IP_TO_BIND --- 侦听IP地址 -* DUBBO_PORT_TO_BIND --- 侦听端口 - -> 1. 以上四个配置是可选的。如果没有配置,Dubbo会自动获得IP和端口。请根据部署情况,灵活选择。 -> 2. Dubbo支持多协议. **如果一个应用程序同时暴露了多个不同的协议服务,并且需要为每个服务分别指定IP或端口。请在上述属性前分别添加协议前缀。** -> * HESSIAN_DUBBO_PORT_TO_BIND hessian 协议绑定端口 -> * DUBBO_DUBBO_PORT_TO_BIND   dubbo 协议绑定端口 -> * HESSIAN_DUBBO_IP_TO_REGISTRY hessian 协议注册的IP -> * DUBBO_DUBBO_IP_TO_REGISTRY     dubbo 协议注册的IP -> 3. `PORT_TO_REGISTRY`或`IP_TO_REGISTRY`不会被用作默认的`PORT_TO_BIND`或`IP_TO_BIND`,但相反的是 true。 -> * 如果设置`PORT_TO_REGISTRY=20881` `IP_TO_REGISTRY=30.5.97.6`,那么 `PORT_TO_BIND` `IP_TO_BIND`不会受到影响。 -> * 如果设置`PORT_TO_BIND=20881` `IP_TO_BIND=30.5.97.6`,那么 `PORT_TO_REGISTRY=20881` `IP_TO_REGISTRY=30.5.97.6` 默认情况下。 - -## 使用场景 -提供隔离的环境,从而确保在开发和部署过程中服务不会受到彼此的影响,对于微服务的开发和部署有很大帮助。 - -## 使用方式 -[dubbo-docker-sample](https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-docker) 本地操作过程: - -1. 克隆项目到本地 -```sh -git clone git@github.com:dubbo/dubbo-docker-sample.git -cd dubbo-docker-sample -``` -2. 包本地的maven -```sh -mvn clean install -``` -3. 通过docker build建立一个镜像 -```sh -docker build --no-cache -t dubbo-docker-sample . -``` -4. 构建镜像 -```sh -FROM openjdk:8-jdk-alpine -ADD target/dubbo-docker-sample-0.0.1-SNAPSHOT.jar app.jar -ENV JAVA_OPTS="" -ENTRYPOINT exec java $JAVA_OPTS -jar /app.jar -``` -5. 从镜像中创建和运行容器 -```sh -# 由于我们使用zk注册中心,我们先启动zk容器 -docker run --name zkserver --restart always -d zookeeper:3.4.9 -``` -```sh -docker run -e DUBBO_IP_TO_REGISTRY=30.5.97.6 -e DUBBO_PORT_TO_REGISTRY=20881 -p 30.5.97.6:20881:20880 --link zkserver:zkserver -it --rm dubbo-docker-sample -``` - -> 假设主机IP是 30.5.97.6. -> 通过环境变量设置提供商注册的IP地址和注册中心的端口 `DUBBO_IP_TO_REGISTRY=30.5.97.6` `DUBBO_PORT_TO_REGISTRY=20881`   -> 通过以下方式实现端口映射`-p 30.5.97.6:20881:20880`, 其中20880是由dubbo自动选择的监听端口。没有监控IP的配置,所以它将监听0.0.0.0(所有IP)。 -> 启动后,提供者的注册地址是30.5.97.6:20881,而容器的监听地址是:0.0.0.0:20880。   - -6. 测试从另一个主机或容器中执行 -```sh -telnet 30.5.97.6 20881 -ls -invoke org.apache.dubbo.test.docker.DemoService.hello("world") -``` \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/others/dubbo-kubernetes-probe.md b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/others/dubbo-kubernetes-probe.md deleted file mode 100644 index 1848e541cf1d..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/others/dubbo-kubernetes-probe.md +++ /dev/null @@ -1,80 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/others/dubbo-kubernetes-probe/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/others/dubbo-kubernetes-probe/ -description: 了解 Dubbo 与 Kubernetes 生命周期对齐探针的扩展与应用场景 -linkTitle: Kubernetes 生命周期探针 -title: Kubernetes 生命周期探针 -type: docs -weight: 5 ---- - - - - - -## 特性说明 -[Pod 的生命周期](https://kubernetes.io/zh/docs/concepts/workloads/pods/pod-lifecycle/) 与服务调度息息相关,通过对 Kubernetes 官方探针的实现,能够使 Dubbo3 乃至整个应用的生命周期与 Pod 的生命周期,在 Pod 的整个生命周期中,影响到 Pod 的就只有健康检查这一部分, 我们可以通过配置 liveness probe(存活探针)和 readiness probe(可读性探针)来影响容器的生命周期。 - -通过 Dubbo3 的 SPI 机制,在内部实现多种“探针”,基于 Dubbo3 QOS 运维模块的 HTTP 服务,使容器探针能够获取到应用内对应探针的状态。另外,SPI 的实现机制也利于用户自行拓展内部“探针”,使整个应用的生命周期更有效的进行管控。 - -**三种探针对应的 SPI 接口** - -- livenessProbe: `org.apache.dubbo.qos.probe.LivenessProbe` -- readinessProbe: `org.apache.dubbo.qos.probe.ReadinessProbe` -- startupProbe: `org.apache.dubbo.qos.probe.StartupProbe` - -接口将自动获取当前应用所有 SPI 的实现,对应接口的 SPI 实现均成功就绪则接口返回成功。 - -Dubbo3 SPI 更多扩展的介绍见 [Dubbo SPI扩展](/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/) - -## 使用场景 -`liveness probe` 来确定你的应用程序是否正在运行,查看是否存活。 - -`readiness probe` 来确定容器是否已经就绪可以接收流量过来,是否准备就绪,是否可以开始工作。 - -`startup probe` 来确定容器内的应用程序是否已启动,如果提供了启动探测则禁用所有其他探测,直到它成功为止,如果启动探测失败则杀死容器,容器将服从其重启策略。如果容器没有提供启动探测,则默认状态为成功。 - -## 使用方式 - -### 存活检测 - -对于 livenessProbe 存活检测,由于 Dubbo3 框架本身无法获取到应用的存活状态,因此本接口无默认实现,且默认返回成功。开发者可以根据 SPI 定义对此 SPI 接口进行拓展,从应用层次对是否存活进行判断。 - -关于 [liveness 存活探针](../../../reference-manual/spi/description/liveness/) 扩展示例 -### 就绪检测 - -对于 readinessProbe 就绪检测,目前 Dubbo3 默认提供了两个检测维度,一是对 Dubbo3 服务自身是否启停做判断,另外是对所有服务是否存在已注册接口,如果所有服务均已从注册中心下线(可以通过 QOS 运维进行操作)将返回未就绪的状态。 - -关于 [readiness 就绪探针](../../../reference-manual/spi/description/readiness/) 扩展示例 - -### 启动检测 - -对于 startupProbe 启动检测,目前 Dubbo3 默认提供了一个检测维度,即是在所有启动流程(接口暴露、注册中心写入等)均结束后返回已就绪状态。 - -关于 [startup 启动探针](../../../reference-manual/spi/description/startup/) 扩展示例 - -### 参考示例 -```yaml -livenessProbe: - httpGet: - path: /live - port: 22222 - initialDelaySeconds: 5 - periodSeconds: 5 -readinessProbe: - httpGet: - path: /ready - port: 22222 - initialDelaySeconds: 5 - periodSeconds: 5 -startupProbe: - httpGet: - path: /startup - port: 22222 - failureThreshold: 30 - periodSeconds: 10 -``` -> QOS 当计算节点检测到内存压力时,kuberentes 会 BestEffort -> Burstable -> Guaranteed 依次驱逐 Pod。 - -目前三种探针均有对应的接口,路径为 QOS 中的命令,端口信息请根据 QOS 配置进行对应修改(默认端口为 22222)。其他参数请参考 [Kubernetes官方文档说明](https://kubernetes.io/zh/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/)。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/others/graceful-shutdown.md b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/others/graceful-shutdown.md deleted file mode 100644 index 337794ae4cd1..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/others/graceful-shutdown.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/others/graceful-shutdown/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/others/graceful-shutdown/ -description: 让 Dubbo 服务完成优雅停机 -linkTitle: 优雅停机 -title: 优雅停机 -type: docs -weight: 2 ---- -## 特性说明 - -优雅停机是指服务实例能安全平稳的停止,对进行中的业务不产生影响。 -一个Dubbo服务可能既作为服务提供者,又是服务消费者,当服务停止时: -1. 消费者不会再请求已停止的服务实例 -2. 该服务实例正在处理的请求能正常处理完成 - -## 使用场景 - -1. 通过 `kill PID` 停止服务 -2. 通过 SpringBoot Actuator 的 `/shutdown` 停止服务 - -> Dubbo 3.0 及以上版本支持不同类型的Java应用,包括 SpringBoot 应用、 Spring 应用、非 Spring 应用。 - -## 使用方式 - -设置优雅停机超时时间,缺省超时时间是 10 秒,如果超时则强制关闭。 -该参数可在 dubbo.properties 文件里配置,例如:配置为 30 秒。 -```properties -# 停止服务等待时间,单位:毫秒 -dubbo.service.shutdown.wait=30000 -``` - -{{% alert title="注意事项" color="primary" %}} - -1. Dubbo 是通过 JDK 的 ShutdownHook 来完成优雅停机的,所以如果用户使用 `kill -9 PID` 等强制关闭指令,是不会执行优雅停机的,只有通过 `kill PID` 时,才会执行。 - -2. 验证是否执行了 Dubbo 的 ShutdownHook 可在日志文件中查找关键字:`Run shutdown hook now.` - -3. 如果使用了 Spring,请升级 4.2 及以上版本,建议使用 5 以上版本 - -4. 如果使用了 SpringBoot,Dubbo 的 ShutdownHook 会在 SpringBoot 的 ShutdownHook 之前执行, -如果使用 SpringBoot 2.3及以上版本,建议配合 SpringBoot 的优雅停机使用,在配置文件 applicaion.yml 中配置: -```yml -server: - shutdown: graceful -``` - -5. 如果 ShutdownHook 不能生效,可根据具体场景自行调用: -```java -ApplicationModel.defaultModel().destroy(); -``` -{{% /alert %}} diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/others/logger-howto.md b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/others/logger-howto.md deleted file mode 100644 index be4746f725fa..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/others/logger-howto.md +++ /dev/null @@ -1,180 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/others/logge-howto/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/others/logger-howto/ -description: 在dubbo和dubbo-samples中如何配置与使用日志框架 -linkTitle: 日志框架配置与使用 -title: 日志框架配置与使用 -type: docs -weight: 7 ---- - -## 特性说明 - -在dubbo 3.3.0-beta.3之前,dubbo和dubbo-samples中存在混用log4j和logback的情况,并且部分模块缺少日志配置,造成日志框架使用混乱,经常冲突报错。因此在3.3.0-beta.3之后,统一将日志组件升级替换为log4j2,配置使用上更加简洁,减少了维护成本。此文档说明了应该如何配置使用日志框架,避免间接引入多种日志框架,引起冲突报错。 - -## 使用方法 - -### 使用约定 - -* 请使用log4j2做为日志框架,禁止使用log4j和logback. - 除部分遗留场景,统一使用一种日志框架可以降低使用成本,避免冲突 -* 避免日志框架依赖被传递到上游,可以通过在maven设置scope为`test、provider`或设置`true`的方式解决. - dubbo作为一个服务框架应该尽量避免传递非必选依赖,将日志框架选择权交给用户 - -### 使用场景 - -#### 1. 普通dubbo模块 - -绝大多数模块是此类型,一般是单元测试需要用到日志框架 - -1. 引入maven依赖,注意如果parent已经引入则无需重复添加 - - ```xml - - org.apache.logging.log4j - log4j-slf4j-impl - test - - ``` - -2. 添加log4j2日志配置 `src/test/resources/log4j2-test.xml`,使用此名称原因是可以保证最高优先级 - - ```xml - - - - - - - - - - - - - - ``` - - -#### 2. 非spring-boot demo模块 -1. 引入maven依赖,注意如果parent已经引入则无需重复添加 - - ```xml - - org.apache.logging.log4j - log4j-slf4j-impl - - ``` - -2. 添加log4j2日志配置 `src/main/resources/log4j2.xml` - - ```xml - - - - - - - - - - - - - - ``` - -#### 3. spring-boot demo模块 - -spring-boot支持用starter的方式引入log4j2依赖,但是注意spring-boot默认使用logback,因此需要在``中排除 - -1. 排除spring-boot-starter-logging - - ```xml - - - - org.springframework.boot - spring-boot-dependencies - ${spring-boot.version} - pom - import - - - org.springframework.boot - spring-boot-starter - ${spring-boot.version} - - - org.springframework.boot - spring-boot-starter-logging - - - - - - ``` - -2. 引入maven依赖 - - ```xml - - org.springframework.boot - spring-boot-starter-log4j2 - - ``` - -3. 添加log4j2日志配置 `src/main/resources/log4j2.xml` - - 可选,spring-boot自带默认日志配置 - -#### 4. spring-boot native demo模块 - -因为log4j2尚不支持native,需要使用logback来作为日志框架,因此无需任何修改,保留原有方式即可,注意不要间接引入log4j或slf4j-log4j12 - -## 常见日志框架问题 - -#### 1. 缺少日志框架 - -控制台输出: - -``` -SLF4J: No SLF4J providers were found. -SLF4J: Defaulting to no-operation (NOP) logger implementation -SLF4J: See SLF4J Error Codes for further details. -``` - -解决方案: 引入log4j2依赖 - -```xml - - org.apache.logging.log4j - log4j-slf4j-impl - -``` - -#### 2. 日志框架冲突 - -控制台输出: - -``` -SLF4J: Class path contains multiple SLF4J bindings. -SLF4J: Found binding in [jar:file:.../slf4j-log4j12-1.x.x.jar!/org/slf4j/impl/StaticLoggerBinder.class] -SLF4J: Found binding in [jar:file:.../logback-classic-1.x.x.jar!/org/slf4j/impl/StaticLoggerBinder.class] -SLF4J: Found binding in [jar:file:.../log4j-slf4j-impl-2.x.x.jar!/org/slf4j/impl/StaticLoggerBinder.class] -SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation. -SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory] -``` - -或 - -``` -Exception in thread "main" java.lang.IllegalArgumentException: LoggerFactory is not a Logback LoggerContext but Logback is on the classpath -``` - -解决方案: 排除掉除了log4j-slf4j-impl的依赖, 强烈推荐使用 [Maven Helper - IntelliJ IDEs Plugin](https://plugins.jetbrains.com/plugin/7179-maven-helper) 来分析和排除依赖 - -#### 3. 其他问题 - -可以参考: [SLF4J Error Codes](https://www.slf4j.org/codes.html) diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/others/logger-management.md b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/others/logger-management.md deleted file mode 100644 index ed70018d0133..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/others/logger-management.md +++ /dev/null @@ -1,121 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/others/logger-management/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/others/logger-management/ -description: 在 Dubbo 中适配日志框架并支持运行时动态切换使用的日志框架 -linkTitle: 日志框架适配及运行时管理 -title: 日志框架适配及运行时管理 -type: docs -weight: 4 ---- -## 特性说明 -日志框架适配,自 `2.2.1` 开始,dubbo 开始内置 log4j、slf4j、jcl、jdk 这些日志框架的适配。 - -日志框架运行时管理,自 `3.0.10` 开始,dubbo-qos 运行时管控支持查询日志配置以及动态修改使用的日志框架和日志级别。 - -> 通过 dubbo-qos 修改的日志配置不进行持久化存储,在应用重启后将会失效。 - -## 使用场景 -应用程序日志: 收集和存储分布式服务的应用程序日志,支持多种日志格式,包括文本、JSON、XML 和二进制,提供了过滤、聚合和分析日志数据,用于解决分布式应用程序的问题,监控服务的性能。 - -运行时管理: 管理分布式服务的运行时,提供设置阈值和在满足某些条件时采取纠正措施,确保服务保持稳定并高效运行实时检测和响应性能问题。 - -## 使用方式 -### 日志框架适配 -可以通过以下方式显式配置日志输出策略 - -1. 命令行 -```sh -java -Ddubbo.application.logger=log4j -``` - -2. `dubbo.properties` 中指定 -``` -dubbo.application.logger=log4j -``` - -3. `dubbo.xml` 中配置 -```xml - -``` - -自定义扩展可以参考 [日志适配扩展](../../../reference-manual/spi/description/logger-adapter) - -### 日志框架运行时管理 -1. 查询日志配置 -命令:`loggerInfo` - -**示例** -```bash -> telnet 127.0.0.1 22222 -> loggerInfo -``` - -**输出** -``` -Trying 127.0.0.1... -Connected to localhost. -Escape character is '^]'. - ___ __ __ ___ ___ ____ - / _ \ / / / // _ ) / _ ) / __ \ - / // // /_/ // _ |/ _ |/ /_/ / -/____/ \____//____//____/ \____/ -dubbo>loggerInfo -Available logger adapters: [jcl, jdk, log4j, slf4j]. Current Adapter: [log4j]. Log level: INFO -``` - -2. 修改日志级别 -命令:`switchLogLevel {level}` - -level: `ALL`, `TRACE`, `DEBUG`, `INFO`, `WARN`, `ERROR`, `OFF` - -**示例** -```bash -> telnet 127.0.0.1 22222 -> switchLogLevel WARN -``` - -**输出** -``` -Trying 127.0.0.1... -Connected to localhost. -Escape character is '^]'. - ___ __ __ ___ ___ ____ - / _ \ / / / // _ ) / _ ) / __ \ - / // // /_/ // _ |/ _ |/ /_/ / -/____/ \____//____//____/ \____/ -dubbo>loggerInfo -Available logger adapters: [jcl, jdk, log4j, slf4j]. Current Adapter: [log4j]. Log level: INFO -dubbo>switchLogLevel WARN -OK -dubbo>loggerInfo -Available logger adapters: [jcl, jdk, log4j, slf4j]. Current Adapter: [log4j]. Log level: WARN``` -``` - -3. 修改日志输出框架 -命令:`switchLogger {loggerAdapterName}` - -loggerAdapterName: `slf4j`, `jcl`, `log4j`, `jdk`, `log4j2` - -**示例** -```bash -> telnet 127.0.0.1 22222 -> switchLogger slf4j -``` - -**输出** -``` -Trying 127.0.0.1... -Connected to localhost. -Escape character is '^]'. - ___ __ __ ___ ___ ____ - / _ \ / / / // _ ) / _ ) / __ \ - / // // /_/ // _ |/ _ |/ /_/ / -/____/ \____//____//____/ \____/ -dubbo>loggerInfo -Available logger adapters: [jcl, slf4j, log4j, jdk]. Current Adapter: [log4j]. Log level: INFO -dubbo>switchLogger slf4j -OK -dubbo>loggerInfo -Available logger adapters: [jcl, slf4j, log4j, jdk]. Current Adapter: [slf4j]. Log level: INFO -``` diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/others/service-container.md b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/others/service-container.md deleted file mode 100644 index 6d1bc031fb36..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/others/service-container.md +++ /dev/null @@ -1,66 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/others/service-container/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/others/service-container/ -description: 了解 Dubbo 中服务自定义容器类型和使用 -linkTitle: 自定义服务容器 -title: 自定义服务容器 -type: docs -weight: 1 ---- -## 特性说明 -Dubbo 的服务容器是一个 standalone 的启动程序,因为后台服务不需要 Tomcat 或 JBoss 等 Web 容器的功能,如果硬要用 Web 容器去加载服务提供方,增加复杂性,也浪费资源。所以服务通常不需要 Tomcat/JBoss 等 Web 容器的特性,没必要用 Web 容器去加载服务。 - -Dubbo 服务容器只是一个简单的 Main 方法,并加载一个简单的 Spring 容器,用于暴露服务。 - -服务容器的加载内容可以扩展,内置了 spring, jetty, log4j 等加载,可通过 [容器扩展点](../../../reference-manual/spi/description/container) 进行扩展。配置配在 java 命令的 -D 参数或者 `dubbo.properties` 中。 - -## 使用场景 -web 容器主要是用来响应 http 请求以及静态页面的,Dubbo 服务提供方只是对外提供 dubbo 服务,用 web 容器不太适合,单独作为 dubbo 服务提供方,只需要通过一个 main 方法加载一个简单的 spring 容器将服务暴露。 - -## 使用方式 -### Spring Container -- 自动加载 `META-INF/spring` 目录下的所有 Spring 配置。 -- 配置 spring 配置加载位置: - -```fallback -dubbo.spring.config=classpath*:META-INF/spring/*.xml -``` - -### Jetty Container -- 启动一个内嵌 Jetty,用于汇报状态。 -- 配置: - - `dubbo.jetty.port=8080`:配置 jetty 启动端口 - - `dubbo.jetty.directory=/foo/bar`:配置可通过 jetty 直接访问的目录,用于存放静态文件 - - `dubbo.jetty.page=log,status,system`:配置显示的页面,缺省加载所有页面 - -### Log4j Container - -- 自动配置 log4j 的配置,在多进程启动时,自动给日志文件按进程分目录。 -- 配置: - - `dubbo.log4j.file=/foo/bar.log`:配置日志文件路径 - - `dubbo.log4j.level=WARN`:配置日志级别 - - `dubbo.log4j.subdirectory=20880`:配置日志子目录,用于多进程启动,避免冲突 - - -### 容器加载说明 -缺省只加载 spring - -```sh -java org.apache.dubbo.container.Main -``` -通过 main 函数参数传入要加载的容器 - -```sh -java org.apache.dubbo.container.Main spring jetty log4j -``` -通过 JVM 启动参数传入要加载的容器 - -```sh -java org.apache.dubbo.container.Main -Ddubbo.container=spring,jetty,log4j -``` -通过 classpath 下的 `dubbo.properties` 配置传入要加载的容器 - -```fallback -dubbo.container=spring,jetty,log4j -``` diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/others/set-host.md b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/others/set-host.md deleted file mode 100644 index 75ad19c1ca47..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/others/set-host.md +++ /dev/null @@ -1,93 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/others/set-host/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/others/set-host/ -description: 自定义 Dubbo 服务对外暴露的主机地址 -linkTitle: 主机地址自定义暴露 -title: 主机地址自定义暴露 -type: docs -weight: 3 ---- - - - - - - -## 特性说明 - -在 Dubbo 中, Provider 启动时主要做两个事情 -- 一是启动 server -- 二是向注册中心注册服务。启动 server 时需要绑定 socket,向注册中心注册服务时也需要发送 socket 唯一标识服务地址。 - -1. `dubbo` 中不设置 `host` 时默认 `host` 是什么? -2. 那在 `dubbo` 中如何指定服务的 `host`,我们是否可以用 hostname 或 domain 代替 IP 地址作为 `host`? -3. 在使用 docker 时,有时需要设置端口映射,此时,启动 server 时绑定的 socket 和向注册中心注册的 socket 使用不同的端口号,此时又该如何设置? - -## 使用场景 -应用程序包含多个服务每个服务定制地址,外部客户端通过定制的地址访问服务。 - -应用程序同一服务的多个版本每个版本的服务定制地址,外部客户端通过定制的地址访问相应版本的服务。 - -应用程序多个地区部署服务每个地区定制地址,外部客户端通过定制的地址访问相应地区的相应服务。 - -## 使用方式 -### 不设置 host 时默认 host - -一般的 dubbo 协议配置如下: -``` xml - ... - - ... -``` - -可以看到,只配置了端口号,没有配置 host,此时设置的 host 又是什么呢? - -查看代码发现,在 `org.apache.dubbo.config.ServiceConfig#findConfigedHosts()` 中,通过 `InetAddress.getLocalHost().getHostAddress()` 获取默认 host。其返回值如下: - -1. 未联网时,返回 127.0.0.1 -2. 在阿里云服务器中,返回私有地址,如: 172.18.46.234 -3. 在本机测试时,返回公有地址,如: 30.5.10.11 - -### 指定服务的 socket - -除此之外,可以通过 `dubbo.protocol` 或 `dubbo.provider `的 `host` 属性对 `host` 进行配置,支持IP地址和域名,如下: - -``` xml - ... - - ... -``` - -### socket 使用不同的端口号 - -见 [dubbo 通过环境变量设置 host](https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-docker) - -有些部署场景需要动态指定服务注册的地址,如 docker bridge 网络模式下要指定注册宿主机 ip 以实现外网通信。dubbo 提供了两对启动阶段的系统属性,用于设置对外通信的ip、port地址。 - -* **DUBBO_IP_TO_REGISTRY**:注册到注册中心的 ip 地址 -* **DUBBO_PORT_TO_REGISTRY**:注册到注册中心的 port 端口 -* **DUBBO_IP_TO_BIND**:监听 ip 地址 -* **DUBBO_PORT_TO_BIND**:监听 port 端口 - -以上四个配置项均为可选项,如不配置 dubbo 会自动获取 ip 与端口,请根据具体的部署场景灵活选择配置。 -dubbo 支持多协议,如果一个应用同时暴露多个不同协议服务,且需要为每个服务单独指定 ip 或 port,请分别在以上属性前加协议前缀。 如: - -* **HESSIAN_DUBBO_PORT_TO_BIND**:hessian 协议绑定的 port -* **DUBBO_DUBBO_PORT_TO_BIND**:dubbo 协议绑定的 port -* **HESSIAN_DUBBO_IP_TO_REGISTRY**:hessian 协议注册的 ip -* **DUBBO_DUBBO_IP_TO_REGISTRY**:dubbo 协议注册的 ip - -PORT_TO_REGISTRY 或 IP_TO_REGISTRY 不会用作默认 PORT_TO_BIND 或 IP_TO_BIND,但是反过来是成立的。如: - -* 设置 `PORT_TO_REGISTRY=20881` 和 `IP_TO_REGISTRY=30.5.97.6`,则 `PORT_TO_BIND` 和 `IP_TO_BIND` 不受影响 -* 设置 `PORT_TO_BIND=20881` 和 `IP_TO_BIND=30.5.97.6`,则默认 `PORT_TO_REGISTRY=20881` 且 `IP_TO_REGISTRY=30.5.97.6` - -{{% alert title="总结" color="primary" %}} - 1. 可以通过`dubbo.protocol`或`dubbo.provider`的`host`属性对`host`进行配置,支持IP地址和域名.但此时注册到注册中心的IP地址和监听IP地址是同一个值 - 2. 为了解决在虚拟环境或局域网内consumer无法与provider通信的问题,可以通过环境变量分别设置注册到注册中心的IP地址和监听IP地址,其优先级高于`dubbo.protocol`或`dubbo.provider`的`host`配置 - - 参考一:[Proposal: support hostname or domain in service discovery.](https://github.com/apache/dubbo/issues/2043) - - 参考二:[dubbo通过环境变量设置host](https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-docker) - {{% /alert %}} diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/_index.md b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/_index.md deleted file mode 100755 index 6a2ad3e926cd..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/_index.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/performance/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/performance/ -description: 诊断与调优 -linkTitle: 诊断与调优 -title: 诊断与调优 -type: docs -weight: 3 ---- diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/concurrency-control.md b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/concurrency-control.md deleted file mode 100644 index ecb692606458..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/concurrency-control.md +++ /dev/null @@ -1,91 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/performance/concurrency-control/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/performance/concurrency-control/ -description: Dubbo 中的并发控制 -linkTitle: 并发控制 -title: 并发控制 -type: docs -weight: 28 ---- - - -## 功能说明 -多种并发控制功能,帮助用户管理其应用程序和服务。 - -## 使用场景 -限制从同一客户端到同一服务的并发请求数,防止恶意请求使服务器过载,确保服务的稳定性,并防止使用过多资源。 - -控制某些服务的最大并发请求数,确保其他服务的资源可用性。系统过载和确保系统稳定性。 - -允许在需求增加时更平滑地扩展服务。 - -确保服务在高峰使用时间保持可靠和稳定。 - -这种方式要求用户准确的预先评估系统能处理的并发数,而准确的评估系统处理能力并不是一件容易的事情,因此 Dubbo 还提供了自适应限流模式,根据系统负载自动识别系统健康程度并进行限流保护,可以在此 [查看使用文档](../adaptive-concurrency-control)。 - -## 使用方式 -### 样例一 - -> 限制 `com.foo.BarService` 的每个方法,服务器端并发执行(或占用线程池线程数)不能超过 10 个 - -```xml - -``` - -### 样例二 - -> 限制 `com.foo.BarService` 的 `sayHello` 方法,服务器端并发执行(或占用线程池线程数)不能超过 10 个 - -```xml - - - -``` -### 样例三 - -> 限制 `com.foo.BarService` 的每个方法,每客户端并发执行(或占用连接的请求数)不能超过 10 个 - -```xml - -``` - -**或** - -```xml - -``` - -### 样例四 - -> 限制 `com.foo.BarService` 的 `sayHello` 方法,每客户端并发执行(或占用连接的请求数)不能超过 10 个 - -```xml - - - -``` - -或 - -```xml - - - -``` - -> 如果 `` 和 `` 都配了actives,`` 优先,参见:[配置的覆盖策略](../../../reference-manual/config/principle/)。 - -### Load Balance 均衡 - -配置服务的客户端的 `loadbalance` 属性为 `leastactive`,此 Loadbalance 会调用并发数最小的 Provider(Consumer端并发数)。 - -```xml - -``` - -**或** - -```xml - -``` \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/config-connections.md b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/config-connections.md deleted file mode 100644 index 2ec514ebea2e..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/config-connections.md +++ /dev/null @@ -1,57 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/performance/config-connections/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/performance/config-connections/ -description: Dubbo 中服务端和客户端的连接控制 -linkTitle: 连接控制 -title: 连接控制 -type: docs -weight: 29 ---- - - - - - -## 功能说明 -连接控制功能可以使用户能够控制和管理进出服务器连接数,限制连接数并设置超时,以确保 Dubbo 系统的稳定性和性能,还允许用户根据 IP 地址、端口和协议配置不同级别的访问控制,保护系统免受恶意流量的影响,并降低服务中断的风险,此外提供了一种监视当前流量和连接状态的方法。 - -## 使用场景 -1. 服务器过载时减少连接数:当服务器过载时,使用 Dubbo 通过设置最大连接限制来减少连接数减少服务器上的负载并防止其崩溃。 -2. 减少服务器受到攻击时的连接数:Dubbo 可以限制服务器受到攻击的连接数防止恶意连接充斥服务器并导致服务器崩溃。 -3. 限制特定服务的连接数:Dubbo 可以限制特定服务连接数防止服务过载过多的请求并确保及时响应所有请求。 -4. 限制来自单个IP地址的连接数:Dubbo 可以限制来自单个地址的连接数降低来自单个IP地址的恶意活动的风险。 - -## 使用方式 -### 服务端连接控制 - -限制服务器端接受的连接不能超过 10 个 [^1]: - -```xml - -``` - -或 - -```xml - -``` - -### 客户端连接控制 - -限制客户端服务使用连接不能超过 10 个 [^2]: - -```xml - -``` - -或 - -```xml - -``` - -如果 `` 和 `` 都配了 connections,`` 优先,参见:[配置的覆盖策略](../../../reference-manual/config/principle/) - -[^1]: 因为连接在 Server上,所以配置在 Provider 上 -[^2]: 如果是长连接,比如 Dubbo 协议,connections 表示该服务对每个提供者建立的长连接数 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/dump.md b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/dump.md deleted file mode 100644 index fd30578c25a5..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/dump.md +++ /dev/null @@ -1,64 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/performance/dump/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/performance/dump/ -description: 在 Dubbo 自动导出线程堆栈来保留现场 -linkTitle: 导出线程堆栈 -title: 导出线程堆栈 -type: docs -weight: 43 ---- - - - - - -## 功能说明 -dubbo 通过 Jstack 自动导出线程堆栈来保留现场,方便排查问题。 - -默认策略 - -* 导出路径: user.home标识的用户主目录 -* 导出间隔: 最短间隔允许每隔10分钟导出一次 -* 导出开关: 默认打开 - -## 使用场景 -当业务线程池满时,我们需要知道线程都在等待哪些资源、条件,以找到系统的瓶颈点或异常点。 - -## 使用方式 - -### 导出开关控制 -```properties -# dubbo.properties -dubbo.application.dump.enable=true -``` -```xml - -``` - -```yaml -dubbo: - application: - name: dubbo-springboot-demo-provider - dump-enable: false -``` - - - -### 指定导出路径 - -```properties -# dubbo.properties -dubbo.application.dump.directory=/tmp -``` - -```xml - -``` - -```yaml -dubbo: - application: - name: dubbo-springboot-demo-provider - dump-directory: /tmp -``` \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/lazy-connect.md b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/lazy-connect.md deleted file mode 100644 index bcf744c8fba2..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/lazy-connect.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/performance/lazy-connect/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/performance/lazy-connect/ -description: 在 Dubbo 中配置延迟连接 -linkTitle: 延迟连接 -title: 延迟连接 -type: docs -weight: 30 ---- - - - - - -## 功能说明 -当消费者请求服务时,实际使用服务时才建立真正的连接,避免不必要的连接来减少延迟并提高系统稳定性。 - -## 使用场景 -延迟连接用于减少长连接数。当有调用发起时,再创建长连接。 - -## 使用方式 -```xml - -``` - -> 该配置只对使用长连接的 dubbo 协议生效。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/loadbalance.md b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/loadbalance.md deleted file mode 100644 index 0c9c5858fc59..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/loadbalance.md +++ /dev/null @@ -1,67 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/performance/loadbalance/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/performance/loadbalance/ -description: Dubbo 提供的集群负载均衡策略 -linkTitle: 负载均衡 -title: 负载均衡 -type: docs -weight: 3 ---- - -## 功能说明 -* [Dubbo 负载均衡算法说明](/zh-cn/overview/core-features/load-balance/) -* 如果要扩展更多负载均衡策略,参见 [Java SPI 负载均衡扩展](../../../reference-manual/spi/description/load-balance) - -目前 Dubbo 内置了如下负载均衡算法,用户可直接配置使用: - -| 算法 | 特性 | 备注 | 配置值 | -| :-------------------------- | :---------------------- | :---------------------------------------------- | :---------------------------------------------- | -| Weighted Random LoadBalance | 加权随机 | 默认算法,默认权重相同 | random (默认) | -| RoundRobin LoadBalance | 加权轮询 | 借鉴于 Nginx 的平滑加权轮询算法,默认权重相同, | roundrobin | -| LeastActive LoadBalance | 最少活跃优先 + 加权随机 | 背后是能者多劳的思想 | leastactive | -| Shortest-Response LoadBalance | 最短响应优先 + 加权随机 | 更加关注响应速度 | shortestresponse | -| ConsistentHash LoadBalance | 一致性哈希 | 确定的入参,确定的提供者,适用于有状态请求 | consistenthash | -| P2C LoadBalance | Power of Two Choice | 随机选择两个节点后,继续选择“连接数”较小的那个节点。 | p2c | -| Adaptive LoadBalance | 自适应负载均衡 | 在 P2C 算法基础上,选择二者中 load 最小的那个节点 | adaptive | - -## 使用场景 -- 高可用性:部署服务的多个实例以确保即使一个或多个实例失败服务保持可用,负载均衡功能可用于在这些实例之间分配传入的请求确保以负载均衡方式使用每个实例的方式,还能最大限度地降低服务停机的风险。 - -- 流量管理:限制指向特定服务实例的流量,以防止过载或确保公平的资源分配,负载均衡特性提供了 Round Robin、Weighted Round Robin、Random、Least Active Load Balancing 等多种负载均衡策略,可以用来实现流量控制。 - -- 服务划分:将一个服务划分成多个逻辑组件,每个逻辑组件可以部署在不同的实例上,使用负载平衡以确保每个分区平衡的方式在这些实例之间分配请求,同时在实例发生故障的情况下提供故障转移功能。 - -- 性能优化:负载平衡可用于优化服务的性能,通过跨多个实例分发请求可以利用可用的计算资源来缩短响应时间并减少延迟。 - -## 使用方式 - -> 只需要调整 `loadbalance` 相应取值即可,每种负载均衡策略取值请参见文档最上方表格。 - -### 服务端服务级别 - -```xml - -``` - -### 客户端服务级别 - -```xml - -``` - -### 服务端方法级别 - -```xml - - - -``` - -### 客户端方法级别 - -```xml - - - -``` diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/profiler.md b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/profiler.md deleted file mode 100644 index 7adc09e71104..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/profiler.md +++ /dev/null @@ -1,196 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/performance/profiler/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/performance/profiler/ -description: Dubbo 请求耗时采样 -linkTitle: 请求耗时采样 -title: 请求耗时采样 -type: docs -weight: 1 ---- - - - - - - -## 功能说明 - -性能采样功能可以对 Dubbo 处理链路上的各处耗时进行检测,在出现超时的时候 `( usageTime / timeout > profilerWarnPercent * 100 )` 通过日志记录调用的耗时。 - -此功能分为 `simple profiler` 和 `detail profiler` 两个模式,其中 `simple profiler` 模式默认开启,`detail profiler` 模式默认关闭。 -`detail profiler` 相较 `simple profiler` 模式多采集了每个 filter 的处理耗时、协议上的具体耗时等。 -在 `simple profiler` 模式下如果发现 Dubbo 框架内部存在耗时长的情况,可以开启 `detail profiler` 模式,以便更好地排查问题。 - -## 使用场景 - -需要对 Dubbo 请求的精确耗时进行采集分析的场景,如服务不明原因的超时等 - -## 使用方式 - -`simple profiler` 默认自动开启,对于请求处理时间超过超时时间 3/4 的,都会通过日志打印出慢调用信息。如果需要开启 `detail profiler` 模式或者修改超时告警比例,可以参考[性能采样命令](../../../reference-manual/qos/profiler/)文档。 - -### 日志说明 - -日志中各字段的含义如下: - -``` -[Dubbo-Consumer] execute service 接口#方法 cost 实际耗时, this invocation almost (maybe already) timeout. Timeout: 超时时间 -invocation context: -请求上下文 -thread info: -Start time: 开始请求时间(nano 时间) -+-[ Offset: 当前节点开始时间; Usage: 当前节点使用总耗时, 当前节点耗时比例 ] 当前节点描述 - +-[ Offset: 当前节点开始时间; Usage: 当前节点使用总耗时, 当前节点耗时比例 ] 当前节点描述 -``` - -对于请求耗时这里以两个例子进行介绍: - -``` -methodA() { - do something (1) - methodB (2) - do something (3) -} - -methodB() { - do something (4) - methodC (5) - do something (6) -} - -methodC() { - do something (7) -} - -+-[ Offset: 0 ms; Usage: (1) + (2) + (3) ms] execute methodA - +-[ Offset: (1) ms; Usage: (4) + (5) + (6) = (2) ms ] execute methodB - +-[ Offset: (1) + (4) ms; Usage: (7) = (5) ms ] execute methodC - -(1) (2) (3) ... 均为时间占位符 -``` - -``` -methodA() { - do something (1) - methodB (2) - methodE (3) - do something (4) -} - -methodB() { - do something (5) - methodC (6) - methodD (7) - do something (8) -} - -methodC() { - do something (9) -} - -methodD() { - do something (10) -} - -methodE() { - do something (11) -} - -+-[ Offset: 0 ms; Usage: (1) + (2) + (3) + (4) ms] execute methodA - +-[ Offset: (1) ms; Usage: (5) + (6) + (7) + (8) = (2) ms ] execute methodB - +-[ Offset: (1) + (5) ms; Usage: (9) = (6) ms ] execute methodC - +-[ Offset: (1) + (5) + (6) ms; Usage: (10) = (7) ms ] execute methodD - +-[ Offset: (1) + (2) ms; Usage: (11) = (3) ms ] execute methodE - -(1) (2) (3) ... 均为时间占位符 -``` - -### simple profiler - -Consumer 侧: -``` -[19/07/22 07:08:35:035 CST] main WARN proxy.InvokerInvocationHandler: [DUBBO] [Dubbo-Consumer] execute service org.apache.dubbo.samples.api.GreetingsService#sayHi cost 1003.015746 ms, this invocation almost (maybe already) timeout. Timeout: 1000ms -invocation context: -path=org.apache.dubbo.samples.api.GreetingsService; -remote.application=first-dubbo-consumer; -interface=org.apache.dubbo.samples.api.GreetingsService; -version=0.0.0; -timeout=1000; -thread info: -Start time: 285821581299853 -+-[ Offset: 0.000000ms; Usage: 1003.015746ms, 100% ] Receive request. Client invoke begin. ServiceKey: org.apache.dubbo.samples.api.GreetingsService MethodName:sayHi - +-[ Offset: 7.987015ms; Usage: 994.207928ms, 99% ] Invoker invoke. Target Address: xx.xx.xx.xx:20880, dubbo version: 3.0.10-SNAPSHOT, current host: xx.xx.xx.xx -``` - -Provider 侧: -``` -[19/07/22 07:08:35:035 CST] DubboServerHandler-30.227.64.173:20880-thread-2 WARN filter.ProfilerServerFilter: [DUBBO] [Dubbo-Provider] execute service org.apache.dubbo.samples.api.GreetingsService:0.0.0#sayHi cost 808.494672 ms, this invocation almost (maybe already) timeout. Timeout: 1000ms -client: xx.xx.xx.xx:51604 -invocation context: -input=281; -path=org.apache.dubbo.samples.api.GreetingsService; -remote.application=first-dubbo-consumer; -dubbo=2.0.2; -interface=org.apache.dubbo.samples.api.GreetingsService; -version=0.0.0; -timeout=1000; -thread info: -Start time: 285821754461125 -+-[ Offset: 0.000000ms; Usage: 808.494672ms, 100% ] Receive request. Server invoke begin. - +-[ Offset: 1.030912ms; Usage: 804.236342ms, 99% ] Receive request. Server biz impl invoke begin., dubbo version: 3.0.10-SNAPSHOT, current host: xx.xx.xx.xx -``` - -### detail profiler - -Consumer 侧: -``` -[19/07/22 07:10:59:059 CST] main WARN proxy.InvokerInvocationHandler: [DUBBO] [Dubbo-Consumer] execute service org.apache.dubbo.samples.api.GreetingsService#sayHi cost 990.828336 ms, this invocation almost (maybe already) timeout. Timeout: 1000ms -invocation context: -path=org.apache.dubbo.samples.api.GreetingsService; -remote.application=first-dubbo-consumer; -interface=org.apache.dubbo.samples.api.GreetingsService; -version=0.0.0; -timeout=1000; -thread info: -Start time: 285965458479241 -+-[ Offset: 0.000000ms; Usage: 990.828336ms, 100% ] Receive request. Client invoke begin. ServiceKey: org.apache.dubbo.samples.api.GreetingsService MethodName:sayHi - +-[ Offset: 0.852044ms; Usage: 989.899439ms, 99% ] Filter org.apache.dubbo.rpc.cluster.filter.support.ConsumerContextFilter invoke. - +-[ Offset: 1.814858ms; Usage: 988.924876ms, 99% ] Filter org.apache.dubbo.rpc.protocol.dubbo.filter.FutureFilter invoke. - +-[ Offset: 1.853211ms; Usage: 988.877928ms, 99% ] Filter org.apache.dubbo.monitor.support.MonitorClusterFilter invoke. - +-[ Offset: 1.873243ms; Usage: 988.661708ms, 99% ] Filter org.apache.dubbo.rpc.cluster.router.RouterSnapshotFilter invoke. - +-[ Offset: 2.159140ms; Usage: 0.504939ms, 0% ] Router route. - +-[ Offset: 8.125823ms; Usage: 981.748366ms, 99% ] Cluster org.apache.dubbo.rpc.cluster.support.FailoverClusterInvoker invoke. - +-[ Offset: 8.258359ms; Usage: 981.612033ms, 99% ] Invoker invoke. Target Address: xx.xx.xx.xx:20880, dubbo version: 3.0.10-SNAPSHOT, current host: xx.xx.xx.xx -``` - -Provider 侧: -``` -[19/07/22 07:10:59:059 CST] DubboServerHandler-30.227.64.173:20880-thread-2 WARN filter.ProfilerServerFilter: [DUBBO] [Dubbo-Provider] execute service org.apache.dubbo.samples.api.GreetingsService:0.0.0#sayHi cost 811.017347 ms, this invocation almost (maybe already) timeout. Timeout: 1000ms -client: xx.xx.xx.xx:52019 -invocation context: -input=281; -path=org.apache.dubbo.samples.api.GreetingsService; -remote.application=first-dubbo-consumer; -dubbo=2.0.2; -interface=org.apache.dubbo.samples.api.GreetingsService; -version=0.0.0; -timeout=1000; -thread info: -Start time: 285965612316294 -+-[ Offset: 0.000000ms; Usage: 811.017347ms, 100% ] Receive request. Server invoke begin. - +-[ Offset: 1.096880ms; Usage: 809.916668ms, 99% ] Filter org.apache.dubbo.rpc.filter.EchoFilter invoke. - +-[ Offset: 1.133478ms; Usage: 809.866204ms, 99% ] Filter org.apache.dubbo.rpc.filter.ClassLoaderFilter invoke. - +-[ Offset: 1.157563ms; Usage: 809.838572ms, 99% ] Filter org.apache.dubbo.rpc.filter.GenericFilter invoke. - +-[ Offset: 1.202075ms; Usage: 809.736843ms, 99% ] Filter org.apache.dubbo.rpc.filter.ContextFilter invoke. - +-[ Offset: 1.433193ms; Usage: 809.504401ms, 99% ] Filter org.apache.dubbo.auth.filter.ProviderAuthFilter invoke. - +-[ Offset: 1.470760ms; Usage: 809.464291ms, 99% ] Filter org.apache.dubbo.rpc.filter.ExceptionFilter invoke. - +-[ Offset: 1.489103ms; Usage: 809.440183ms, 99% ] Filter org.apache.dubbo.monitor.support.MonitorFilter invoke. - +-[ Offset: 1.515757ms; Usage: 809.381893ms, 99% ] Filter org.apache.dubbo.rpc.filter.TimeoutFilter invoke. - +-[ Offset: 1.526632ms; Usage: 809.366553ms, 99% ] Filter org.apache.dubbo.rpc.protocol.dubbo.filter.TraceFilter invoke. - +-[ Offset: 1.536964ms; Usage: 809.335907ms, 99% ] Filter org.apache.dubbo.rpc.filter.ClassLoaderCallbackFilter invoke. - +-[ Offset: 1.558545ms; Usage: 804.276436ms, 99% ] Receive request. Server biz impl invoke begin., dubbo version: 3.0.10-SNAPSHOT, current host: xx.xx.xx.xx -``` -{{% alert title="注意" color="warning" %}} -由于日志框架不匹配导致的日志为空可以参考[日志框架适配及运行时管理](../../others/logger-management/)动态修改日志输出框架。 -{{% /alert %}} diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/router-snapshot.md b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/router-snapshot.md deleted file mode 100644 index 5e0982710d4d..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/router-snapshot.md +++ /dev/null @@ -1,89 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/performance/router-snapshot/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/performance/router-snapshot/ -description: 路由状态采集 -linkTitle: 路由状态采集 -title: 路由状态采集 -type: docs -weight: 2 ---- - - - - - -## 功能说明 -路由状态收集功能可用于识别可能影响服务性能的任何潜在问题,识别可能阻碍服务尽可能高效使用的任何潜在瓶颈或问题,确保服务平稳运行,用户在尝试访问服务时不会遇到任何问题,允许用户检查路由的状态是启用还是禁用,确保仅使用授权的服务,并且访问仅限于具有适当授权的人员。 - -## 使用场景 - -Dubbo 的很多流量治理能力是基于 Router 进行实现的,在生产环境中,如果出现流量结果不符合预期的情况,可以通过路由状态命令来查看路由的状态,以此来定位可能存在的问题。 - -## 使用方式 - -### 查看路由缓存状态 - -Dubbo 在收到地址变更的时候,会将地址信息推送给所有的 `Router`,这些 `Router` 可以在此阶段提前计算路由的分组,缓存起来,以避免在调用时需要遍历所有的提供者计算分组参数。 -在 Dubbo 3 中引入的 `StateRouter` 提供了通过 qos 命令工具实时获取每个路由的状态的能力。 - -运维人员可以通过 `getRouterSnapshot` 命令获取路由的状态。具体命令使用方式可以参考 [getRouterSnapshot 命令](../../../reference-manual/qos/router-snapshot/#getroutersnapshot-%E5%91%BD%E4%BB%A4) 文档。 - -**注:此功能仅支持 `StateRoute`,且 `StateRouter` 需要基于 `AbstractStateRouter` 实现 `doBuildSnapshot` 接口。** - -### 查看实际请求的路由计算结果 - -Dubbo 3 中默认在路由筛选后为空的时候打印路由计算的节点状态。运维人员可以通过日志判断每个路由的计算结果是否符合预期。 - -#### 日志格式 - -``` -No provider available after route for the service 服务 from registry 注册中心地址 on the consumer 消费端IP using the dubbo version 3.0.7. Router snapshot is below: -[ Parent (Input: 当前节点输入地址数) (Current Node Output: 当前节点计算结果数) (Chain Node Output: 当前节点和后级节点交集结果数) ] Input: 输入的地址示例(显示最多 5 个) -> Chain Node Output: 当前节点输出的地址示例(显示最多 5 个) - [ 路由名称 (Input: 当前节点输入地址数) (Current Node Output: 当前节点计算结果数) (Chain Node Output: 当前节点和后级节点交集结果数) Router message: 路由日志 ] Current Node Output: 当前节点输出的地址示例(显示最多 5 个) - [ 路由名称 (Input: 当前节点输入地址数) (Current Node Output: 当前节点计算结果数) (Chain Node Output: 当前节点和后级节点交集结果数) Router message: 路由日志 ] Current Node Output: 当前输入的地址示例(显示最多 5 个) -``` - -#### 注意: -- 路由日志需要依赖路由实现判断 `needToPrintMessage` 参数,并在需要时写入 `messageHolder` 路由日志 -- 由于多级路由结果是结果取交集的,所以当前节点计算结果数可能和后级取交后为空 - -#### 日志示例 - -``` -[19/07/22 07:42:46:046 CST] main WARN cluster.RouterChain: [DUBBO] No provider available after route for the service org.apache.dubbo.samples.governance.api.DemoService from registry 30.227.64.173 on the consumer 30.227.64.173 using the dubbo version 3.0.7. Router snapshot is below: -[ Parent (Input: 2) (Current Node Output: 2) (Chain Node Output: 0) ] Input: 30.227.64.173:20881,30.227.64.173:20880 -> Chain Node Output: Empty - [ MockInvokersSelector (Input: 2) (Current Node Output: 2) (Chain Node Output: 0) Router message: invocation.need.mock not set. Return normal Invokers. ] Current Node Output: 30.227.64.173:20881,30.227.64.173:20880 - [ StandardMeshRuleRouter (Input: 2) (Current Node Output: 2) (Chain Node Output: 0) Router message: MeshRuleCache has not been built. Skip route. ] Current Node Output: 30.227.64.173:20881,30.227.64.173:20880 - [ TagStateRouter (Input: 2) (Current Node Output: 0) (Chain Node Output: 0) Router message: FAILOVER: return all Providers without any tags ] Current Node Output: Empty, dubbo version: 3.0.7, current host: 30.227.64.173 -``` - -#### 开启路由全采样 - -在一些特殊情况下,请求可能调用到错误的服务端,但是因为选址非空,所以无法看到路由的过程信息,此时可以 [通过 qos 开启路由全采样](../../../reference-manual/qos/router-snapshot/)。通过 qos 的 `getRecentRouterSnapshot` 命令可以远程获取最近的路由快照。 - -``` -dubbo>getRecentRouterSnapshot -1658224330156 - Router snapshot service com.dubbo.dubbointegration.BackendService from registry 172.18.111.184 on the consumer 172.18.111.184 using the dubbo version 3.0.9 is below: -[ Parent (Input: 2) (Current Node Output: 2) (Chain Node Output: 2) ] Input: 172.18.111.187:20880,172.18.111.183:20880 -> Chain Node Output: 172.18.111.187:20880,172.18.111.183:20880 - [ MockInvokersSelector (Input: 2) (Current Node Output: 2) (Chain Node Output: 2) Router message: invocation.need.mock not set. Return normal Invokers. ] Current Node Output: 172.18.111.187:20880,172.18.111.183:20880 - [ StandardMeshRuleRouter (Input: 2) (Current Node Output: 2) (Chain Node Output: 2) Router message: MeshRuleCache has not been built. Skip route. ] Current Node Output: 172.18.111.187:20880,172.18.111.183:20880 - [ TagStateRouter (Input: 2) (Current Node Output: 2) (Chain Node Output: 2) Router message: Disable Tag Router. Reason: tagRouterRule is invalid or disabled ] Current Node Output: 172.18.111.187:20880,172.18.111.183:20880 - [ ServiceStateRouter (Input: 2) (Current Node Output: 2) (Chain Node Output: 2) Router message: Directly return. Reason: Invokers from previous router is empty or conditionRouters is empty. ] Current Node Output: 172.18.111.187:20880,172.18.111.183:20880 - [ AppStateRouter (Input: 2) (Current Node Output: 2) (Chain Node Output: 2) Router message: Directly return. Reason: Invokers from previous router is empty or conditionRouters is empty. ] Current Node Output: 172.18.111.187:20880,172.18.111.183:20880 - -1658224330156 - Router snapshot service com.dubbo.dubbointegration.BackendService from registry 172.18.111.184 on the consumer 172.18.111.184 using the dubbo version 3.0.9 is below: -[ Parent (Input: 2) (Current Node Output: 2) (Chain Node Output: 2) ] Input: 172.18.111.187:20880,172.18.111.183:20880 -> Chain Node Output: 172.18.111.187:20880,172.18.111.183:20880 - [ MockInvokersSelector (Input: 2) (Current Node Output: 2) (Chain Node Output: 2) Router message: invocation.need.mock not set. Return normal Invokers. ] Current Node Output: 172.18.111.187:20880,172.18.111.183:20880 - [ StandardMeshRuleRouter (Input: 2) (Current Node Output: 2) (Chain Node Output: 2) Router message: MeshRuleCache has not been built. Skip route. ] Current Node Output: 172.18.111.187:20880,172.18.111.183:20880 - [ TagStateRouter (Input: 2) (Current Node Output: 2) (Chain Node Output: 2) Router message: Disable Tag Router. Reason: tagRouterRule is invalid or disabled ] Current Node Output: 172.18.111.187:20880,172.18.111.183:20880 - [ ServiceStateRouter (Input: 2) (Current Node Output: 2) (Chain Node Output: 2) Router message: Directly return. Reason: Invokers from previous router is empty or conditionRouters is empty. ] Current Node Output: 172.18.111.187:20880,172.18.111.183:20880 - [ AppStateRouter (Input: 2) (Current Node Output: 2) (Chain Node Output: 2) Router message: Directly return. Reason: Invokers from previous router is empty or conditionRouters is empty. ] Current Node Output: 172.18.111.187:20880,172.18.111.183:20880 - -··· - -dubbo> -``` - -#### 注意: -由于日志框架不匹配导致的日志为空可以参考[日志框架适配及运行时管理](../../others/logger-management/)动态修改日志输出框架。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/serialization.md b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/serialization.md deleted file mode 100644 index 513fa41e437b..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/serialization.md +++ /dev/null @@ -1,253 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/performance/serialization/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/performance/serialization/ -description: 在 Dubbo 中使用高效的 Java 序列化(Kryo 和 FST) -linkTitle: Kryo 和 FST 序列化 -title: Kryo 和 FST 序列化 -type: docs -weight: 46 ---- - - - - - -## 功能说明 -### 序列化漫谈 -#### 漫谈一 - -dubbo RPC是dubbo体系中最核心的一种高性能、高吞吐量的远程调用方式,我喜欢称之为多路复用的TCP长连接调用。主要用于两个dubbo系统之间作远程调用,特别适合高并发、小数据的互联网场景。 - -**长连接:避免了每次调用新建TCP连接,提高了调用的响应速度。** - -**多路复用:单个TCP连接可交替传输多个请求和响应的消息,降低了连接的等待闲置时间,从而减少了同样并发数下的网络连接数,提高了系统吞吐量。** - - - -#### 漫谈二 - -而序列化对于远程调用的响应速度、吞吐量、网络带宽消耗等同样也起着至关重要的作用,是我们提升分布式系统性能的最关键因素之一。 - -在dubbo RPC中,同时支持多种序列化方式 - -**dubbo序列化:阿里尚未开发成熟的高效java序列化实现,阿里不建议在生产环境使用它** - -**hessian2序列化:hessian是一种跨语言的高效二进制序列化方式。但这里实际不是原生的序列化,而是阿里修改过的hessian lite,它是dubbo RPC默认启用的序列化方式。** - -**json序列化:目前有两种实现,一种是采用的阿里的fastjson库,另一种是采用dubbo中自己实现的简单json库,但其实现都不是特别成熟,而且json这种文本序列化性能一般不如上面两种二进制序列化。** - -**java序列化:主要是采用JDK自带的Java序列化实现,性能很不理想。** - -在通常情况下,这四种主要序列化方式的性能从上到下依次递减。 - -对于dubbo RPC这种追求高性能的远程调用方式来说,实际上只有1、2两种高效序列化方式比较般配,而第1个dubbo序列化由于还不成熟,所以实际只剩下2可用,所以dubbo RPC默认采用hessian2序列化。 - -但hessian是一个比较老的序列化实现了,而且它是跨语言的,所以不是单独针对java进行优化的。而dubbo RPC实际上完全是一种Java to Java的远程调用,其实没有必要采用跨语言的序列化方式(当然肯定也不排斥跨语言的序列化)。 - -最近几年,各种新的高效序列化方式层出不穷,不断刷新序列化性能的上限,最典型包括: - -**专门针对Java语言的:Kryo,FST等等** - -**跨语言的:Protostuff,ProtoBuf,Thrift,Avro,MsgPack等等** - -这些序列化方式的性能多数都显著优于hessian2(甚至包括尚未成熟的dubbo序列化)。 - -有鉴于此,我们为dubbo引入Kryo和FST这两种高效Java序列化实现,来逐步取代hessian2。 - -其中,Kryo是一种非常成熟的序列化实现,已经在Twitter、Groupon、Yahoo以及多个著名开源项目(如Hive、Storm)中广泛的使用。而FST是一种较新的序列化实现,目前还缺乏足够多的成熟使用案例,但我认为它还是非常有前途的。 - -在面向生产环境的应用中,我建议目前更优先选择Kryo。 - -## 使用场景 -高性能微服务,大型对象图,分布式系统等 - -## 实现方式 -### 启用Kryo和FST - -使用Kryo和FST非常简单,只需要先增加对应的依赖。 -更多插件: [Dubbo SPI Extensions](/zh-cn/download/spi-extensions) - -```xml - - org.apache.dubbo.extensions - dubbo-serialization-kryo - 1.0.0 - -``` - -```xml - - org.apache.dubbo.extensions - dubbo-serialization-fst - 1.0.0 - -``` - -然后在dubbo RPC的XML配置中添加一个属性即可: - -```xml - -``` - -```xml - -``` - -### 注册被序列化类 - -要让Kryo和FST完全发挥出高性能,最好将那些需要被序列化的类注册到dubbo系统中,实现如下 - -**回调接口** -```java -public class SerializationOptimizerImpl implements SerializationOptimizer { - - public Collection getSerializableClasses() { - List classes = new LinkedList(); - classes.add(BidRequest.class); - classes.add(BidResponse.class); - classes.add(Device.class); - classes.add(Geo.class); - classes.add(Impression.class); - classes.add(SeatBid.class); - return classes; - } -} -``` - -然后在XML配置中添加: - -```xml - -``` - -在注册这些类后,序列化的性能可能被大大提升,特别针对小数量的嵌套对象的时候。 - -当然,在对一个类做序列化的时候,可能还级联引用到很多类,比如Java集合类。 - -针对这种情况,我们已经自动将JDK中的常用类进行了注册,所以你不需要重复注册它们(当然你重复注册了也没有任何影响)。 - -包括 -``` -GregorianCalendar -InvocationHandler -BigDecimal -BigInteger -Pattern -BitSet -URI -UUID -HashMap -ArrayList -LinkedList -HashSet -TreeSet -Hashtable -Date -Calendar -ConcurrentHashMap -SimpleDateFormat -Vector -BitSet -StringBuffer -StringBuilder -Object -Object[] -String[] -byte[] -char[] -int[] -float[] -double[] -``` - -由于注册被序列化的类仅仅是出于性能优化的目的,所以即使你忘记注册某些类也没有关系。 - -事实上,即使不注册任何类,Kryo和FST的性能依然普遍优于hessian和dubbo序列化。 - -> 当然,有人可能会问为什么不用配置文件来注册这些类?这是因为要注册的类往往数量较多,导致配置文件冗长;而且在没有好的IDE支持的情况下,配置文件的编写和重构都比java类麻烦得多;最后,这些注册的类一般是不需要在项目编译打包后还需要做动态修改的。 - -> 另外,有人也会觉得手工注册被序列化的类是一种相对繁琐的工作,是不是可以用annotation来标注,然后系统来自动发现并注册。但这里annotation的局限是,它只能用来标注你可以修改的类,而很多序列化中引用的类很可能是你没法做修改的(比如第三方库或者JDK系统类或者其他项目的类)。另外,添加annotation毕竟稍微的“污染”了一下代码,使应用代码对框架增加了一点点的依赖性。 - -> 除了annotation,我们还可以考虑用其它方式来自动注册被序列化的类,例如扫描类路径,自动发现实现Serializable接口(甚至包括Externalizable)的类并将它们注册。当然,我们知道类路径上能找到Serializable类可能是非常多的,所以也可以考虑用package前缀之类来一定程度限定扫描范围。 - -> 当然,在自动注册机制中,特别需要考虑如何保证服务提供端和消费端都以同样的顺序(或者ID)来注册类,避免错位,毕竟两端可被发现然后注册的类的数量可能都是不一样的。 - -### 无参构造函数和Serializable接口 - -如果被序列化的类中不包含无参的构造函数,则在Kryo的序列化中,性能将会大打折扣,因为此时我们在底层将用Java的序列化来透明的取代Kryo序列化。所以,尽可能为每一个被序列化的类添加无参构造函数是一种最佳实践(当然一个java类如果不自定义构造函数,默认就有无参构造函数)。 - -另外,Kryo和FST本来都不需要被序列化的类实现Serializable接口,但我们还是建议每个被序列化类都去实现它,因为这样可以保持和Java序列化以及dubbo序列化的兼容性,另外也使我们未来采用上述某些自动注册机制带来可能。 - -### 序列化性能分析与测试 - -本文我们主要讨论的是序列化,但在做性能分析和测试的时候我们并不单独处理每种序列化方式,而是把它们放到dubbo RPC中加以对比,因为这样更有现实意义。 - - -**测试环境** - -* 两台独立服务器 -* 4核Intel(R) Xeon(R) CPU E5-2603 0 @ 1.80GHz -* 8G内存 -* 虚拟机之间网络通过百兆交换机 -* CentOS 5 -* JDK 7 -* Tomcat 7 -* JVM参数-server -Xms1g -Xmx1g -XX:PermSize=64M -XX:+UseConcMarkSweepGC - -> 当然这个测试环境较有局限,故当前测试结果未必有非常权威的代表性。 - -### 测试脚本 - -和dubbo自身的基准测试保持接近: - -10个并发客户端持续不断发出请求: - -* 传入嵌套复杂对象(但单个数据量很小),不做任何处理,原样返回 -* 传入50K字符串,不做任何处理,原样返回(TODO:结果尚未列出) - -进行5分钟性能测试。(引用dubbo自身测试的考虑:主要考察序列化和网络IO的性能,因此服务端无任何业务逻辑。取10并发是考虑到rpc协议在高并发下对CPU的使用率较高可能会先打到瓶颈。) - -### Dubbo RPC中不同序列化生成字节大小比较 - -序列化生成字节数的大小是一个比较有确定性的指标,它决定了远程调用的网络传输时间和带宽占用。 - -针对复杂对象的结果如下(数值越小越好): - -| 序列化实现 | 请求字节数 | 响应字节数 | -| ----------- | ------------- | ------------- | -| Kryo | 272 | 90 | -| FST | 288 | 96 | -| Dubbo Serialization | 430 | 186 | -| Hessian | 546 | 329 | -| FastJson | 461 | 218 | -| Json | 657 | 409 | -| Java Serialization | 963 | 630 | - - -### Dubbo RPC中不同序列化响应时间和吞吐量对比 - -| 远程调用方式 | 平均响应时间 | 平均TPS(每秒事务数) | -| ----------- | ------------- | ------------- | -| REST: Jetty + JSON | 7.806 | 1280 | -| REST: Jetty + JSON + GZIP | TODO | TODO | -| REST: Jetty + XML | TODO | TODO | -| REST: Jetty + XML + GZIP | TODO | TODO | -| REST: Tomcat + JSON | 2.082 | 4796 | -| REST: Netty + JSON | 2.182 | 4576 | -| Dubbo: FST | 1.211 | 8244 | -| Dubbo: kyro | 1.182 | 8444 | -| Dubbo: dubbo serialization | 1.43 | 6982 | -| Dubbo: hessian2 | 1.49 | 6701 | -| Dubbo: fastjson | 1.572 | 6352 | - -![rt](/imgs/user/rt.png) - -![tps](/imgs/user/tps.png) - - -> 测试总结: 就目前结果而言,我们可以看到不管从生成字节的大小,还是平均响应时间和平均TPS,Kryo和FST相比Dubbo RPC中原有的序列化方式都有非常显著的改进。 - - - -> 未来展望:当Kryo或者FST在dubbo中当应用足够成熟之后,我们很可能会将dubbo RPC的默认序列化从hessian2改为它们中间的某一个。 diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/simplify-registry-data.md b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/simplify-registry-data.md deleted file mode 100644 index aef0cb59e386..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/simplify-registry-data.md +++ /dev/null @@ -1,272 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/performance/simplify-registry-data/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/performance/simplify-registry-data/ -description: 了解 Dubbo 减少注册中心上服务的注册数据 -linkTitle: 注册信息简化 -title: 注册信息简化 -type: docs -weight: 3 ---- - - - - - - -## 功能说明 - -Dubbo provider 中的服务配置项有接近 [30 个配置项](/zh-cn/docs/references/xml/dubbo-parameter)。 排除注册中心服务治理需要之外,很大一部分配置项是 provider 自己使用,不需要透传给消费者。这部分数据不需要进入注册中心,而只需要以 key-value 形式持久化存储。 - -Dubbo consumer 中的配置项也有 [20+个配置项](/zh-cn/docs/references/xml/dubbo-consumer)。在注册中心之中,服务消费者列表中只需要关注 application,version,group,ip,dubbo 版本等少量配置,其他配置也可以以 key-value 形式持久化存储。 -这些数据是以服务为维度注册进入注册中心,导致了数据量的膨胀,进而引发注册中心 (如 zookeeper) 的网络开销增大,性能降低。 - -{{% alert title="设计目标和宗旨" color="primary" %}} - -1. 期望简化进入注册中心的 provider 和 consumer 配置数量。 -2. 期望将部分配置项以其他形式存储。这些配置项需要满足:不在服务调用链路上,同时这些配置项不在注册中心的核心链路上(服务查询,服务列表)。 -{{% /alert %}} - -> 注意:简化注册中心的配置,只在 2.7 之后的版本中进行支持。开启 provider 或者 consumer 简化配置之后,默认保留的配置项。 - -**provider** - -| Constant Key | Key | remark | -| ------ |---------------| ------ | -| APPLICATION_KEY | application | | -| CODEC_KEY | codec | | -| EXCHANGER_KEY | exchanger | | -| SERIALIZATION_KEY | serialization | | -| CLUSTER_KEY | cluster | | -| CONNECTIONS_KEY | connections | | -| DEPRECATED_KEY | deprecated | | -| GROUP_KEY | group | | -| LOADBALANCE_KEY | loadbalance | | -| MOCK_KEY | mock | | -| PATH_KEY | path | | -| TIMEOUT_KEY | timeout | | -| TOKEN_KEY | token | | -| VERSION_KEY | version | | -| WARMUP_KEY | warmup | | -| WEIGHT_KEY | weight | | -| DUBBO_VERSION_KEY | dubbo | | -| RELEASE_KEY | release | | -| SIDE_KEY | side | | - - -**consumer** - -| Constant Key | Key | remark | -| ------ | ------ | ------ | -| APPLICATION_KEY | application | | -| VERSION_KEY | version | | -| GROUP_KEY | group | | -| DUBBO_VERSION_KEY | dubbo | | - -Constant Key 表示来自于类 org.apache.dubbo.common.Constants 的字段。 - -下面介绍几种常用的使用方式。所有的 sample,都可以查看 [sample-2.7](https://github.com/dubbo/dubbo-samples/tree/master) - -## 使用场景 - -数据量大导致注册中心的网络开销增大,性能降低。 - -## 使用方式 - -**现有功能 sample** 当前现状一个简单展示。通过这个展示,分析下为什么需要做简化配置。 - -参考 sample 子工程: dubbo-samples-simplified-registry/dubbo-samples-simplified-registry-nosimple (跑 sample 前,先跑下 ZKClean 进行配置项清理) - -### dubbo-provider.xml - -``` - - - - -``` - -启动 provider 的 main 方法之后,查看 zookeeper 的叶子节点(路径为:/dubbo/org.apache.dubbo.samples.simplified.registry.nosimple.api.DemoService/providers 目录下)的内容 - -``` -dubbo://30.5.124.158:20880/org.apache.dubbo.samples.simplified.registry.nosimple.api.DemoService -?anyhost=true -&application=simplified-registry-xml-provider -&async=true -&dubbo=2.0.2 -&executes=4500 -&generic=false -&group=dubbo-simple -&interface=org.apache.dubbo.samples.simplified.registry.nosimple.api.DemoService -&methods=sayHello -&owner=vict -&pid=2767 -&retries=7 -&revision=1.2.3 -&side=provider -&timeout=5300 -×tamp=1542361152795 -&valid=true -&version=1.2.3 -``` - -从中能看到有:`executes`, `retries`, `owner`, `timeout`。但是这些字段不是每个都需要传递给 dubbo ops 或者 dubbo consumer。 同样的,consumer 也有这个问题,可以在例子中启动 Consumer 的 main 方法进行查看。 - - - -### 1. dubbo.properties - -sample 在 dubbo-samples-simplified-registry/dubbo-samples-simplified-registry-xml 工程下 (跑 sample 前,先跑下ZKClean 进行配置项清理) - -```properties -dubbo.registry.simplified=true -dubbo.registry.extra-keys=retries,owner -``` -和上面的 **现有功能 sample** 进行对比,上面的 sample 中,executes, retries, owner, timeout 四个配置项都进入了注册中心。但是本实例不是,配置情况分为: - -* 配置:dubbo.registry.simplified=true, 默认情况下,timeout 在默认的配置项列表,所以还是会进入注册中心; -* 配置:dubbo.registry.extra-keys=retries,owner , 所以 retries,owner 也会进入注册中心。 - -### provider 端 - -```xml - - - - - - - - -``` -得到的 zookeeper 的叶子节点的值 -``` -dubbo://30.5.124.149:20880/org.apache.dubbo.samples.simplified.registry.nosimple.api.DemoService -?application=simplified-registry-xml-provider -&dubbo=2.0.2 -&group=dubbo-simple -&owner=vict -&retries=7 -&timeout=5300 -×tamp=1542594503305 -&version=1.2.3 -``` - -### consumer 端 -* 配置:dubbo.registry.simplified=true -* 默认情况:application,version,group,dubbo 在默认的配置项列表,所以还是会进入注册中心。 -```xml - - - - - - - - - - -``` -得到的 zookeeper 的叶子节点的值 -``` -consumer://30.5.124.149/org.apache.dubbo.samples.simplified.registry.nosimple.api.DemoService -?actives=6 -&application=simplified-registry-xml-consumer -&category=consumers -&check=false -&dubbo=2.0.2 -&group=dubbo-simple -&owner=vvv -&version=1.2.3 -``` - -### 2.声明 spring bean - -sample 在 dubbo-samples-simplified-registry/dubbo-samples-simplified-registry-annotation 工程下 (跑 sample 前,先跑下 ZKClean 进行配置项清理) - -和上面 sample 中的 dubbo.properties 的效果是一致的。 - -* 默认情况:timeout 在默认的配置项列表,所以还是会进入注册中心; -* 配置: retries,owner 作为额外的 key 进入注册中心 , 所以 retries,owner 也会进入注册中心。 - -### Provider 配置 - -#### privider 端 bean 配置 -```java -// 等同于dubbo.properties配置,用@Bean形式进行配置 -@Bean -public RegistryConfig registryConfig() { - RegistryConfig registryConfig = new RegistryConfig(); - registryConfig.setAddress("zookeeper://127.0.0.1:2181"); - registryConfig.setSimplified(true); - registryConfig.setExtraKeys("retries,owner"); - return registryConfig; -} -``` - -```java -// 暴露服务 -@Service(version = "1.1.8", group = "d-test", executes = 4500, retries = 7, owner = "victanno", timeout = 5300) -public class AnnotationServiceImpl implements AnnotationService { - @Override - public String sayHello(String name) { - System.out.println("async provider received: " + name); - return "annotation: hello, " + name; - } -} -``` -### Consumer 配置 - -和上面 sample 中 **consumer 端配置** 是一样的。 - -默认情况: application,version,group,dubbo 在默认的配置项列表,所以还是会进入注册中心。 - -#### consumer 端 bean 配置 -```java -@Bean -public RegistryConfig registryConfig() { - RegistryConfig registryConfig = new RegistryConfig(); - registryConfig.setAddress("zookeeper://127.0.0.1:2181"); - registryConfig.setSimplified(true); - return registryConfig; - } -``` - -消费服务 - -```java -@Component("annotationAction") -public class AnnotationAction { - - @Reference(version = "1.1.8", group = "d-test", owner = "vvvanno", retries = 4, actives = 6, timeout = 4500) - private AnnotationService annotationService; - public String doSayHello(String name) { - return annotationService.sayHello(name); - } -} -``` -> 注意: 如果一个应用中既有 provider 又有 consumer,那么配置需要合并成如下 -```java -@Bean -public RegistryConfig registryConfig() { - RegistryConfig registryConfig = new RegistryConfig(); - registryConfig.setAddress("zookeeper://127.0.0.1:2181"); - registryConfig.setSimplified(true); - //只对provider生效 - registryConfig.setExtraKeys("retries,owner"); - return registryConfig; -} -``` -> 提示:本版本还保留了大量的配置项,接下来的版本中,会逐渐删除所有的配置项。 diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/stickiness.md b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/stickiness.md deleted file mode 100644 index ba0d4684e912..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/stickiness.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/performance/stickiness/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/performance/stickiness/ -description: 为有状态服务配置粘滞连接 -linkTitle: 粘滞连接 -title: 粘滞连接 -type: docs -weight: 31 ---- - - - - - -## 功能说明 -允许消费者在提供者接收请求之前向提供者发送请求,消费者等待提供者准备就绪,然后将发送消费者者的请求,当消费者需要连接到提供者,提供者尚未准备好接受请求时,确保在正确的时间发送请求,防止消费者被速度慢或不可用的提供程序阻止。 - -## 使用场景 -粘滞连接用于有状态服务,尽可能让客户端总是向同一提供者发起调用,除非该提供者挂了,再连另一台。 - -粘滞连接将自动开启 [延迟连接](../lazy-connect),以减少长连接数。 - -## 使用方式 -```xml - -``` - -Dubbo 支持方法级别的粘滞连接,如果你想进行更细粒度的控制,还可以这样配置。 - -```xml - - - -``` \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/threading-model/_index.md b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/threading-model/_index.md deleted file mode 100755 index 0fa6a0a29ee3..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/threading-model/_index.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/performance/threading-model/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/performance/threading-model/ -description: 生产者和消费者线程模型 -linkTitle: 线程模型 -title: 线程模型 -type: docs -weight: 1 ---- diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/threading-model/consumer.md b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/threading-model/consumer.md deleted file mode 100644 index 1409d4d9a426..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/threading-model/consumer.md +++ /dev/null @@ -1,57 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/performance/threading-model/consumer/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/performance/threading-model/consumer/ -description: Dubbo 消费端线程池模型用法 -linkTitle: 消费端线程模型 -title: 消费端线程模型 -type: docs -weight: 2 ---- - - - - - -## 功能说明 -2.7.5 版本对整个调用链路做了全面的优化,根据压测结果显示,总体 QPS 性能提升将近 30%,同时也减少了调用过程中的内存分配开销。其中一个值得提及的设计点是 2.7.5 引入了 Servicerepository 的概念,在服务注册阶段提前生成 ServiceDescriptor 和 MethodDescriptor,以减少 RPC 调用阶段计算 Service 原信息带来的资源消耗。 - -## 使用场景 -并发请求,负载均衡,连接管理,超时处理,容错等。 - -## 实现方式 -### 消费端线程池模型优化 - -对 2.7.5 版本之前的 Dubbo 应用,尤其是一些消费端应用,当面临需要消费大量服务且并发数比较大的大流量场景时(典型如网关类场景),经常会出现消费端线程数分配过多的问题,具体问题讨论可参见 [Need a limited Threadpool in consumer side #2013](https://github.com/apache/dubbo/issues/2013) - -改进后的消费端线程池模型,通过复用业务端被阻塞的线程,很好的解决了这个问题。 - -### 老的线程池模型 - -![消费端线程池.png](/imgs/user/consumer-threadpool0.png) - -我们重点关注 Consumer 部分: - -1. 业务线程发出请求,拿到一个 Future 实例。 -2. 业务线程紧接着调用 future.get 阻塞等待业务结果返回。 -3. 当业务数据返回后,交由独立的 Consumer 端线程池进行反序列化等处理,并调用 future.set 将反序列化后的业务结果置回。 -4. 业务线程拿到结果直接返回 - - - -### 2.7.5 版本引入的线程池模型 - -![消费端线程池新.png](/imgs/user/consumer-threadpool1.png) - -1. 业务线程发出请求,拿到一个 Future 实例。 -2. 在调用 future.get() 之前,先调用 ThreadlessExecutor.wait(),wait 会使业务线程在一个阻塞队列上等待,直到队列中被加入元素。 -3. 当业务数据返回后,生成一个 Runnable Task 并放入 ThreadlessExecutor 队列 -4. 业务线程将 Task 取出并在本线程中执行:反序列化业务数据并 set 到 Future。 -5. 业务线程拿到结果直接返回 - -这样,相比于老的线程池模型,由业务线程自己负责监测并解析返回结果,免去了额外的消费端线程池开销。 - -关于性能优化,在接下来的版本中将会持续推进,主要从以下两个方面入手: - -1. RPC 调用链路。目前能看到的点包括:进一步减少执行链路的内存分配、在保证协议兼容性的前提下提高协议传输效率、提高 Filter、Router 等计算效率。 -2. 服务治理链路。进一步减少地址推送、服务治理规则推送等造成的内存、cpu 资源消耗。 diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/threading-model/provider.md b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/threading-model/provider.md deleted file mode 100644 index e9bde113d60f..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/threading-model/provider.md +++ /dev/null @@ -1,138 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/performance/threading-model/provider/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/performance/threading-model/provider/ -description: Dubbo 服务提供端端线程池模型和用法 -linkTitle: 服务端线程模型 -title: 服务端线程模型 -type: docs -weight: 1 ---- - - - - - -## 功能说明 -Dubbo协议的和Triple协议目前的线程模型还并没有对齐,下面分开介绍Triple协议和Dubbo协议的线程模型。 - -### Dubbo协议—Provider端线程模型 - -介绍Dubbo协议的Provider端线程模型之前,先介绍Dubbo对channel上的操作抽象成了五种行为: - -- 建立连接:connected,主要是的职责是在channel记录read、write的时间,以及处理建立连接后的回调逻辑,比如dubbo支持在断开后自定义回调的hook(onconnect),即在该操作中执行。 -- 断开连接:disconnected,主要是的职责是在channel移除read、write的时间,以及处理端开连接后的回调逻辑,比如dubbo支持在断开后自定义回调的hook(ondisconnect),即在该操作中执行。 -- 发送消息:sent,包括发送请求和发送响应。记录write的时间。 -- 接收消息:received,包括接收请求和接收响应。记录read的时间。 -- 异常捕获:caught,用于处理在channel上发生的各类异常。 - -Dubbo框架的线程模型与以上这五种行为息息相关,Dubbo协议Provider线程模型可以分为五类,也就是AllDispatcher、DirectDispatcher、MessageOnlyDispatcher、ExecutionDispatcher、ConnectionOrderedDispatcher。 - -### Triple协议—Provider端线程模型 - -下图为Triple协议 Provider端的线程模型 - -![triple-provider](/imgs/v3/feature/performance/threading-model/triple-provider.png) - -Triple协议Provider线程模型目前还比较简单,目前序列化和反序列化操作都在Dubbo线程上工作,而IO线程并没有承载这些工作。 - -### All Dispatcher - -下图是All Dispatcher的线程模型说明图: - -![dubbo-provider-alldispatcher](/imgs/v3/feature/performance/threading-model/dubbo-provider-alldispatcher.png) - -- 在IO线程中执行的操作有: - 1. sent操作在IO线程上执行。 - 2. 序列化响应在IO线程上执行。 -- 在Dubbo线程中执行的操作有: - 1. received、connected、disconnected、caught都是在Dubbo线程上执行的。 - 2. 反序列化请求的行为在Dubbo中做的。 - -### Direct Dispatcher - -下图是Direct Dispatcher的线程模型说明图: - -![dubbo-provider-directDispatcher](/imgs/v3/feature/performance/threading-model/dubbo-provider-directDispatcher.png) - -- 在IO线程中执行的操作有: - 1. received、connected、disconnected、caught、sent操作在IO线程上执行。 - 2. 反序列化请求和序列化响应在IO线程上执行。 -- 1. 并没有在Dubbo线程操作的行为。 - -### Execution Dispatcher - -下图是Execution Dispatcher的线程模型说明图: - -![dubbo-provider-ExecutionDispatcher](/imgs/v3/feature/performance/threading-model/dubbo-provider-executionDispatcher.png) - -- 在IO线程中执行的操作有: - 1. sent、connected、disconnected、caught操作在IO线程上执行。 - 2. 序列化响应在IO线程上执行。 -- 在Dubbo线程中执行的操作有: - 1. received都是在Dubbo线程上执行的。 - 2. 反序列化请求的行为在Dubbo中做的。 - -### Message Only Dispatcher - -在Provider端,Message Only Dispatcher和Execution Dispatcher的线程模型是一致的,所以下图和Execution Dispatcher的图一致,区别在Consumer端。见下方Consumer端的线程模型。 - -下图是Message Only Dispatcher的线程模型说明图: - -![dubbo-provider-ExecutionDispatcher](/imgs/v3/feature/performance/threading-model/dubbo-provider-executionDispatcher.png) - -- 在IO线程中执行的操作有: - 1. sent、connected、disconnected、caught操作在IO线程上执行。 - 2. 序列化响应在IO线程上执行。 -- 在Dubbo线程中执行的操作有: - 1. received都是在Dubbo线程上执行的。 - 2. 反序列化请求的行为在Dubbo中做的。 - -### Connection Ordered Dispatcher - -下图是Connection Ordered Dispatcher的线程模型说明图: - -![dubbbo-provider-connectionOrderedDispatcher](/imgs/v3/feature/performance/threading-model/dubbbo-provider-connectionOrderedDispatcher.png) - -- 在IO线程中执行的操作有: - 1. sent操作在IO线程上执行。 - 2. 序列化响应在IO线程上执行。 -- 在Dubbo线程中执行的操作有: - 1. received、connected、disconnected、caught都是在Dubbo线程上执行的。但是connected和disconnected两个行为是与其他两个行为通过线程池隔离开的。并且在Dubbo connected thread pool中提供了链接限制、告警灯能力。 - 2. 反序列化请求的行为在Dubbo中做的。 - - - -## 使用场景 -异步处理,连接管理,资源管理,负载均衡,容错等。 - -## 使用方式 - -| 线程模型 | 配置 | -| ---- | -- | -All Dispatcher | all -Direct Dispatcher | direct -Execution Dispatcher | execution -Message Only Dispatcher | message -Connection Ordered Dispatcher | connection - -### 线程模型示例 - -拿yaml的配置方式举例:在protocol下配置dispatcher: all,即可把dubbo协议的线程模型调整为All Dispatcher - -```yaml -dubbo: - application: - name: dubbo-springboot-demo-provider - protocol: - name: dubbo - port: -1 - dispatcher: all - registry: - id: zk-registry - address: zookeeper://127.0.0.1:2181 - config-center: - address: zookeeper://127.0.0.1:2181 - metadata-report: - address: zookeeper://127.0.0.1:2181 -``` diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/security/_index.md b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/security/_index.md deleted file mode 100755 index 9d442ac47de7..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/security/_index.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/security/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/security/ -description: 提升服务安全性 -linkTitle: 提升安全性 -title: 提升服务安全性 -type: docs -weight: 4 ---- diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/_index.md b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/_index.md deleted file mode 100755 index e2284e70a7a9..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/_index.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/service/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/service/ -description: 配置框架与服务行为 -linkTitle: 框架与服务 -title: 配置框架与服务行为 -type: docs -weight: 1 ---- diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/accesslog.md b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/accesslog.md deleted file mode 100644 index 06df94342dc2..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/accesslog.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/service/accesslog/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/service/accesslog/ -description: 了解 Dubbo 调用信息记录通过访问日志来配置和使用 -linkTitle: 调用信息记录 -title: 调用信息记录 -type: docs -weight: 13 ---- - - - - - -## 特性说明 - -在 dubbo3 日志分为日志适配和访问日志,如果想记录每一次请求信息,可开启访问日志,类似于 apache 的访问日志。 - -## 使用场景 - -基于审计需要等类似 nginx accesslog 输出等。 - -## 使用方式 -### log4j 日志 -将访问日志输出到当前应用的 log4j 日志 -```xml - -``` -### 指定文件 -将访问日志输出到指定文件 -```xml - -``` -> 此日志量比较大,请注意磁盘容量。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/async-call.md b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/async-call.md deleted file mode 100644 index 64a39d698ada..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/async-call.md +++ /dev/null @@ -1,184 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/service/async-call/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/service/async-call/ -description: 在 Dubbo 中发起异步调用 -linkTitle: 异步调用 -title: 异步调用 -type: docs -weight: 3 ---- - - - - - - -## 特性说明 -#### 背景 - -从 2.7.0 开始,Dubbo 的所有异步编程接口开始以 [CompletableFuture](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html) 为基础 - -基于 NIO 的非阻塞实现并行调用,客户端不需要启动多线程即可完成并行调用多个远程服务,相对多线程开销较小。 - -![/user-guide/images/future.jpg](/imgs/user/future.jpg) - - -## 使用场景 - -将用户请求内容发送到目标请求,当目标请求遇到高流量或需要长时间处理,异步调用功能将允许立即向用户返回响应,同时目标请求继续后台处理请求,当目标请求返回结果时,将内容显示给用户。 - -> 参考用例 -[https://github.com/apache/dubbo-samples/tree/master/dubbo-samples-async](https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-async) - -## 使用方式 -### 使用 CompletableFuture 签名的接口 - -需要服务提供者事先定义 CompletableFuture 签名的服务,接口定义指南如下: - -Provider端异步执行将阻塞的业务从Dubbo内部线程池切换到业务自定义线程,避免Dubbo线程池的过度占用,有助于避免不同服务间的互相影响。异步执行无异于节省资源或提升RPC响应性能,因为如果业务执行需要阻塞,则始终还是要有线程来负责执行。 - -> **Provider 端异步执行和 Consumer 端异步调用是相互独立的,任意正交组合两端配置** -> - Consumer同步 - Provider同步 -> - Consumer异步 - Provider同步 -> - Consumer同步 - Provider异步 -> - Consumer异步 - Provider异步 - -### 定义 CompletableFuture 签名的接口 - -服务接口定义 -```java -public interface AsyncService { - CompletableFuture sayHello(String name); -} -``` - -服务实现 -```java -public class AsyncServiceImpl implements AsyncService { - @Override - public CompletableFuture sayHello(String name) { - return CompletableFuture.supplyAsync(() -> { - System.out.println(name); - try { - Thread.sleep(5000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - return "async response from provider."; - }); - } -} -``` - -通过 `return CompletableFuture.supplyAsync() `,业务执行已从 Dubbo 线程切换到业务线程,避免了对 Dubbo 线程池的阻塞。 - -注意接口的返回类型是 `CompletableFuture`。 - -XML 引用服务 -```xml - -``` - -调用远程服务 -```java -// 调用直接返回CompletableFuture -CompletableFuture future = asyncService.sayHello("async call request"); -// 增加回调 -future.whenComplete((v, t) -> { - if (t != null) { - t.printStackTrace(); - } else { - System.out.println("Response: " + v); - } -}); -// 早于结果输出 -System.out.println("Executed before response return."); -``` - -### 使用 AsyncContext - -Dubbo 提供了一个类似 Servlet 3.0 的异步接口`AsyncContext`,在没有 CompletableFuture 签名接口的情况下,也可以实现 Provider 端的异步执行。 - -服务接口定义 -```java -public interface AsyncService { - String sayHello(String name); -} -``` - -服务暴露,和普通服务完全一致 -```xml - - -``` - -服务实现 -```java -public class AsyncServiceImpl implements AsyncService { - public String sayHello(String name) { - final AsyncContext asyncContext = RpcContext.startAsync(); - new Thread(() -> { - // 如果要使用上下文,则必须要放在第一句执行 - asyncContext.signalContextSwitch(); - try { - Thread.sleep(500); - } catch (InterruptedException e) { - e.printStackTrace(); - } - // 写回响应 - asyncContext.write("Hello " + name + ", response from provider."); - }).start(); - return null; - } -} -``` - -### 使用 RpcContext 实现消费端异步调用 -在 consumer.xml 中配置 -```xml - - - -``` - -调用代码 -```java -// 此调用会立即返回null -asyncService.sayHello("world"); -// 拿到调用的Future引用,当结果返回后,会被通知和设置到此Future -CompletableFuture helloFuture = RpcContext.getServiceContext().getCompletableFuture(); -// 为Future添加回调 -helloFuture.whenComplete((retValue, exception) -> { - if (exception == null) { - System.out.println(retValue); - } else { - exception.printStackTrace(); - } -}); -``` - -或者,也可以这样做异步调用 -```java -CompletableFuture future = RpcContext.getServiceContext().asyncCall( - () -> { - asyncService.sayHello("oneway call request1"); - } -); - -future.get(); -``` - - -**异步总是不等待返回**,你也可以设置是否等待消息发出 -- `sent="true"` 等待消息发出,消息发送失败将抛出异常。 -- `sent="false"` 不等待消息发出,将消息放入 IO 队列,即刻返回。 - -```xml - -``` - -如果你只是想异步,完全忽略返回值,可以配置 `return="false"`,以减少 Future 对象的创建和管理成本 -```xml - -``` \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/async-execute-on-provider.md b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/async-execute-on-provider.md deleted file mode 100644 index 528bc835dad8..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/async-execute-on-provider.md +++ /dev/null @@ -1,106 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/service/async-execute-on-provider/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/service/async-execute-on-provider/ -description: Dubbo 服务提供方的异步执行 -linkTitle: 异步执行 -title: 异步执行 -type: docs -weight: 21 ---- - - - - - - -{{% pageinfo %}} 此文档已经不再维护。您当前查看的是快照版本。如果想要查看最新版本的文档,请参阅[最新版本](/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/attachment/)。 -{{% /pageinfo %}} - - -Provider端异步执行将阻塞的业务从Dubbo内部线程池切换到业务自定义线程,避免Dubbo线程池的过度占用,有助于避免不同服务间的互相影响。异步执行无异于节省资源或提升RPC响应性能,因为如果业务执行需要阻塞,则始终还是要有线程来负责执行。 - -{{% alert title="注意" color="warning" %}} -Provider 端异步执行和 Consumer 端异步调用是相互独立的,你可以任意正交组合两端配置 -- Consumer同步 - Provider同步 -- Consumer异步 - Provider同步 -- Consumer同步 - Provider异步 -- Consumer异步 - Provider异步 -{{% /alert %}} - - -## 定义 CompletableFuture 签名的接口 - -服务接口定义: - -```java -public interface AsyncService { - CompletableFuture sayHello(String name); -} -``` - -服务实现: - -```java -public class AsyncServiceImpl implements AsyncService { - @Override - public CompletableFuture sayHello(String name) { - RpcContext savedContext = RpcContext.getContext(); - // 建议为supplyAsync提供自定义线程池,避免使用JDK公用线程池 - return CompletableFuture.supplyAsync(() -> { - System.out.println(savedContext.getAttachment("consumer-key1")); - try { - Thread.sleep(5000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - return "async response from provider."; - }); - } -} -``` - -通过 `return CompletableFuture.supplyAsync() `,业务执行已从 Dubbo 线程切换到业务线程,避免了对 Dubbo 线程池的阻塞。 - - - -## 使用AsyncContext - -Dubbo 提供了一个类似 Servlet 3.0 的异步接口`AsyncContext`,在没有 CompletableFuture 签名接口的情况下,也可以实现 Provider 端的异步执行。 - -服务接口定义: - -```java -public interface AsyncService { - String sayHello(String name); -} -``` - -服务暴露,和普通服务完全一致: - -```xml - - -``` - -服务实现: - -```java -public class AsyncServiceImpl implements AsyncService { - public String sayHello(String name) { - final AsyncContext asyncContext = RpcContext.startAsync(); - new Thread(() -> { - // 如果要使用上下文,则必须要放在第一句执行 - asyncContext.signalContextSwitch(); - try { - Thread.sleep(500); - } catch (InterruptedException e) { - e.printStackTrace(); - } - // 写回响应 - asyncContext.write("Hello " + name + ", response from provider."); - }).start(); - return null; - } -} -``` \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/attachment.md b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/attachment.md deleted file mode 100644 index 48be1851e0de..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/attachment.md +++ /dev/null @@ -1,146 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/service/attachment/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/service/attachment/ -description: 通过 Dubbo 中的 Attachment 在服务消费方和提供方之间隐式传递参数 -linkTitle: 调用链路传递隐式参数 -title: 调用链路传递隐式参数 -type: docs -weight: 5 ---- - - - - - - -## 特性说明 - -可以通过 `RpcContext` 上的 `setAttachment` 和 `getAttachment` 在服务消费方和提供方之间进行参数的隐式传递。 - -#### 背景 - -上下文信息是 RPC 框架很重要的一个功能,使用 RpcContext 可以为单次调用指定不同配置。如分布式链路追踪场景,其实现原理就是在全链路的上下文中维护一个 traceId,Consumer 和 Provider 通过传递 traceId 来连接一次RPC调用,分别上报日志后可以在追踪系统中串联并展示完整的调用流程。这样可以更方便地发现异常,定位问题。 -Dubbo 中的 RpcContext 是一个 ThreadLocal 的临时状态记录器,当接收到 RPC 请求,或发起 RPC 请求时,RpcContext 的状态都会变化。比如:**A 调 B,B 调 C,则 B 机器上,在 B 调 C 之前,RpcContext 记录的是 A 和 B 的信息,在 B 调 C 之后,RpcContext 记录的是 B 和 C 的信息。** - -在 Dubbo 3 中,RpcContext 被拆分为四大模块(ServerContext、ClientAttachment、ServerAttachment 和 ServiceContext)。 - -它们分别承担了不同的职责: -- ServiceContext:在 Dubbo 内部使用,用于传递调用链路上的参数信息,如 invoker 对象等 -- ClientAttachment:在 Client 端使用,往 ClientAttachment 中写入的参数将被传递到 Server 端 -- ServerAttachment:在 Server 端使用,从 ServerAttachment 中读取的参数是从 Client 中传递过来的 -- ServerContext:在 Client 端和 Server 端使用,用于从 Server 端回传 Client 端使用,Server 端写入到 ServerContext 的参数在调用结束后可以在 Client 端的 ServerContext 获取到 - -![/imgs/v3/concepts/rpccontext.png](/imgs/v3/concepts/rpccontext.png) - -如上图所示,消费端发起调用的时候可以直接通过 Method Invoke 向远程的服务发起调用,同时消费端往 RpcClientAttachment 写入的数据会连同 Invoke 的参数信息写入到 Invocation 中。 -消费端的 Invocation 经过序列化后通过网络传输发送给服务端,服务端解析 Invocation 生成 Method Invoke 的参数和 RpcServerAttachment,然后发起真实调用。 -在服务端处理结束之后,Method Response 结果会连同 RpcServiceContext 一起生成 Result 对象。 -服务端的 Result 结果对象经过序列化后通过网络传输发送回消费端,消费端解析 Result 生成 Method Response 结果和 RpcServiceContext,返回真实调用结果和上下文给消费端。 - -> path, group, version, dubbo, token, timeout 几个 key 是保留字段,请使用其它值。 - -## 使用场景 - -内部系统通过 Dubbo 调用时, traceId 如何透传到服务提供方。 - -## 使用方式 - -> `setAttachment` 设置的 KV 对,在完成下面一次远程调用会被清空,即多次远程调用要多次设置。 - -### 在服务消费方端设置隐式参数 - -```java -RpcContext.getClientAttachment().setAttachment("index", "1"); // 隐式传参,后面的远程调用都会隐式将这些参数发送到服务器端,类似cookie,用于框架集成,不建议常规业务使用 -xxxService.xxx(); // 远程调用 -// ... -``` - -### 在服务提供方端获取隐式参数 - -```java -public class XxxServiceImpl implements XxxService { - - public void xxx() { - // 获取客户端隐式传入的参数,用于框架集成,不建议常规业务使用 - String index = RpcContext.getServerAttachment().getAttachment("index"); - } -} -``` - -### 在服务提供方写入回传参数 - -```java -public class XxxServiceImpl implements XxxService { - - public void xxx() { - String index = xxx; - RpcContext.getServerContext().setAttachment("result", index); - } -} -``` - -### 在消费端获取回传参数 - -```java -xxxService.xxx(); // 远程调用 -String result = RpcContext.getServerContext().getAttachment("result"); -// ... -``` - -> 参数透传问题 - -在 Dubbo 2.7 中,在 A 端设置的参数,调用 B 以后,如果 B 继续调用了 C,原来在 A 中设置的参数也会被带到 C 端过去,造成参数污染的问题。 -Dubbo 3 对 RpcContext 进行了重构,支持可选参数透传,默认开启参数透传。 - -在 Dubbo 3 中提供了如下的 SPI,默认无实现,用户可以自行定义实现,`select` 的结果(可以从 RpcClientAttachment 获取当前所有参数)将作为需要透传的键值对传递到下一跳,如果返回 null 则表示不透传参数。 - -```java -@SPI -public interface PenetrateAttachmentSelector { - - /** - * Select some attachments to pass to next hop. - * These attachments can fetch from {@link RpcContext#getServerAttachment()} or user defined. - * - * @return attachment pass to next hop - */ - Map select(); - -} -``` - -# 历史遗留问题 - -在之前的版本中,你可能会见到这样的使用方式: -```java -@Activate(group = {CommonConstants.CONSUMER}) -public class DubboConsumerFilter implements Filter { - - @Override - public Result invoke(Invoker invoker, Invocation invocation) throws RpcException { - - RpcContext.getContext().setAttachment("demo","demo02"); - - - return invoker.invoke(invocation); - } -} -``` - -但是在新版本中我们的建议是 **在 Filter 里面的尽可能不要操作 RpcContext**,上面的使用方式会导致不生效。原因在于新版本中,我们在`ConsumerContextFilter`类中做了`ClientAttachment` -> `Invocation`属性的复制,该类是Dubbo内置Filter类,而内置Filter类先于用户定义Filter类执行,所以在自定义Filter类中这样使用不会生效。 -可以直接使用这种方式进行传递: - -```java -@Activate(group = {CommonConstants.CONSUMER}) -public class DubboConsumerFilter implements Filter { - - @Override - public Result invoke(Invoker invoker, Invocation invocation) throws RpcException { - - invocation.setAttachment("demo","demo02"); - - return invoker.invoke(invocation); - } -} -``` diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/consistent-hash.md b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/consistent-hash.md deleted file mode 100644 index fad39b8c90fb..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/consistent-hash.md +++ /dev/null @@ -1,56 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/service/consistent-hash/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/service/consistent-hash/ -description: 在负载均衡阶段基于一致性哈希进行选址 -linkTitle: 一致性哈希选址 -title: 一致性哈希选址 -type: docs -weight: 6 ---- - - - - - -## 特性说明 -在分布式系统中跨多个节点均匀分布请求的方法,使用哈希算法创建请求的哈希并根据哈希值确定哪个节点应该处理请求,算法确保每个节点处理的请求数量大致相等。如果一个节点发生故障,其他节点可以快速接管请求,保持系统高可用性,即使一个节点出现故障,系统的数据映射到系统中有限数量节点的哈希算法,在系统中添加或删除节点时,只需更改有限数量的映射,确保数据均匀分布在系统中的所有节点上提高系统的性能。 - -[Dubbo 一致性Hash负载均衡实现剖析](/zh-cn/blog/2019/05/01/dubbo-%E4%B8%80%E8%87%B4%E6%80%A7hash%E8%B4%9F%E8%BD%BD%E5%9D%87%E8%A1%A1%E5%AE%9E%E7%8E%B0%E5%89%96%E6%9E%90/) - -## 使用场景 - -在有多台服务端的时候根据请求参数的进行一致性哈希散列选择服务端。 - -## 使用方式 - -配置一致性哈希的方式有很多,最常见的是: - -### 注解配置 - -> @DubboReference(loadbalance = “consistenthash”) - -### API 配置 - -> referenceConfig.setLoadBalance("consistenthash"); - -### Properties 配置 - -> dubbo.reference.loadbalance=consistenthash - -### XML 配置 - -> - -默认采用第一个参数作为哈希 key,如果需要切换参数,可以指定 `hash.arguments` 属性 - -```java -ReferenceConfig referenceConfig = new ReferenceConfig(); -// ... init -Map parameters = new HashMap(); -parameters.put("hash.arguments", "1"); -parameters.put("sayHello.hash.arguments", "0,1"); -referenceConfig.setParameters(parameters); -referenceConfig.setLoadBalance("consistenthash"); -referenceConfig.get(); -``` \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/context.md b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/context.md deleted file mode 100644 index 28e61ce460c3..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/context.md +++ /dev/null @@ -1,57 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/service/context/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/service/context/ -description: 通过上下文存放当前调用过程中所需的环境信息 -linkTitle: RPC调用上下文 -title: RPC调用上下文 -type: docs -weight: 6 ---- - - - - - -## 特性说明 -上下文中存放的是当前调用过程中所需的环境信息。所有配置信息都将转换为 URL 的参数,参见 [schema 配置参考手册](../../../reference-manual/config/properties/) 中的**对应URL参数**一列。 - -RpcContext 是一个 ThreadLocal 的临时状态记录器,当接收到 RPC 请求,或发起 RPC 请求时,RpcContext 的状态都会变化。比如:A 调 B,B 再调 C,则 B 机器上,在 B 调 C 之前,RpcContext 记录的是 A 调 B 的信息,在 B 调 C 之后,RpcContext 记录的是 B 调 C 的信息。 - -## 使用场景 -全局链路追踪和隐藏参数。 - -## 使用方式 - -### 服务消费方 -```java -// 远程调用 -xxxService.xxx(); -// 本端是否为消费端,这里会返回true -boolean isConsumerSide = RpcContext.getServiceContext().isConsumerSide(); -// 获取最后一次调用的提供方IP地址 -String serverIP = RpcContext.getServiceContext().getRemoteHost(); -// 获取当前服务配置信息,所有配置信息都将转换为URL的参数 -String application = RpcContext.getServiceContext().getUrl().getParameter("application"); -// 注意:每发起RPC调用,上下文状态会变化 -yyyService.yyy(); -``` - -### 服务提供方 -```java -public class XxxServiceImpl implements XxxService { - - public void xxx() { - // 本端是否为提供端,这里会返回true - boolean isProviderSide = RpcContext.getServiceContext().isProviderSide(); - // 获取调用方IP地址 - String clientIP = RpcContext.getServiceContext().getRemoteHost(); - // 获取当前服务配置信息,所有配置信息都将转换为URL的参数 - String application = RpcContext.getServiceContext().getUrl().getParameter("application"); - // 注意:每发起RPC调用,上下文状态会变化 - yyyService.yyy(); - // 此时本端变成消费端,这里会返回false - boolean isProviderSide = RpcContext.getServiceContext().isProviderSide(); - } -} -``` \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/delay-publish.md b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/delay-publish.md deleted file mode 100644 index 230c32257095..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/delay-publish.md +++ /dev/null @@ -1,74 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/service/delay-publish/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/service/delay-publish/ -description: 延迟暴露 Dubbo 服务 -linkTitle: 延迟暴露 -title: 延迟暴露 -type: docs -weight: 27 ---- - - - - - - -## 特性说明 -如果你的服务需要预热时间,比如初始化缓存,等待相关资源就位等,可以使用 delay 进行延迟暴露。我们在 Dubbo 2.6.5 版本中对服务延迟暴露逻辑进行了细微的调整,将需要延迟暴露(delay > 0)服务的倒计时动作推迟到了 Spring 初始化完成后进行。你在使用 Dubbo 的过程中,并不会感知到此变化,因此请放心使用。 - -## 使用场景 -当服务完全配置并准备好向外界暴露时才会触发服务的暴露,保证服务在准备就绪时暴露,提高了服务系统可靠性。 - - -## 使用方式 - -### Dubbo 2.6.5 之前版本 - -延迟到 Spring 初始化完成后,再暴露服务[^1] - -```xml - -``` - -延迟 5 秒暴露服务 - -```xml - -``` - -### Dubbo 2.6.5 及以后版本 - -所有服务都将在 Spring 初始化完成后进行暴露,如果你不需要延迟暴露服务,无需配置 delay。 - -延迟 5 秒暴露服务 - -```xml - -``` - -### Spring 2.x 初始化死锁问题 - -### 触发条件 - -在 Spring 解析到 `` 时,就已经向外暴露了服务,而 Spring 还在接着初始化其它 Bean。如果这时有请求进来,并且服务的实现类里有调用 `applicationContext.getBean()` 的用法。 - -1. 请求线程的 applicationContext.getBean() 调用,先同步 singletonObjects 判断 Bean 是否存在,不存在就同步 beanDefinitionMap 进行初始化,并再次同步 singletonObjects 写入 Bean 实例缓存。 - - ![deadlock](/imgs/user/lock-get-bean.jpg) - -2. 而 Spring 初始化线程,因不需要判断 Bean 的存在,直接同步 beanDefinitionMap 进行初始化,并同步 singletonObjects 写入 Bean 实例缓存。 - - ![/user-guide/images/lock-init-context.jpg](/imgs/user/lock-init-context.jpg) - - 这样就导致 getBean 线程,先锁 singletonObjects,再锁 beanDefinitionMap,再次锁 singletonObjects。 -而 Spring 初始化线程,先锁 beanDefinitionMap,再锁 singletonObjects。反向锁导致线程死锁,不能提供服务,启动不了。 - -### 规避办法 - -1. 强烈建议不要在服务的实现类中有 applicationContext.getBean() 的调用,全部采用 IoC 注入的方式使用 Spring的Bean。 -2. 如果实在要调 getBean(),可以将 Dubbo 的配置放在 Spring 的最后加载。 -3. 如果不想依赖配置顺序,可以使用 ``,使 Dubbo 在 Spring 容器初始化完后,再暴露服务。 -4. 如果大量使用 getBean(),相当于已经把 Spring 退化为工厂模式在用,可以将 Dubbo 的服务隔离单独的 Spring 容器。 - -[^1]: 基于 Spring 的 ContextRefreshedEvent 事件触发暴露 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/distributed-transaction.md b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/distributed-transaction.md deleted file mode 100644 index a0413a84c802..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/distributed-transaction.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/service/distributed-transaction/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/service/distributed-transaction/ -description: Dubbo 中分布式事务的支持 -linkTitle: 分布式事务支持 -title: 分布式事务支持 -type: docs -weight: 42 ---- - - - - - -## 特性说明 -分布式事务基于 JTA/XA 规范实现。 - -## 使用场景 -支付交易:支付交易中的分布式交易支持,如在线支付、银行转账等,确保在完成多个服务调用后支付成功。 - -库存管理:支持库存管理中的分布式事务场景,确保用户购买产品时,库存得到相应更新成功和交易成功。 - -订单处理:支持订单处理中的分布式事务场景,确保当用户下订单时,在完成多个服务调用后成功下订单。 - -数据同步:支持数据同步中的分布式事务场景,确保在完成多个服务调用后,不同服务之间的数据同步成功。 - -## 实现方式 -**两阶段提交** - -![/user-guide/images/jta-xa.jpg](/imgs/user/jta-xa.jpg) - -> 在 Dubbo 中,可以采用 [seata](/zh-cn/blog/2019/01/17/如何使用seata保证dubbo微服务间的一致性/) 来完成对分布式事务的支持。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/echo-service.md b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/echo-service.md deleted file mode 100644 index 9761f7c96ca0..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/echo-service.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/service/echo-service/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/service/echo-service/ -description: 通过回声测试检测 Dubbo 服务是否可用 -linkTitle: 回声测试 -title: 回声测试 -type: docs -weight: 12 ---- - - - - - - -## 特性说明 -回声测试用于检测服务是否可用,回声测试按照正常请求流程执行,能够测试整个调用是否通畅,可用于监控。执行回声测试,客户端发送一个包含特定值(如字符串)的请求。服务器应使用相同的值进行响应,从而验证请求是否已成功接收和处理。如果响应与请求不匹配,则表示服务运行不正常,应进一步调查。要求 Dubbo 服务器正在运行,并且服务器和客户端之间具有网络连接。在客户端,必须配置 Dubbo 客户端以连接到服务器,客户端将向服务器发送请求,然后服务器应返回与请求相同的响应。 - - -## 使用场景 -测试验证是否可以调用服务以及响应是否正确,对于在尝试在生产环境中使用服务之前验证服务特别有用。 -echo 测试是验证 Dubbo 服务基本功能的一种简单有效的方法,在将服务部署到生产环境之前执行此测试非常重要,以确保服务按预期工作。 - -> 参考用例 -[https://github.com/apache/dubbo-samples/tree/master/dubbo-samples-echo](https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-echo) - -## 使用方式 -所有服务自动实现 `EchoService` 接口,只需将任意服务引用强制转型为 `EchoService`,即可使用。 - -### Spring 配置 -```xml - -``` - -### 代码示例 -```java -// 远程服务引用 -MemberService memberService = ctx.getBean("memberService"); - -EchoService echoService = (EchoService) memberService; // 强制转型为EchoService - -// 回声测试可用性 -String status = echoService.$echo("OK"); - -assert(status.equals("OK")); -``` \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/explicit-target.md b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/explicit-target.md deleted file mode 100644 index 4f9b8cf7e017..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/explicit-target.md +++ /dev/null @@ -1,68 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/service/explicit-target/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/service/explicit-target/ -description: Dubbo 中点对点的直连方式 -linkTitle: 直连提供者 -title: 直连提供者 -type: docs -weight: 5 ---- - - - - - - -{{% pageinfo %}} 此文档已经不再维护。您当前查看的是快照版本。如果想要查看最新版本的文档,请参阅[最新版本](/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/specify-ip/)。 -{{% /pageinfo %}} - -在开发及测试环境下,经常需要绕过注册中心,只测试指定服务提供者,这时候可能需要点对点直连,点对点直连方式,将以服务接口为单位,忽略注册中心的提供者列表,A 接口配置点对点,不影响 B 接口从注册中心获取列表。 - -![/user-guide/images/dubbo-directly.jpg](/imgs/user/dubbo-directly.jpg) - -## 通过 XML 配置 - -如果是线上需求需要点对点,可在 `` 中配置 url 指向提供者,将绕过注册中心,多个地址用分号隔开,配置如下: - -```xml - -``` - -{{% alert title="提示" color="primary" %}} -`1.0.6` 及以上版本支持 -{{% /alert %}} - -## 通过 -D 参数指定 - -在 JVM 启动参数中加入-D参数映射服务地址,如: - -```sh -java -Dcom.alibaba.xxx.XxxService=dubbo://localhost:20890 -``` - -{{% alert title="提示" color="primary" %}} -key 为服务名,value 为服务提供者 url,此配置优先级最高,`1.0.15` 及以上版本支持 -{{% /alert %}} - -## 通过文件映射 - -如果服务比较多,也可以用文件映射,用 `-Ddubbo.resolve.file` 指定映射文件路径,此配置优先级高于 `` 中的配置 [^3],如: - -```sh -java -Ddubbo.resolve.file=xxx.properties -``` - -然后在映射文件 `xxx.properties` 中加入配置,其中 key 为服务名,value 为服务提供者 URL: - -```properties -com.alibaba.xxx.XxxService=dubbo://localhost:20890 -``` - -{{% alert title="提示" color="primary" %}} -`1.0.15` 及以上版本支持,`2.0` 以上版本自动加载 ${user.home}/dubbo-resolve.properties文件,不需要配置 -{{% /alert %}} - -{{% alert title="注意" color="warning" %}} -为了避免复杂化线上环境,不要在线上使用这个功能,只应在测试阶段使用。 -{{% /alert %}} \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/fault-tolerent-strategy.md b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/fault-tolerent-strategy.md deleted file mode 100644 index e4535ac3228c..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/fault-tolerent-strategy.md +++ /dev/null @@ -1,152 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/service/fault-tolerent-strategy/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/service/fault-tolerent-strategy/ -description: 集群调用失败时,Dubbo 提供的容错方案 -linkTitle: 集群容错 -title: 集群容错 -type: docs -weight: 2 ---- - - - - - -## 特性说明 -在集群调用失败时,Dubbo 提供了多种容错方案,缺省为 failover 重试。 - -![cluster](/imgs/user/cluster.jpg) - -各节点关系: - -* 这里的 `Invoker` 是 `Provider` 的一个可调用 `Service` 的抽象,`Invoker` 封装了 `Provider` 地址及 `Service` 接口信息 -* `Directory` 代表多个 `Invoker`,可以把它看成 `List` ,但与 `List` 不同的是,它的值可能是动态变化的,比如注册中心推送变更 -* `Cluster` 将 `Directory` 中的多个 `Invoker` 伪装成一个 `Invoker`,对上层透明,伪装过程包含了容错逻辑,调用失败后,重试另一个 -* `Router` 负责从多个 `Invoker` 中按路由规则选出子集,比如读写分离,应用隔离等 -* `LoadBalance` 负责从多个 `Invoker` 中选出具体的一个用于本次调用,选的过程包含了负载均衡算法,调用失败后,需要重选 - -通过使用服务注册表和负载平衡,可以提高集群提供的容错能力,服务注册表用于存储有关可用服务及其位置的信息,负载平衡用于确保请求均匀分布在集群中的所有服务器上,如果一台服务器发生故障,负载将转移到其他可用服务器。 - -配置监视集群中服务器运行状况的运行状况检查,如果服务器未通过运行状况检查,则可以将其从集群中删除,并将负载转移到其余服务器,确保集群正常运行,并且用户可以使用应用程序。 - -## 使用场景 -多个服务器部署同一集群中,运行同一应用程序,如果一台服务器出现故障,其他服务器将接管负载,确保应用程序对用户仍然可用。 - -> 可以自行扩展集群容错策略 [集群扩展](../../../reference-manual/spi/description/cluster/) - -## 使用方式 - -### Failover Cluster - -失败自动切换,当出现失败,重试其它服务器。通常用于读操作,但重试会带来更长延迟。可通过 `retries="2"` 来设置重试次数(不含第一次)。 - -重试次数配置如下: - -```xml - -``` - -或 - -```xml - -``` - -或 - -```xml - - - -``` - -{{% alert title="提示" color="primary" %}} -该配置为缺省配置 -{{% /alert %}} - -### Failfast Cluster - -快速失败,只发起一次调用,失败立即报错。通常用于非幂等性的写操作,比如新增记录。 - -### Failsafe Cluster - -失败安全,出现异常时,直接忽略。通常用于写入审计日志等操作。 - -### Failback Cluster - -失败自动恢复,后台记录失败请求,定时重发。通常用于消息通知操作。 - -### Forking Cluster - -并行调用多个服务器,只要一个成功即返回。通常用于实时性要求较高的读操作,但需要浪费更多服务资源。可通过 `forks="2"` 来设置最大并行数。 - -### Broadcast Cluster - -广播调用所有提供者,逐个调用,任意一台报错则报错。通常用于通知所有提供者更新缓存或日志等本地资源信息。 - -现在广播调用中,可以通过 broadcast.fail.percent 配置节点调用失败的比例,当达到这个比例后,BroadcastClusterInvoker -将不再调用其他节点,直接抛出异常。 broadcast.fail.percent 取值在 0~100 范围内。默认情况下当全部调用失败后,才会抛出异常。 -broadcast.fail.percent 只是控制的当失败后是否继续调用其他节点,并不改变结果(任意一台报错则报错)。broadcast.fail.percent 参数 -在 dubbo2.7.10 及以上版本生效。 - -Broadcast Cluster 配置 broadcast.fail.percent。 - -broadcast.fail.percent=20 代表了当 20% 的节点调用失败就抛出异常,不再调用其他节点。 - -```text -@reference(cluster = "broadcast", parameters = {"broadcast.fail.percent", "20"}) -``` - - -{{% alert title="提示" color="primary" %}} -`2.1.0` 开始支持 -{{% /alert %}} - -### Available Cluster - -调用目前可用的实例(只调用一个),如果当前没有可用的实例,则抛出异常。通常用于不需要负载均衡的场景。 - -### Mergeable Cluster - -将集群中的调用结果聚合起来返回结果,通常和group一起配合使用。通过分组对结果进行聚合并返回聚合后的结果,比如菜单服务,用group区分同一接口的多种实现,现在消费方需从每种group中调用一次并返回结果,对结果进行合并之后返回,这样就可以实现聚合菜单项。 - -### ZoneAware Cluster - -多注册中心订阅的场景,注册中心集群间的负载均衡。对于多注册中心间的选址策略有如下四种 - -1. 指定优先级:`preferred="true"`注册中心的地址将被优先选择 - -```xml - -``` - -2. 同中心优先:检查当前请求所属的区域,优先选择具有相同区域的注册中心 - -```xml - -``` - -3. 权重轮询:根据每个注册中心的权重分配流量 - -```xml - - - -``` - -4. 缺省值:选择一个可用的注册中心 - -### 集群模式示例 - -按照以下示例在服务提供方和消费方配置集群模式 - -```xml - -``` - -或 - -```xml - -``` \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/generic-reference.md b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/generic-reference.md deleted file mode 100644 index 1202ae9de6aa..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/generic-reference.md +++ /dev/null @@ -1,385 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/service/generic-reference/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/service/generic-reference/ -description: 不需要服务端 API 的 RPC 调用 -linkTitle: 泛化调用 -title: 泛化调用(客户端泛化) -type: docs -weight: 4 ---- - - - - - - -## 特性说明 - -泛化调用是指在调用方没有服务方提供的 API(SDK)的情况下,对服务方进行调用,并且可以正常拿到调用结果。 - -## 使用场景 - -泛化调用主要用于实现一个通用的远程服务 Mock 框架,可通过实现 GenericService 接口处理所有服务请求。比如如下场景: - -1. 网关服务:如果要搭建一个网关服务,那么服务网关要作为所有 RPC 服务的调用端。但是网关本身不应该依赖于服务提供方的接口 API(这样会导致每有一个新的服务发布,就需要修改网关的代码以及重新部署),所以需要泛化调用的支持。 - -2. 测试平台:如果要搭建一个可以测试 RPC 调用的平台,用户输入分组名、接口、方法名等信息,就可以测试对应的 RPC 服务。那么由于同样的原因(即会导致每有一个新的服务发布,就需要修改网关的代码以及重新部署),所以平台本身不应该依赖于服务提供方的接口 API。所以需要泛化调用的支持。 - -## 使用方式 - -demo 可见 [dubbo 项目中的示例代码](https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-generic) - -API 部分以此 demo 为例讲解使用方式。 - -### 服务定义 - -#### 服务接口 - -``` java -public interface HelloService { - - String sayHello(String name); - - CompletableFuture sayHelloAsync(String name); - - CompletableFuture sayHelloAsyncComplex(String name); - - CompletableFuture> sayHelloAsyncGenericComplex(String name); -} - -``` - -#### 服务实现类 - -``` java -public class HelloServiceImpl implements HelloService { - - @Override - public String sayHello(String name) { - return "sayHello: " + name; - } - - @Override - public CompletableFuture sayHelloAsync(String name) { - CompletableFuture future = new CompletableFuture<>(); - new Thread(() -> { - try { - Thread.sleep(5000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - future.complete("sayHelloAsync: " + name); - }).start(); - - return future; - } - - @Override - public CompletableFuture sayHelloAsyncComplex(String name) { - Person person = new Person(1, "sayHelloAsyncComplex: " + name); - CompletableFuture future = new CompletableFuture<>(); - new Thread(() -> { - try { - Thread.sleep(5000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - future.complete(person); - }).start(); - - return future; - } - - @Override - public CompletableFuture> sayHelloAsyncGenericComplex(String name) { - Person person = new Person(1, "sayHelloAsyncGenericComplex: " + name); - GenericType genericType = new GenericType<>(person); - CompletableFuture> future = new CompletableFuture<>(); - new Thread(() -> { - try { - Thread.sleep(5000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - future.complete(genericType); - }).start(); - - return future; - } -} - -``` - -### 通过API使用泛化调用 - -#### 服务启动方 - -1. 在设置 `ServiceConfig` 时,使用`setGeneric("true")`来开启泛化调用 - -2. 在设置 `ServiceConfig` 时,使用 setRef 指定实现类时,要设置一个 `GenericService` 的对象。而不是真正的服务实现类对象 - -3. 其他设置与正常 Api 服务启动一致即可 - -``` java -private static String zookeeperAddress = "zookeeper://" + System.getProperty("zookeeper.address", "127.0.0.1") + ":2181"; - - public static void main(String[] args) throws Exception { - new EmbeddedZooKeeper(2181, false).start(); - - //创建ApplicationConfig - ApplicationConfig applicationConfig = new ApplicationConfig(); - applicationConfig.setName("generic-impl-provider"); - //创建注册中心配置 - RegistryConfig registryConfig = new RegistryConfig(); - registryConfig.setAddress(zookeeperAddress); - - //新建服务实现类,注意要使用GenericService接收 - GenericService helloService = new GenericImplOfHelloService(); - - //创建服务相关配置 - ServiceConfig service = new ServiceConfig<>(); - service.setApplication(applicationConfig); - service.setRegistry(registryConfig); - service.setInterface("org.apache.dubbo.samples.generic.call.api.HelloService"); - service.setRef(helloService); - //重点:设置为泛化调用 - //注:不再推荐使用参数为布尔值的setGeneric函数 - //应该使用referenceConfig.setGeneric("true")代替 - service.setGeneric("true"); - service.export(); - - System.out.println("dubbo service started"); - - new CountDownLatch(1).await(); - } -} -``` - -#### 泛化调用方 -步骤: - -1. 在设置 `ReferenceConfig` 时,使用 `setGeneric("true")` 来开启泛化调用 - -2. 配置完 `ReferenceConfig` 后,使用 `referenceConfig.get()` 获取到 `GenericService` 类的实例 - -3. 使用其 `$invoke` 方法获取结果 - -4. 其他设置与正常 Api 服务启动一致即可 - -``` java - //定义泛化调用服务类 - private static GenericService genericService; - public static void main(String[] args) throws Exception { - //创建ApplicationConfig - ApplicationConfig applicationConfig = new ApplicationConfig(); - applicationConfig.setName("generic-call-consumer"); - //创建注册中心配置 - RegistryConfig registryConfig = new RegistryConfig(); - registryConfig.setAddress("zookeeper://127.0.0.1:2181"); - //创建服务引用配置 - ReferenceConfig referenceConfig = new ReferenceConfig<>(); - //设置接口 - referenceConfig.setInterface("org.apache.dubbo.samples.generic.call.api.HelloService"); - applicationConfig.setRegistry(registryConfig); - referenceConfig.setApplication(applicationConfig); - //重点:设置为泛化调用 - //注:不再推荐使用参数为布尔值的setGeneric函数 - //应该使用referenceConfig.setGeneric("true")代替 - referenceConfig.setGeneric(true); - //设置异步,不必须,根据业务而定。 - referenceConfig.setAsync(true); - //设置超时时间 - referenceConfig.setTimeout(7000); - - //获取服务,由于是泛化调用,所以获取的一定是GenericService类型 - genericService = referenceConfig.get(); - - //使用GenericService类对象的$invoke方法可以代替原方法使用 - //第一个参数是需要调用的方法名 - //第二个参数是需要调用的方法的参数类型数组,为String数组,里面存入参数的全类名。 - //第三个参数是需要调用的方法的参数数组,为Object数组,里面存入需要的参数。 - Object result = genericService.$invoke("sayHello", new String[]{"java.lang.String"}, new Object[]{"world"}); - //使用CountDownLatch,如果使用同步调用则不需要这么做。 - CountDownLatch latch = new CountDownLatch(1); - //获取结果 - CompletableFuture future = RpcContext.getContext().getCompletableFuture(); - future.whenComplete((value, t) -> { - System.err.println("invokeSayHello(whenComplete): " + value); - latch.countDown(); - }); - //打印结果 - System.err.println("invokeSayHello(return): " + result); - latch.await(); - } -``` - -### 通过 Spring 使用泛化调用 -Spring 中服务暴露与服务发现有多种使用方式,如 xml,注解。这里以 xml 为例。 -步骤: - -1. 生产者端无需改动 - -2. 消费者端原有的 `dubbo:reference` 标签加上 `generic=true` 的属性。 - -``` xml - -``` - -3. 获取到 Bean 容器,通过 Bean 容器拿到 `GenericService` 实例。 - -4. 调用 `$invoke` 方法获取结果 - -``` java - - private static GenericService genericService; - - public static void main(String[] args) throws Exception { - ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring/generic-impl-consumer.xml"); - context.start(); - //服务对应bean的名字由xml标签的id决定 - genericService = context.getBean("helloService"); - //获得结果 - Object result = genericService.$invoke("sayHello", new String[]{"java.lang.String"}, new Object[]{"world"}); - } -``` - - -### Protobuf 对象泛化调用 - -一般泛化调用只能用于生成的服务参数为 POJO 的情况,而 GoogleProtobuf 的对象是基于 Builder 生成的非正常 POJO,可以通过 protobuf-json 泛化调用。 - -GoogleProtobuf 序列化相关的 Demo 可以参考 [protobuf-demo](https://github.com/apache/dubbo-samples/tree/master/3-extensions/serialization/dubbo-samples-protobuf) - -#### 通过 Spring 对 Google Protobuf 对象泛化调用 - -在 Spring 中配置声明 generic = "protobuf-json" - -```xml - -``` - -在 Java 代码获取 barService 并开始泛化调用: - -```java -GenericService barService = (GenericService) applicationContext.getBean("barService"); -Object result = barService.$invoke("sayHello",new String[]{"org.apache.dubbo.protobuf.GooglePbBasic$CDubboGooglePBRequestType"}, new Object[]{"{\"double\":0.0,\"float\":0.0,\"bytesType\":\"Base64String\",\"int32\":0}"}); -``` - -#### 通过 API 方式对 Google Protobuf 对象泛化调用 - -```java -ReferenceConfig reference = new ReferenceConfig(); -// 弱类型接口名 -reference.setInterface(GenericService.class.getName()); -reference.setInterface("com.xxx.XxxService"); -// 声明为Protobuf-json -reference.setGeneric(Constants.GENERIC_SERIALIZATION_PROTOBUF); - -GenericService genericService = reference.get(); -Map person = new HashMap(); -person.put("fixed64", "0"); -person.put("int64", "0"); -// 参考google官方的protobuf 3 的语法,服务的每个方法中只传输一个POJO对象 -// protobuf的泛化调用只允许传递一个类型为String的json对象来代表请求参数 -String requestString = new Gson().toJson(person); -// 返回对象是GoolgeProtobuf响应对象的json字符串。 -Object result = genericService.$invoke("sayHello", new String[] { - "com.xxx.XxxService.GooglePbBasic$CDubboGooglePBRequestType"}, - new Object[] {requestString}); -``` - -#### GoogleProtobuf 对象的处理 - -GoogleProtobuf 对象是由 Protocol 契约生成,相关知识请参考 [ProtocolBuffers 文档](https://developers.google.com/protocol-buffers/?hl=zh-CN)。假如有如下 Protobuf 契约 - -```proto -syntax = "proto3"; -package com.xxx.XxxService.GooglePbBasic.basic; -message CDubboGooglePBRequestType { - double double = 1; - float float = 2; - int32 int32 = 3; - bool bool = 13; - string string = 14; - bytes bytesType = 15; -} - -message CDubboGooglePBResponseType { - string msg = 1; -} - -service CDubboGooglePBService { - rpc sayHello (CDubboGooglePBRequestType) returns (CDubboGooglePBResponseType); -} -``` - -则对应请求按照如下方法构造 - -```java -Map person = new HashMap<>(); -person.put("double", "1.000"); -person.put("float", "1.00"); -person.put("int32","1" ); -person.put("bool","false" ); -//String 的对象需要经过base64编码 -person.put("string","someBaseString"); -person.put("bytesType","150"); -``` - -#### GoogleProtobuf 服务元数据解析 - -Google Protobuf 对象缺少标准的 JSON 格式,生成的服务元数据信息存在错误。请添加如下依赖元数据解析的依赖。 - -```xml - - org.apache.dubbo - dubbo-metadata-definition-protobuf - ${dubbo.version} - -``` - -从服务元数据中也可以比较容易构建泛化调用对象。 - - -{{% alert title="注意事项" color="primary" %}} - -1. 如果参数为基本类型或者 Date,List,Map 等,则不需要转换,直接调用。 - -2. 如果参数为其他 POJO,则使用 Map 代替。 -{{% /alert %}} - -如: -``` java -public class Student { - String name; - int age; - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public int getAge() { - return age; - } - - public void setAge(int age) { - this.age = age; - } -} - -``` - -在调用时应该转换为: - -``` java -Map student = new HashMap(); -student.put("name", "xxx"); -student.put("age", "xxx"); -``` - -3. 对于其他序列化格式,需要特殊配置 diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/generic-service.md b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/generic-service.md deleted file mode 100644 index 711841a38c7b..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/generic-service.md +++ /dev/null @@ -1,70 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/service/generic-service/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/service/generic-service/ -description: 实现一个通用的远程服务 Mock 框架,可通过实现 GenericService 接口处理所有服务请求 -linkTitle: 泛化调用 -title: 实现泛化实现(服务端泛化) -type: docs -weight: 17 ---- - - - - - -## 特性说明 -泛接口实现方式主要用于服务器端没有 API 接口及模型类元的情况,参数及返回值中的所有 POJO 均用 Map 表示,通常用于框架集成,比如:实现一个通用的远程服务 Mock 框架,可通过实现 GenericService 接口处理所有服务请求。 - -## 使用场景 -注册服务: 服务提供者在服务注册表中注册服务,例如 Zookeeper,服务注册表存储有关服务的信息,例如其接口、实现类和地址。 - -部署服务: 服务提供商将服务部署在服务器并使其对消费者可用。 - -调用服务: 使用者使用服务注册表生成的代理调用服务,代理将请求转发给服务提供商,服务提供商执行服务并将响应发送回消费者。 - -监视服务:提供者和使用者可以使用 Dubbo 框架监视服务,允许他们查看服务的执行情况,并在必要时进行调整。 - - -## 使用方式 -在 Java 代码中实现 `GenericService` 接口 - -```java -package com.foo; -public class MyGenericService implements GenericService { - - public Object $invoke(String methodName, String[] parameterTypes, Object[] args) throws GenericException { - if ("sayHello".equals(methodName)) { - return "Welcome " + args[0]; - } - } -} -``` - -### 通过 Spring 暴露泛化实现 - -在 Spring 配置申明服务的实现 - -```xml - - -``` - -### 通过 API 方式暴露泛化实现 - -```java -... -// 用org.apache.dubbo.rpc.service.GenericService可以替代所有接口实现 -GenericService xxxService = new XxxGenericService(); - -// 该实例很重量,里面封装了所有与注册中心及服务提供方连接,请缓存 -ServiceConfig service = new ServiceConfig(); -// 弱类型接口名 -service.setInterface("com.xxx.XxxService"); -service.setVersion("1.0.0"); -// 指向一个通用服务实现 -service.setRef(xxxService); - -// 暴露及注册服务 -service.export(); -``` \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/group-merger.md b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/group-merger.md deleted file mode 100644 index a4f2bddc7723..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/group-merger.md +++ /dev/null @@ -1,78 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/service/group-merger/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/service/group-merger/ -description: 通过分组对结果进行聚合并返回聚合后的结果 -linkTitle: 分组聚合 -title: 分组聚合 -type: docs -weight: 1 ---- - - - - - - -## 特性说明 -通过分组对结果进行聚合并返回聚合后的结果,比如菜单服务,用 group 区分同一接口的多种实现,现在消费方需从每种 group 中调用一次并返回结果,对结果进行合并之后返回,这样就可以实现聚合菜单项。 - -相关代码可以参考 [dubbo 项目中的示例](https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-merge) - -## 使用场景 - -将多个服务提供者分组作为一个提供者进行访问。应用程序能够像访问一个服务一样访问多个服务,并允许更有效地使用资源。 - -## 使用方式 - -### 搜索所有分组 - -```xml - -``` - -### 合并指定分组 - -```xml - -``` -### 指定方法合并 - -指定方法合并结果,其它未指定的方法,将只调用一个 Group - -```xml - - - -``` -### 某个方法不合并 - -某个方法不合并结果,其它都合并结果 - -```xml - - - -``` -### 指定合并策略 - -指定合并策略,缺省根据返回值类型自动匹配,如果同一类型有两个合并器时,需指定合并器的名称 [合并结果扩展](../../../reference-manual/spi/description/merger) - -```xml - - - -``` -### 指定合并方法 - -指定合并方法,将调用返回结果的指定方法进行合并,合并方法的参数类型必须是返回结果类型本身 - -```xml - - - -``` - -{{% alert title="提示" color="primary" %}} -`2.1.0` 开始支持 -{{% /alert %}} diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/isolation-executor.md b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/isolation-executor.md deleted file mode 100644 index 95691105c658..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/isolation-executor.md +++ /dev/null @@ -1,240 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/service/isolation-executor/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/service/isolation-executor/ -description: 提供一种新的线程池管理方式,用于隔离服务之间的线程池 -linkTitle: 线程池隔离 -title: 线程池隔离 -type: docs -weight: 4 ---- - - - - - - -## 特性说明 -一种新的线程池管理方式,使得提供者应用内各个服务的线程池隔离开来,互相独立,某个服务的线程池资源耗尽不会影响其他正常服务。支持线程池可配置化,由用户手动指定。 - -## 使用场景 -使用线程池隔离来确保 Dubbo 用于调用远程方法的线程与微服务用于执行其任务的线程是分开的。可以通过防止线程阻塞或相互竞争来帮助提高系统的性能和稳定性。 - - -## 使用方式 - -目前可以以 API、XML、Annotation 的方式进行配置 - -**配置参数** -- `ApplicationConfig` 新增 `String executor-management-mode` 参数,配置值为 `default` 和 `isolation` ,默认为 `isolation`。 - - `executor-management-mode = default` 使用原有 **以协议端口为粒度、服务间共享** 的线程池管理方式 - - `executor-management-mode = isolation` 使用新增的 **以服务三元组为粒度、服务间隔离** 的线程池管理方式 -- `ServiceConfig` 新增 `Executor executor` 参数,**用以服务间隔离的线程池**,可以由用户配置化、提供自己想要的线程池,若没有指定,则会根据协议配置(`ProtocolConfig`)信息构建默认的线程池用以服务隔离。 - -> `ServiceConfig` 新增 `Executor executor` 配置参数只有指定`executor-management-mode = isolation` 才生效。 -### API -```java - public void test() { - // provider app - DubboBootstrap providerBootstrap = DubboBootstrap.newInstance(); - - ServiceConfig serviceConfig1 = new ServiceConfig(); - serviceConfig1.setInterface(DemoService.class); - serviceConfig1.setRef(new DemoServiceImpl()); - serviceConfig1.setVersion(version1); - // set executor1 for serviceConfig1, max threads is 10 - NamedThreadFactory threadFactory1 = new NamedThreadFactory("DemoService-executor"); - ExecutorService executor1 = Executors.newFixedThreadPool(10, threadFactory1); - serviceConfig1.setExecutor(executor1); - - ServiceConfig serviceConfig2 = new ServiceConfig(); - serviceConfig2.setInterface(HelloService.class); - serviceConfig2.setRef(new HelloServiceImpl()); - serviceConfig2.setVersion(version2); - // set executor2 for serviceConfig2, max threads is 100 - NamedThreadFactory threadFactory2 = new NamedThreadFactory("HelloService-executor"); - ExecutorService executor2 = Executors.newFixedThreadPool(100, threadFactory2); - serviceConfig2.setExecutor(executor2); - - ServiceConfig serviceConfig3 = new ServiceConfig(); - serviceConfig3.setInterface(HelloService.class); - serviceConfig3.setRef(new HelloServiceImpl()); - serviceConfig3.setVersion(version3); - // Because executor is not set for serviceConfig3, the default executor of serviceConfig3 is built using - // the threadpool parameter of the protocolConfig ( FixedThreadpool , max threads is 200) - serviceConfig3.setExecutor(null); - - // It takes effect only if [executor-management-mode=isolation] is configured - ApplicationConfig applicationConfig = new ApplicationConfig("provider-app"); - applicationConfig.setExecutorManagementMode("isolation"); - - providerBootstrap - .application(applicationConfig) - .registry(registryConfig) - // export with tri and dubbo protocol - .protocol(new ProtocolConfig("tri", 20001)) - .protocol(new ProtocolConfig("dubbo", 20002)) - .service(serviceConfig1) - .service(serviceConfig2) - .service(serviceConfig3); - - providerBootstrap.start(); - } -``` - -### XML -```xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -``` -### Annotation -```java -@Configuration -@EnableDubbo(scanBasePackages = "org.apache.dubbo.config.spring.isolation.spring.annotation.provider") -public class ProviderConfiguration { - @Bean - public RegistryConfig registryConfig() { - RegistryConfig registryConfig = new RegistryConfig(); - registryConfig.setAddress("zookeeper://127.0.0.1:2181"); - return registryConfig; - } - - // NOTE: we need config executor-management-mode="isolation" - @Bean - public ApplicationConfig applicationConfig() { - ApplicationConfig applicationConfig = new ApplicationConfig("provider-app"); - - applicationConfig.setExecutorManagementMode("isolation"); - return applicationConfig; - } - - // expose services with dubbo protocol - @Bean - public ProtocolConfig dubbo() { - ProtocolConfig protocolConfig = new ProtocolConfig("dubbo"); - return protocolConfig; - } - - // expose services with tri protocol - @Bean - public ProtocolConfig tri() { - ProtocolConfig protocolConfig = new ProtocolConfig("tri"); - return protocolConfig; - } - - // customized thread pool - @Bean("executor-demo-service") - public Executor demoServiceExecutor() { - return new DemoServiceExecutor(); - } - - // customized thread pool - @Bean("executor-hello-service") - public Executor helloServiceExecutor() { - return new HelloServiceExecutor(); - } -} -``` -```java -// customized thread pool -public class DemoServiceExecutor extends ThreadPoolExecutor { - public DemoServiceExecutor() { - super(10, 10, 60, TimeUnit.SECONDS, new LinkedBlockingDeque<>(), - new NamedThreadFactory("DemoServiceExecutor")); - } -} -``` - -```java -// customized thread pool -public class HelloServiceExecutor extends ThreadPoolExecutor { - public HelloServiceExecutor() { - super(100, 100, 60, TimeUnit.SECONDS, new LinkedBlockingDeque<>(), - new NamedThreadFactory("HelloServiceExecutor")); - } -} -``` -```java -// "executor-hello-service" is beanName -@DubboService(executor = "executor-demo-service", version = "1.0.0", group = "Group1") -public class DemoServiceImplV1 implements DemoService { - - @Override - public String sayName(String name) { - return "server name"; - } - - @Override - public Box getBox() { - return null; - } -} - -``` - -```java -// not set executor for this service, the default executor built using threadpool parameter of the protocolConfig -@DubboService(version = "3.0.0", group = "Group3") -public class HelloServiceImplV2 implements HelloService { - private static final Logger logger = LoggerFactory.getLogger(HelloServiceImplV2.class); - - @Override - public String sayHello(String name) { - return "server hello"; - } -} - -``` - -```java -@DubboService(executor = "executor-hello-service", version = "2.0.0", group = "Group2") -public class HelloServiceImplV3 implements HelloService { - private static final Logger logger = LoggerFactory.getLogger(HelloServiceImplV3.class); - - @Override - public String sayHello(String name) { - return "server hello"; - } -} -``` diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/json-compatibility-check.md b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/json-compatibility-check.md deleted file mode 100644 index 40a075263898..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/json-compatibility-check.md +++ /dev/null @@ -1,67 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/service/json-compatibility-check/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/service/json-compatibility-check/ -description: Rest协议下对服务接口进行JSON兼容性检测 -linkTitle: 服务接口JSON兼容性检测 -title: 服务接口JSON兼容性检测 -type: docs -weight: 6 ---- - - - - - -## 特性说明 -`Dubbo`目前支持使用`Rest`协议进行服务调用,`Rest`协议默认会使用`JSON`作为序列化方式,但`JSON`并不支持`Java`的一些特殊用法,如`接口`和`抽象类`等。 - -`Dubbo 3.3`版本在服务发布流程中增加了`服务接口JSON兼容性检测`功能, 可以确保服务接口传输对象是否可以被`JSON`序列化, 进一步提升`Rest`服务接口的正确性。 - -## 使用场景 -使用`Rest`作为通信协议,`JSON`作为序列化方式时,对服务接口进行兼容性检查,确保服务接口传输对象可以正确地被`JSON`序列化。 - -## 使用方式 - -当使用`Rest`协议作为通信协议,`JSON`作为序列化方式时,可以在`xml`文件中通过配置`protocol`的`json-check-level`属性来配置`JSON兼容性检查`的级别。 - -目前有`3`种级别,每种级别的具体含义如下: - -* `disabled`:表示`不开启JSON兼容性检查`,此时不会对接口进行兼容性检查。 -* `warn`:表示`开启JSON兼容性检查`,如果出现不兼容的情况,将会以`warn`级别的日志形式将不兼容的接口名称打印输出到终端。 -* `strict`:表示`开启JSON兼容性检查`,如果出现不兼容的情况,将会在启动时抛出`IllegalStateException`异常,终止启动流程,同时会将不兼容的接口名称存放在异常信息中。 - -> 如果没有通过`json-check-level`指定兼容性检查级别,则默认是`warn`告警级别。 - -### 使用示例 - -```xml - - - - - - - - - - - - - - - - - - - - - - -``` diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/local-mock.md b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/local-mock.md deleted file mode 100644 index 08bffee5d1fd..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/local-mock.md +++ /dev/null @@ -1,162 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/service/local-mock/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/service/local-mock/ -description: 了解如何在 Dubbo 中利用本地伪装实现服务降级 -linkTitle: 本地伪装 -title: 本地伪装 -type: docs -weight: 10 ---- - - - - - - -## 特性说明 - -在 Dubbo3 中有一种机制可以实现轻量级的服务降级,也就是本地伪装。 - -Mock 是 Stub 的一个子集,便于服务提供方在客户端执行容错逻辑,因经常需要在出现 RpcException (比如网络失败,超时等)时进行容错,而在出现业务异常(比如登录用户名密码错误)时不需要容错, -如果用 Stub,可能就需要捕获并依赖 RpcException 类,而用 Mock 就可以不依赖 RpcException,因为它的约定就是只有出现 RpcException 时才执行。 - -## 使用场景 - -本地伪装常被用于服务降级。比如某验权服务,当服务提供方全部挂掉后,假如此时服务消费方发起了一次远程调用,那么本次调用将会失败并抛出一个 `RpcException` 异常。 - -为了避免出现这种直接抛出异常的情况出现,那么客户端就可以利用本地伪装来提供 Mock 数据返回授权失败。 - -## 使用方式 - -### 开启 Mock 配置 - -在 Spring XML 配置文件中按以下方式配置: - -```xml - -``` - -或 - -```xml - -``` - -在工程中提供 Mock 实现 [^2]: -在 interface 旁放一个 Mock 实现,它实现 BarService 接口,并有一个无参构造函数。同时,如果没有在配置文件中显式指定 Mock 类的时候,那么需要保证 Mock 类的全限定类名是 `原全限定类名+Mock` 的形式,例如 `com.foo.BarServiceMock`,否则将会 Mock 失败。 -```java -package com.foo; -public class BarServiceMock implements BarService { - public String sayHello(String name) { - // 你可以伪造容错数据,此方法只在出现RpcException时被执行 - return "容错数据"; - } -} -``` - -### 使用 return 关键字 Mock 返回值 - -使用 `return` 来返回一个字符串表示的对象,作为 Mock 的返回值。合法的字符串可以是: -- *empty*:代表空,返回基本类型的默认值、集合类的空值、自定义实体类的空对象,如果返回值是一个实体类,那么此时返回的将会是一个属性都为默认值的空对象而不是 `null`。 -- *null*:返回 `null` -- *true*:返回 `true` -- *false*:返回 `false` -- *JSON 字符串*:返回反序列化 JSON 串后所得到的对象 - -举个例子,如果服务的消费方经常需要 try-catch 捕获异常,如: - -```java -public class DemoService { - - public Offer findOffer(String offerId) { - Offer offer = null; - try { - offer = offerService.findOffer(offerId); - } catch (RpcException e) { - logger.error(e); - } - - return offer; - } -} -``` - -那么请考虑改为 Mock 实现,并在 Mock 实现中 `return null`。如果只是想简单的忽略异常,在 `2.0.11` 以上版本可用: - -```xml - -``` - -### 使用 throw 关键字 Mock 抛出异常 - -使用 `throw` 来返回一个 Exception 对象,作为 Mock 的返回值。 - -当调用出错时,抛出一个默认的 RPCException: - -```xml - - -``` - -当调用出错时,抛出指定的 Exception: - -自定义异常必须拥有一个入参为 `String` 的构造函数,该构造函数将用于接受异常信息。 -```xml - - -``` - -### 使用 force 和 fail 关键字来配置 Mock 的行为 - -`force:` 代表强制使用 Mock 行为,在这种情况下不会走远程调用。 - -`fail:` 与默认行为一致,只有当远程调用发生错误时才使用 Mock 行为。也就是说,配置的时候其实是可以不使用 `fail` 关键字的,直接使用 `throw` 或者 `return` 就可以了。 - -`force:` 和 `fail:` 都支持与 `throw` 或者 `return` 组合使用。 - -强制返回指定值: - -```xml - - -``` - -强制抛出指定异常: - -```xml - - -``` - -调用失败时返回指定值: -```xml - - - - - -``` - -调用失败时抛出异常 - -```xml - - - - - -``` - -### 在方法级别配置 Mock - -Mock 可以在方法级别上指定,假定 `com.foo.BarService` 上有好几个方法,我们可以单独为 `sayHello()` 方法指定 Mock 行为。 - -具体配置如下所示,在本例中,只要 `sayHello()` 被调用到时,强制返回 "fake": - -```xml - - - - -``` diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/multi-protocols.md b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/multi-protocols.md deleted file mode 100644 index 8bf228f84145..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/multi-protocols.md +++ /dev/null @@ -1,67 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/service/multi-protocols/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/service/multi-protocols/ -description: 在 Dubbo 中配置多协议 -linkTitle: 多协议 -title: 多协议 -type: docs -weight: 9 ---- - - - - - -## 特性说明 -Dubbo 允许配置多协议,在不同服务上支持不同协议或者同一服务上同时支持多种协议。 - -## 使用场景 - -与不同系统的兼容:如果你正在与一个支持特定协议的系统集成,你可以使用 Dubbo 对该协议的支持来方便通信。例如,如果您正在与使用 RMI 的遗留系统进行集成,则可以使用 Dubbo 的 RMI 协议支持与该系统进行通信。使用多种协议可以提供灵活性,并允许您为您的特定用例选择最佳选项。 - -- 改进的性能:不同的协议可能具有不同的性能特征,这取决于传输的数据量和网络条件等因素。通过使用多种协议,可以根据您的性能要求选择最适合给定情况的协议。 -- 安全性:一些协议可能提供比其他协议更好的安全特性。HTTPS 协议通过加密传输的数据来提供安全通信,这对于保护敏感数据非常有用。 -- 易用性:某些协议在某些情况下可能更易于使用。如果正在构建 Web 应用程序并希望与远程服务集成,使用 HTTP 协议可能比使用需要更复杂设置的协议更方便。 - -## 使用方式 - -### 不同服务不同协议 -不同服务在性能上适用不同协议进行传输,比如大数据用短连接协议,小数据大并发用长连接协议 - -```xml - - - - - - - - - - - - -``` - -### 多协议暴露服务 -需要与 http 客户端相互操作 - -```xml - - - - - - - - - - -``` \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/multi-registry.md b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/multi-registry.md deleted file mode 100644 index 1a2b6fd43c35..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/multi-registry.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/service/multi-registry/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/service/multi-registry/ -description: 在 Dubbo 中把同一个服务注册到多个注册中心上 -linkTitle: 多注册中心 -title: 多注册中心 -type: docs -weight: 10 ---- - - - - - -## 特性说明 -Dubbo 支持同一服务向多注册中心同时注册,或者不同服务分别注册到不同的注册中心上去,甚至可以同时引用注册在不同注册中心上的同名服务。另外,注册中心是支持自定义扩展的 [^1]。 - -## 使用场景 -- 高可用:多个注册服务器确保即使其中一个注册服务器出现故障,服务仍然可用。 -- 负载:同时访问大量服务,使用多个注册服务器帮助在多个服务器之间分配负载提高系统的整体性能和可扩展性。 -- 区域:不同地理位置的服务,使用多个注册服务器来确保根据其位置注册和发现服务减少请求需要传输的距离来帮助提高系统的性能和可靠性。 -- 安全:使用多个注册服务器。期望将一台注册服务器用于内部服务,另一台用于外部服务,以确保只有授权的客户端才能访问您的内部服务。 - -## 使用方式 -### 多注册中心注册 - -比如:中文站有些服务来不及在青岛部署,只在杭州部署,而青岛的其它应用需要引用此服务,就可以将服务同时注册到两个注册中心。 -```xml - - - - - - - - - -``` - -### 不同服务使用不同注册中心 - -比如:CRM 有些服务是专门为国际站设计的,有些服务是专门为中文站设计的。 -```xml - - - - - - - - - - - -``` - -### 多注册中心引用 - -比如:CRM 需同时调用中文站和国际站的 PC2 服务,PC2 在中文站和国际站均有部署,接口及版本号都一样,但连的数据库不一样。 -```xml - - - - - - - - - - - -``` - -如果只是测试环境临时需要连接两个不同注册中心,使用竖号分隔多个不同注册中心地址: - -```xml - - - - - - - - -``` - -[^1]: 可以自行扩展注册中心,参见:[注册中心扩展](../../../reference-manual/spi/description/registry) diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/multi-versions.md b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/multi-versions.md deleted file mode 100644 index bccdcda6f48b..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/multi-versions.md +++ /dev/null @@ -1,57 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/service/multi-versions/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/service/multi-versions/ -description: 在 Dubbo 中为同一个服务配置多个版本 -linkTitle: 服务分版本 -title: 服务分版本 -type: docs -weight: 1 ---- - - - - - - -## 特性说明 -**按照以下的步骤进行版本迁移** - -1. 在低压力时间段,先升级一半提供者为新版本 -2. 再将所有消费者升级为新版本 -3. 然后将剩下的一半提供者升级为新版本 - -#### 配置 -- 新老版本服务提供者 -- 新老版本服务消费者 - -## 使用场景 -当一个接口实现,出现不兼容升级时,可以用版本号过渡,版本号不同的服务相互间不引用。 - ->参考用例 -[https://github.com/apache/dubbo-samples/tree/master/dubbo-samples-version](https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-version) - -## 使用方式 -### 服务提供者 -老版本服务提供者配置 -```xml - -``` -新版本服务提供者配置 -```xml - -``` -### 服务消费者 -老版本服务消费者配置 -```xml - -``` -新版本服务消费者配置 -```xml - -``` -### 不区分版本 -如果不需要区分版本,可以按照以下的方式配置 -```xml - -``` \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/port-unification.md b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/port-unification.md deleted file mode 100644 index 522294ec1f30..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/port-unification.md +++ /dev/null @@ -1,139 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/service/port-unification/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/service/port-unification/ -description: Dubbo 端口协议复用, 单端口多协议支持 -linkTitle: 端口协议复用 -title: 端口协议复用 -type: docs -weight: 1 ---- - - - - - -## 特性说明 -通过对protocol进行配置,dubbo3可以支持端口的协议复用。 -比如使用Triple协议启动端口复用后,可以在相同的端口上为服务增加 -Dubbo协议支持,以及Qos协议支持。这些协议的识别都是由一个统一的端口复用 -服务器进行处理的,可以用于服务的协议迁移,并且可以节约端口以及相关的资源,减少运维的复杂性。 - -![pu-server-image1](/imgs/blog/pu-server/pu-server-flow.png) - -- 在服务的创建阶段,通过从Config层获取到服务导出的协议配置从而创建不同的Protocol对象进行导出。在导出的过程 -中,如果不是第一次创建端口复用的Server,那么Exchanger会将Protcol层传递的数据保存到Server,用于后续处理该协议类型的消息。 - -- 当客户端的消息传递过来后,首先会通过Server传递给ProtocolDetector,如果完成了识别,那么就会标记该客户端为对应的协议。并通过WireProtocol配置对应的处理逻辑,最后交给ChannelOperator完成底层的IO框架和对应的Dubbo框架的处理逻辑的绑定。 - -- 以上的协议识别完成之后,Channel已经确定了如何处理远程的客户端消息,通过对应的ServerPipeline进行处理即可(在处理的过程中也会根据配置信息决定消息的处理线程)。 - -## 使用场景 -- 最常用的是用于服务发现。这允许应用程序通过网络发现服务,然后使用同一端口与它们通信,有助于降低网络通信的复杂性,并使其更易于管理。 - -- 可以用于负载平衡。这允许应用程序在多个远程服务或服务集群之间平衡负载,有助于提高服务的可扩展性、可靠性和可用性。 - -- 可以用于服务监控。这允许应用程序监视远程服务的运行状况,并在服务出现故障或变得不可用时发出警报,有助于确保服务的可用性并减少停机时间。 - -> 参考用例 -[https://github.com/apache/dubbo-samples/tree/master/dubbo-samples-port-unification](https://github.com/apache/dubbo-samples/tree/master/3-extensions/protocol/dubbo-samples-port-unification) - -## 使用方式 -在同一主机上部署多个服务或需要通过负载均衡器访问多个服务。 - -> 关于Dubbo支持的配置方式 [配置说明](/zh-cn/overview/mannual/java-sdk/reference-manual/config/) - -### 服务多协议导出 - -ext-protocol参数支持配置多个不同的协议,协议之间通过","进行分隔。 - -#### xml 配置 - -```xml - - - - - - -``` - -#### API 配置 - -```java -ProtocolConfig config = new ProtocolConfig(CommonConstants.TRIPLE, -1); - -config.setExtProtocol(CommonConstants.DUBBO+","); -``` - -#### yaml 配置 - -``` yaml -dubbo: - application: - name: dubbo-springboot-demo-provider - protocol: - name: tri - port: -1 - ext-protocol: dubbo, -``` - -#### properties 配置 -```properties -dubbo.protocol.name=tri -dubbo.protocol.ext-protocol=dubbo, -dubbo.protocol.port=20880 -``` - -### Qos接入 - -#### Qos模块导入 - -```xml - - org.apache.dubbo - dubbo-qos - -``` - -完成Qos模块的导入之后,相关的配置项可参考[Qos操作手册](/zh-cn/overview/mannual/java-sdk/reference-manual/qos/overview/)进行配置。 - -默认情况下,基于端口复用的Qos服务在模块导入后是启动的。 - - - -### Qos使用 - -将Qos协议接入到端口复用的场景下,需要在建立连接之后,客户端先向服务端发送消息,对比将Qos协议通过单个端口提供服务,端口复用版的Qos协议在处理telnet连接的情况下需要用户执行一些操作,完成协议识别(二选一)。 - -1. 直接调用命令 - - 直接调用telnet支持的命令也可以完成识别,在用户不熟悉的情况下可以调用help指令完成识别 - - ![pu-server-image2](/imgs/blog/pu-server/qos-telnet-directcall.png) - -2. 发送telnet命令识别 - - 通过telnet命令建立连接之后,执行以下几个步骤: - - 1. 使用 crtl + "]" 进入到telnet交互界面(telnet默认的escape character) - 2. 调用 "send ayt" 向服务端发送特殊识别字段(为telnet协议的一个特殊字段) - 3. 回车完成消息发送并进入到dubbo的交互界面 - - ![pu-server-imgs3](/imgs/blog/pu-server/qos-telnet-sendayt.png) - - -### 服务引用 - -以[dubbo-samples-port-unification](https://github.com/apache/dubbo-samples/tree/master/3-extensions/protocol/dubbo-samples-port-unification)中的例子作为基础, 引用不同协议的服务和非端口复用情况下的配置是一致的,下面通过Consumer端的InvokerListener输出调用过程中的URL信息。 - -```java -ReferenceConfig reference = new ReferenceConfig<>(); -reference.setInterface(GreetingService.class); -reference.setListener("consumer"); -reference.setProtocol(this.protocol); -// reference.setProtocol(CommonConstants.DUBBO); -// reference.setProtocol(CommonConstants.TRIPLE); -``` - -![pu-server-imgs4](/imgs/blog/pu-server/reference-service.png) \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/preflight-check.md b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/preflight-check.md deleted file mode 100644 index 2f4182a8ba52..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/preflight-check.md +++ /dev/null @@ -1,75 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/service/preflight-check/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/service/preflight-check/ -description: 在启动时检查依赖的服务是否可用 -linkTitle: 启动时检查 -title: 启动时检查 -type: docs -weight: 1 ---- - - - - - -## 特性说明 -Dubbo 缺省会在启动时检查依赖的服务是否可用,不可用时会抛出异常,阻止 Spring 初始化完成,以便上线时,能及早发现问题,默认 `check="true"`。 - -可以通过 `check="false"` 关闭检查,比如,测试时,有些服务不关心,或者出现了循环依赖,必须有一方先启动。 - -另外,如果你的 Spring 容器是懒加载的,或者通过 API 编程延迟引用服务,请关闭 check,否则服务临时不可用时,会抛出异常,拿到 null 引用,如果 `check="false"`,总是会返回引用,当服务恢复时,能自动连上。 - -## 使用场景 - -- 单向依赖:有依赖关系(建议默认设置)和无依赖关系(可以设置 check=false) -- 相互依赖:即循环依赖,(不建议设置 check=false) -- 延迟加载处理 - -> check 只用来启动时检查,运行时没有相应的依赖仍然会报错。 - -## 使用方式 - -**配置含义** - -`dubbo.reference.com.foo.BarService.check`,覆盖 `com.foo.BarService`的 reference 的 check 值,就算配置中有声明,也会被覆盖。 - -`dubbo.consumer.check=false`,是设置 reference 的 `check` 的缺省值,如果配置中有显式的声明,如:``,不会受影响。 - -`dubbo.registry.check=false`,前面两个都是指订阅成功,但提供者列表是否为空是否报错,如果注册订阅失败时,也允许启动,需使用此选项,将在后台定时重试。 - -### 通过 spring 配置文件 - -关闭某个服务的启动时检查 - -```xml - -``` - -关闭所有服务的启动时检查 - -```xml - -``` - -关闭注册中心启动时检查 - -```xml - -``` - -### 通过 dubbo.properties - -```properties -dubbo.reference.com.foo.BarService.check=false -dubbo.consumer.check=false -dubbo.registry.check=false -``` - -### 通过 -D 参数 - -```sh -java -Ddubbo.reference.com.foo.BarService.check=false -java -Ddubbo.consumer.check=false -java -Ddubbo.registry.check=false -``` \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/registry-only.md b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/registry-only.md deleted file mode 100644 index 0465f89bc506..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/registry-only.md +++ /dev/null @@ -1,38 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/service/registry-only/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/service/registry-only/ -description: 只注册不订阅 -linkTitle: 只注册 -title: 只注册 -type: docs -weight: 41 ---- - - - - - -## 特性说明 -如果有两个镜像环境,两个注册中心,有一个服务只在其中一个注册中心有部署,另一个注册中心还没来得及部署,而两个注册中心的其它应用都需要依赖此服务。这个时候,可以让服务提供者方只注册服务到另一注册中心,而不从另一注册中心订阅服务。 - - -## 使用场景 -服务互不依赖的情况或者当服务提供者端发生变化时,服务提供者不需要接收通知时。 - -该机制通常用于提供程序相对静态且不太可能更改的场景或者提供程序和使用者互不依赖的场景。 - -## 使用方式 -### 禁用订阅配置 - -```xml - - -``` - -**或者** - -```xml - - -``` \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/service-downgrade.md b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/service-downgrade.md deleted file mode 100644 index f8cbd4b71c03..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/service-downgrade.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/service/service-downgrade/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/service/service-downgrade/ -description: 降级 Dubbo 服务 -linkTitle: 服务降级 -title: 服务降级 -type: docs -weight: 3 ---- - - - - - - -## 特性说明 -推荐使用相关限流降级组件(如 [Sentinel](https://sentinelguard.io/zh-cn/docs/open-source-framework-integrations.html))以达到最佳体验。参考示例实践:[微服务治理/限流降级](/zh-cn/overview/tasks/ecosystem/rate-limit/) - -服务降级是指服务在非正常情况下进行降级应急处理。 - -## 使用场景 - -- 某服务或接口负荷超出最大承载能力范围,需要进行降级应急处理,避免系统崩溃 -- 调用的某非关键服务或接口暂时不可用时,返回模拟数据或空,业务还能继续可用 -- 降级非核心业务的服务或接口,腾出系统资源,尽量保证核心业务的正常运行 -- 某上游基础服务超时或不可用时,执行能快速响应的降级预案,避免服务整体雪崩 - -## 使用方式 - -以 xml 配置为例:(通过注解方式配置类似) - -### 1.配置一 -`mock="true"` - -例: -```xml - -``` -这种方式需要在相同包下有类名 + `Mock`后缀的实现类,即`com.xxx.service`包下有`DemoServiceMock`类。 - -### 2.配置二 -`mock="com.xxx.service.DemoServiceMock"` - -例: -```xml - -``` -这种方式指定 Mock 类的全路径。 - -### 3.配置三 -`mock="[fail|force]return|throw xxx"` - -* fail 或 force 关键字可选,表示调用失败或不调用强制执行 mock 方法,如果不指定关键字默认为 fail -* return 表示指定返回结果,throw 表示抛出指定异常 -* xxx 根据接口的返回类型解析,可以指定返回值或抛出自定义的异常 - -例: -```xml - -``` - -```xml - -``` - -```xml - -``` - -```xml - -``` - -```xml - -``` - -```xml - -``` - -### 4.配合 dubbo-admin 使用 - -* 应用消费端引入 `dubbo-mock-admin`依赖 - -* 应用消费端启动时设置 JVM 参数,`-Denable.dubbo.admin.mock=true` - -* 启动 dubbo-admin,在服务 Mock-> 规则配置菜单下设置 Mock 规则 - -以服务方法的维度设置规则,设置返回模拟数据,动态启用/禁用规则 - - -{{% alert title="注意事项" color="primary" %}} - -Dubbo 启动时会检查配置,当 mock 属性值配置有误时会启动失败,可根据错误提示信息进行排查 - -- 配置格式错误,如 `return+null` 会报错,被当做 mock 类型处理,`return` 后面可省略不写或者跟空格后再跟返回值 -- 类型找不到错误,如自定义 mock 类、throw 自定义异常,请检查类型是否存在或是否有拼写错误 -{{% /alert %}} diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/service-group.md b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/service-group.md deleted file mode 100644 index dbd43aae8f35..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/service-group.md +++ /dev/null @@ -1,193 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/service/service-group/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/service/service-group/ -description: 使用服务分组区分服务接口的不同实现 -linkTitle: 服务分组 -title: 服务分组 -type: docs -weight: 2 ---- - - - - - - -## 特性说明 -同一个接口针对不同的业务场景、不同的使用需求或者不同的功能模块等场景,可使用服务分组来区分不同的实现方式。同时,这些不同实现所提供的服务是可并存的,也支持互相调用。 - -## 使用场景 -当一个接口有多种实现时,可以用 group 区分。 - -> 参考用例 -[https://github.com/apache/dubbo-samples/tree/master/dubbo-samples-group](https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-group) - -## 使用方式 - -### 注解配置 - -#### 服务提供端(注解配置) - -使用 @DubboService 注解,添加 group 参数 - -```java -@DubboService(group = "demo") -public class DemoServiceImpl implements DemoService { - ... -} - -@DubboService(group = "demo2") -public class Demo2ServiceImpl implements DemoService { - ... -} -``` - -启动 Dubbo 服务,可在注册中心看到相同服务名不同分组的服务,以 Nacos 作为注册中心为例,显示如下内容: - -![image-service-group-1.png](/imgs/blog/service-group-1.png) - -#### 服务消费端(注解配置) - -使用 @DubboReference 注解,添加 group 参数 - -```java -@DubboReference(group = "demo") -private DemoService demoService; - -@DubboReference(group = "demo2") -private DemoService demoService2; - -//group值为*,标识匹配任意服务分组 -@DubboReference(group = "*") -private DemoService demoService2; -``` - - -#### 分组聚合 - -> 参考用例 -[https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-merge](https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-merge) - -```java -// 分组聚合,对所有分组进行merge后返回 -@DubboReference(group = "*", merger = "true") -private DemoService demoService2; - -// 分组聚合,对指定分组进行merge后返回 -@DubboReference(group = "merge,merge2", merger = "true") -private DemoService demoService2; - -``` - -同样启动 Dubbo 服务后,可在注册中心看到相同服务名不同分组的引用者,以 Nacos 作为注册中心为例,显示如下内容: -![image-service-group-2.png](/imgs/blog/service-group-2.png) - -### xml配置 - -#### 服务提供端( xml 配置) - -使用 标签,添加 group 参数 - -```xml - - - ... - - - -... - -``` - -启动 Dubbo 服务,可在注册中心看到相同服务名不同分组的服务,以 Nacos 作为注册中心为例,显示如下内容: - -![image-service-group-1.png](/imgs/blog/service-group-1.png) - -#### 服务消费端( xml 配置) - -使用 注解,添加 group 参数 - -```xml - - - ... - - - - - - - - ... - -``` - -同样启动 Dubbo 服务后,可在注册中心看到相同服务名不同分组的引用者,以 Nacos 作为注册中心为例,显示如下内容: - -![image-service-group-2.png](/imgs/blog/service-group-2.png) - -### API配置 - -#### 服务提供端( API 配置) - -使用 org.apache.dubbo.config.ServiceConfig 类,添加 group 参数 - -```java -// ServiceConfig为重对象,内部封装了与注册中心的连接,以及开启服务端口 -// 请自行缓存,否则可能造成内存和连接泄漏 -ServiceConfig service = new ServiceConfig<>(); -service.setInterface(DemoService.class); -service.setGroup("demo"); -... - -ServiceConfig service2 = new ServiceConfig<>(); -service.setInterface(DemoService.class); -service.setGroup("demo2"); -... -``` - -启动 Dubbo 服务,可在注册中心看到相同服务名不同分组的服务,以 Nacos 作为注册中心为例,显示如下内容: - -![image-service-group-1.png](/imgs/blog/service-group-1.png) - -#### 服务消费端( API 配置) - -使用 org.apache.dubbo.config.ReferenceConfig,添加 group 参数 - -```java -// ReferenceConfig为重对象,内部封装了与注册中心的连接,以及开启服务端口 -// 请自行缓存,否则可能造成内存和连接泄漏 -ReferenceConfig reference = new ReferenceConfig<>(); -reference.setInterface(DemoService.class); -reference.setGroup("demo"); -... - -ReferenceConfig reference2 = new ReferenceConfig<>(); -reference2.setInterface(DemoService.class); -reference2.setGroup("demo2"); -... - -ReferenceConfig reference3 = new ReferenceConfig<>(); -reference3.setInterface(DemoService.class); -reference3.setGroup("*"); -... - -``` -同样启动 Dubbo 服务后,可在注册中心看到相同服务名不同分组的引用者,以 Nacos 作为注册中心为例,显示如下内容: -![image-service-group-2.png](/imgs/blog/service-group-2.png) - - -> 总是 **只调** 一个可用组的实现 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/streaming.md b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/streaming.md deleted file mode 100644 index cf93ebc4e30c..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/streaming.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/service/streaming/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/service/streaming/ -description: 基于 Triple 协议进行流式通信 -linkTitle: 流式通信 -title: 流式通信 -type: docs -weight: 4 ---- - - - - - - -TBD \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/subscribe-only.md b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/subscribe-only.md deleted file mode 100644 index bde2b3b81ed5..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/subscribe-only.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/service/subscribe-only/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/service/subscribe-only/ -description: 只订阅不注册 -linkTitle: 只订阅 -title: 只订阅 -type: docs -weight: 6 ---- - - - - - -## 特性说明 - -为方便开发测试,经常会在线下共用一个所有服务可用的注册中心,这时,如果一个正在开发中的服务提供者注册,可能会影响消费者不能正常运行。 - -可以让服务提供者开发方,只订阅服务(开发的服务可能依赖其它服务),而不注册正在开发的服务,通过直连测试正在开发的服务。 - -![/user-guide/images/subscribe-only.jpg](/imgs/user/subscribe-only.jpg) - -## 使用场景 - -- 消费者是一个正在开发但尚未部署的新应用程序。消费者希望订阅未注册的服务,以确保在部署后能够访问所需的服务。 -- 消费者是正在更新或修改的现有应用程序。消费者希望订阅未注册的服务以确保它能够访问更新或修改的服务。 -- 消费者是在暂存环境中开发或测试的应用程序。消费者希望订阅未注册的服务,以确保在开发或测试时能够访问所需的服务。 - -## 使用方式 - -### 禁用注册配置 - -```xml - -``` -**或者** - -```xml - -``` \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/transaction.md b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/transaction.md deleted file mode 100644 index 7e972a6bd5c3..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/transaction.md +++ /dev/null @@ -1,413 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/service/transaction/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/service/transaction/ -description: 在 Dubbo 中使用分布式事务 -linkTitle: 分布式事务 -title: 分布式事务 -type: docs -weight: 1 ---- - - - - - -## 特性说明 -分布式事务提供对补偿事务的支持,能够在事务失败时回滚事务的影响,支持全局事务超时,能够指定事务完成的超时时间,对日志提供支持,能够查看分布式应用程序中所有服务中发生的事务的历史记录,能够轻松地调试和排除事务。 - -## 使用场景 -- 电商:当客户在线购买商品时,提供分布式交易。可以确保订单和付款在不同的数据库和服务中保持同步,有助于防止付款丢失和订单错误。 -- 银行:当客户在账户之间转账时,提供分布式交易。可以确保资金正确转移,所有数据库和服务保持同步。 -- 医疗保健:用于在患者接受医疗治疗时提供分布式事务。可以确保医疗记录、账单信息和患者信息在多个系统中保持同步。 -- 供应链管理:当材料从一个地点运送到另一个地点时,提供分布式事务。可以确保库存水平、订单和装运信息在多个系统中保持同步。 - -## 使用方式 - -### **第一步** - -首先访问: [https://seata.apache.org/unversioned/download/seata-server](https://seata.apache.org/unversioned/download/seata-server) - -下载我们需要使用的 seata1.5.2 服务 - -### **第二步** - -1.在你的参与全局事务的数据库中加入 undo_log 这张表(TCC,SAGA,XA 可跳过这步) - -```sql --- for AT mode you must to init this sql for you business database. the seata server not need it. -CREATE TABLE IF NOT EXISTS `undo_log` -( - `branch_id` BIGINT(20) NOT NULL COMMENT 'branch transaction id', - `xid` VARCHAR(100) NOT NULL COMMENT 'global transaction id', - `context` VARCHAR(128) NOT NULL COMMENT 'undo_log context,such as serialization', - `rollback_info` LONGBLOB NOT NULL COMMENT 'rollback info', - `log_status` INT(11) NOT NULL COMMENT '0:normal status,1:defense status', - `log_created` DATETIME(6) NOT NULL COMMENT 'create datetime', - `log_modified` DATETIME(6) NOT NULL COMMENT 'modify datetime', - UNIQUE KEY `ux_undo_log` (`xid`, `branch_id`) -) ENGINE = InnoDB - AUTO_INCREMENT = 1 - DEFAULT CHARSET = utf8 COMMENT ='AT transaction mode undo table'; -``` - -2.在你的 mysql 数据库中创建名为 seata 的库,并使用以下下 sql - -```sql --- -------------------------------- The script used when storeMode is 'db' -------------------------------- --- the table to store GlobalSession data -CREATE TABLE IF NOT EXISTS `global_table` -( - `xid` VARCHAR(128) NOT NULL, - `transaction_id` BIGINT, - `status` TINYINT NOT NULL, - `application_id` VARCHAR(32), - `transaction_service_group` VARCHAR(32), - `transaction_name` VARCHAR(128), - `timeout` INT, - `begin_time` BIGINT, - `application_data` VARCHAR(2000), - `gmt_create` DATETIME, - `gmt_modified` DATETIME, - PRIMARY KEY (`xid`), - KEY `idx_gmt_modified_status` (`gmt_modified`, `status`), - KEY `idx_transaction_id` (`transaction_id`) -) ENGINE = InnoDB - DEFAULT CHARSET = utf8; - --- the table to store BranchSession data -CREATE TABLE IF NOT EXISTS `branch_table` -( - `branch_id` BIGINT NOT NULL, - `xid` VARCHAR(128) NOT NULL, - `transaction_id` BIGINT, - `resource_group_id` VARCHAR(32), - `resource_id` VARCHAR(256), - `branch_type` VARCHAR(8), - `status` TINYINT, - `client_id` VARCHAR(64), - `application_data` VARCHAR(2000), - `gmt_create` DATETIME(6), - `gmt_modified` DATETIME(6), - PRIMARY KEY (`branch_id`), - KEY `idx_xid` (`xid`) -) ENGINE = InnoDB - DEFAULT CHARSET = utf8; - --- the table to store lock data -CREATE TABLE IF NOT EXISTS `lock_table` -( - `row_key` VARCHAR(128) NOT NULL, - `xid` VARCHAR(96), - `transaction_id` BIGINT, - `branch_id` BIGINT NOT NULL, - `resource_id` VARCHAR(256), - `table_name` VARCHAR(32), - `pk` VARCHAR(36), - `gmt_create` DATETIME, - `gmt_modified` DATETIME, - PRIMARY KEY (`row_key`), - KEY `idx_branch_id` (`branch_id`) -) ENGINE = InnoDB - DEFAULT CHARSET = utf8; -``` - -### **第三步** - -在你的项目中引入 seata 依赖 - -spring-boot 应用: - -``` - - io.seata - seata-spring-boot-starter - 1.5.2 - -``` - -spring 应用: - -``` - - io.seata - seata-all - 1.5.2 - -``` - -### **第四步** - -spring-boot 应用: - -参考 [seata/script/client/spring at develop · seata/seata (github.com)](https://github.com/seata/seata/tree/develop/script/client/spring) - -加到你项目的 application.yml中. - -```yaml -seata: - enabled: true - application-id: applicationName - tx-service-group: my_test_tx_group - enable-auto-data-source-proxy: true #仅AT与XA模式需要为true,开启后会自动代理数据源 - data-source-proxy-mode: AT #可选AT&XA - config: - type: nacos - nacos: - #namespace: 如果配置创建在非默认namespace,请在此处填写namespace的id - serverAddr: 127.0.0.1:8848 - group: SEATA_GROUP - username: "nacos" - password: "nacos" - data-id: seata.properties - registry: - type: nacos - nacos: - application: seata-server - server-addr: 127.0.0.1:8848 - group: SEATA_GROUP - #namespace: 如果配置创建在非默认namespace,请在此处填写namespace的id - username: "nacos" - password: "nacos" -``` - -spring 应用: - -添加 [seata/script/client/conf at develop · seata/seata (github.com)](https://github.com/seata/seata/tree/develop/script/client/conf) 下 registry.conf,由于高可用部署使用第三方配置中心,故无需 file.conf - -``` -registry { - # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa、custom - type = "nacos" - nacos { - application = "seata-server" - serverAddr = "127.0.0.1:8848" - group = "SEATA_GROUP" - namespace = "" - username = "" - password = "" - ##if use MSE Nacos with auth, mutex with username/password attribute - #accessKey = "" - #secretKey = "" - ##if use Nacos naming meta-data for SLB service registry, specify nacos address pattern rules here - #slbPattern = "" - } -} - -config { - # file、nacos 、apollo、zk、consul、etcd3、springCloudConfig、custom - type = "nacos" - nacos { - serverAddr = "127.0.0.1:8848" - namespace = "" - group = "SEATA_GROUP" - username = "" - password = "" - ##if use MSE Nacos with auth, mutex with username/password attribute - #accessKey = "" - #secretKey = "" - dataId = "seata.properties" - } -} -``` - -### **第五步** - -运行你下载的 nacos,并参考 [https://github.com/seata/seata/tree/develop/script/config-center](https://github.com/seata/seata/tree/develop/script/config-center) 的 config.txt 并修改 - -```properties -#仅client使用 -#事务分组叫my_test_tx_group对应的seata-server集群为default -service.vgroupMapping.my_test_tx_group=default -#以下仅server使用 -store.mode=db -store.db.datasource=druid -store.db.dbType=mysql -store.db.driverClassName=com.mysql.jdbc.Driver -store.db.url=jdbc:mysql://127.0.0.1:3306/seata?useUnicode=true -store.db.user=username -store.db.password=password -store.db.minConn=5 -store.db.maxConn=30 -store.db.globalTable=global_table -store.db.branchTable=branch_table -store.db.queryLimit=100 -store.db.lockTable=lock_table -store.db.maxWait=5000 -``` - -打开 nacos 控制台,在对应的 namespace 下创建 dataId 为 seata.properties 的配置,并填写 group 为 SEATA_GROUP,并将以上内容填入选择类型为 properties 保存 -Dingtalk_20220724021635.jpg.png - -### **第六步** - -更改 server 中的 application.yml - -```yaml -server: - port: 7091 - -spring: - application: - name: seata-server - -logging: - config: classpath:logback-spring.xml - file: - path: ${user.home}/logs/seata - -console: - user: - username: seata - password: seata - -seata: - config: - # support: nacos, consul, apollo, zk, etcd3 - type: nacos - nacos: - server-addr: 127.0.0.1:8848 - #namespace: 如果配置创建在非默认namespace,请在此处填写namespace的id - group: SEATA_GROUP - username: - password: - ##if use MSE Nacos with auth, mutex with username/password attribute - #access-key: "" - #secret-key: "" - data-id: seata.properties - registry: - # support: nacos, eureka, redis, zk, consul, etcd3, sofa - type: nacos - nacos: - application: seata-server - server-addr: 127.0.0.1:8848 - group: SEATA_GROUP - namespace: - cluster: default - #namespace: 如果配置创建在非默认namespace,请在此处填写namespace的id - password: - ##if use MSE Nacos with auth, mutex with username/password attribute - #access-key: "" - #secret-key: "" -# server: -# service-port: 8091 #If not configured, the default is '${server.port} + 1000' - security: - secretKey: SeataSecretKey0c382ef121d778043159209298fd40bf3850a017 - tokenValidityInMilliseconds: 1800000 - ignore: - urls: /,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.ico,/console-fe/public/**,/api/v1/auth/login -``` - -### **第七步** - -在全局事务调用者(发起全局事务的服务)的接口上加入 @GlobalTransactional 示例如下: - -```java -@GetMapping(value = "testCommit") -@GlobalTransactional -public Object testCommit(@RequestParam(name = "id",defaultValue = "1") Integer id, - @RequestParam(name = "sum", defaultValue = "1") Integer sum) { - Boolean ok = productService.reduceStock(id, sum); - if (ok) { - LocalDateTime now = LocalDateTime.now(); - Orders orders = new Orders(); - orders.setCreateTime(now); - orders.setProductId(id); - orders.setReplaceTime(now); - orders.setSum(sum); - orderService.save(orders); - return "ok"; - } else { - return "fail"; - } -} -``` - -spring 应用在使用 AT 或 XA 模式下需手动代理数据源选择事务模式和初始化事务扫描器 - -```java -@Primary -@Bean("dataSource") -public DataSource dataSource(DataSource druidDataSource) { - //AT 代理 二选一 - return new DataSourceProxy(druidDataSource); - //XA 代理 - return new DataSourceProxyXA(druidDataSource) -} -``` - -```java - @Bean - public GlobalTransactionScanner globalTransactionScanner() { - return new GlobalTransactionScanner("应用名", "my_test_tx_group"); - } -``` - -如果使用 tcc 模式,需要额外在对应的 provider 的 serviceimpl 中定义两阶段的 try 和 confirm(commit) cancel(rollback) - -spring-boot 应用需关闭数据源代理 - -```yaml -seata: - enable-auto-data-source-proxy: false -``` - -```java -/** - * 定义两阶段提交 name = 该tcc的bean名称,全局唯一 commitMethod = commit 为二阶段确认方法 rollbackMethod = rollback 为二阶段取消方法 - * useTCCFence=true 为开启防悬挂 - * BusinessActionContextParameter注解 传递参数到二阶段中 - * - * @param params -入参 - * @return String - */ -@TwoPhaseBusinessAction(name = "beanName", commitMethod = "commit", rollbackMethod = "rollback", useTCCFence = true) -public void insert(@BusinessActionContextParameter(paramName = "params") Map params) { - logger.info("此处可以预留资源,或者利用tcc的特点,与AT混用,二阶段时利用一阶段在此处存放的消息,通过二阶段发出,比如redis,mq等操作"); -} - -/** - * 确认方法、可以另命名,但要保证与commitMethod一致 context可以传递try方法的参数 - * - * @param context 上下文 - * @return boolean - */ -public void commit(BusinessActionContext context) { - logger.info("预留资源真正处理,或者发出mq消息和redis入库"); -} - -/** - * 二阶段取消方法 - * - * @param context 上下文 - * @return boolean - */ -public void rollback(BusinessActionContext context) { - logger.info("预留资源释放,或清除一阶段准备让二阶段提交时发出的消息缓存"); -} -``` - -linux/macos - -```shell -cd bin - -sh seata-server.sh -``` - -windows - -```shell -cd bin -./seata-server.bat -``` - -运行 seata-server,成功后,运行自己的服务 dubbo provider&consumer - - - -### **第八步高可用 Seata-server 搭建** - -由于 seata-server 支持计算与存储分离模式,并支持暴露服务地址至多种注册中心,仅需按照第六步配置完毕后水平扩展即可 - -> 详情请访问: [seata官网](https://seata.io/) diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/traffic/_index.md b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/traffic/_index.md deleted file mode 100755 index db8334d60554..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/traffic/_index.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/traffic/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/traffic/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/traffic/mesh-style/ab-testing-deployment/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/traffic/mesh-style/blue-green-deployment/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/traffic/mesh-style/canary-deployment/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/traffic/mesh-style/demo-rule-deployment/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/traffic/mesh-style/destination-rule/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/traffic/mesh-style/dynamic-rule-deployment/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/traffic/mesh-style/virtualservice/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/traffic/mesh-style/weight-rule-deployment/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/traffic/config-rule/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/traffic/routing-rule/ -description: 流量治理规则 -hide_summary: true -linkTitle: 流量治理 -no_list: true -title: 流量治理规则 -type: docs -weight: 2 ---- - -Java 版本实现的流量治理规则完全遵循 Dubbo 框架设计的流量治理能力,可以通过以下链接了解更多详情: -* [Dubbo 流量治理规则设计](/zh-cn/overview/core-features/traffic/) -* [Dubbo 流量治理示例任务](/zh-cn/overview/tasks/traffic-management/) \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/traffic/_index.md.bak b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/traffic/_index.md.bak deleted file mode 100755 index 5962b3c566c0..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/traffic/_index.md.bak +++ /dev/null @@ -1,45 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/traffic/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/traffic/ -description: 流量治理规则 -hide_summary: true -linkTitle: 流量治理 -no_list: true -title: 流量治理规则 -type: docs -weight: 2 ---- - - -### 流量管理 - -流量管理的本质是将请求根据制定好的路由规则分发到应用服务上,如下图所示: - -![What is traffic control](/imgs/v3/concepts/what-is-traffic-control.png) - -其中: -+ 路由规则可以有多个,不同的路由规则之间存在优先级。如:Router(1) -> Router(2) -> …… -> Router(n) -+ 一个路由规则可以路由到多个不同的应用服务。如:Router(2) 既可以路由到 Service(1) 也可以路由到 Service(2) -+ 多个不同的路由规则可以路由到同一个应用服务。如:Router(1) 和 Router(2) 都可以路由到 Service(2) -+ 路由规则也可以不路由到任何应用服务。如:Router(m) 没有路由到任何一个 Service 上,所有命中 Router(m) 的请求都会因为没有对应的应用服务处理而导致报错 -+ 应用服务可以是单个的实例,也可以是一个应用集群。 - -### Dubbo Mesh 格式流量管理介绍 - -Dubbo 提供了支持 mesh 方式的流量管理策略,可以很容易实现 [A/B测试](./mesh-style/ab-testing-deployment/)、[金丝雀发布](./mesh-style/canary-deployment/)、[蓝绿发布](./mesh-style/blue-green-deployment/) 等能力。 - -Dubbo 将整个流量管理分成 [VirtualService](./mesh-style/virtualservice/) 和 [DestinationRule](./mesh-style/destination-rule/) 两部分。当 Consumer 接收到一个请求时,会根据 [VirtualService](./mesh-style/virtualservice/) 中定义的 [DubboRoute](./mesh-style/virtualservice/#dubboroute) 和 [DubboRouteDetail](./mesh-style/virtualservice/#dubboroutedetail) 匹配到对应的 [DubboDestination](./mesh-style/virtualservice/#dubbodestination) 中的 subnet,最后根据 [DestinationRule](./mesh-style/destination-rule/) 中配置的 [subnet](./mesh-style/destination-rule/#subset) 信息中的 labels 找到对应需要具体路由的 Provider 集群。其中: - -+ [VirtualService](./mesh-style/virtualservice/) 主要处理入站流量分流的规则,支持服务级别和方法级别的分流。 -+ [DubboRoute](./mesh-style/virtualservice/#dubboroute) 主要解决服务级别的分流问题。同时,还提供的重试机制、超时、故障注入、镜像流量等能力。 -+ [DubboRouteDetail](./mesh-style/virtualservice/#dubboroutedetail) 主要解决某个服务中方法级别的分流问题。支持方法名、方法参数、参数个数、参数类型、header 等各种维度的分流能力。同时也支持方法级的重试机制、超时、故障注入、镜像流量等能力。 -+ [DubboDestination](./mesh-style/virtualservice/#dubbodestination) 用来描述路由流量的目标地址,支持 host、port、subnet 等方式。 -+ [DestinationRule](./mesh-style/destination-rule/) 主要处理目标地址规则,可以通过 hosts、subnet 等方式关联到 Provider 集群。同时可以通过 [trafficPolicy](./mesh-style/destination-rule/#trafficpolicy) 来实现负载均衡。 - -这种设计理念很好的解决流量分流和目标地址之间的耦合问题。不仅将配置规则进行了简化有效避免配置冗余的问题,还支持 [VirtualService](./mesh-style/virtualservice/) 和 [DestinationRule](./mesh-style/destination-rule/) 的任意组合,可以非常灵活的支持各种业务使用场景。 - -### 流量治理 -- [路由规则](./routing-rule/) -- [配置规则](./config-rule/) -- [Mesh 路由规则](./mesh-style) \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/traffic/config-rule.md.bak b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/traffic/config-rule.md.bak deleted file mode 100644 index 82351e74faef..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/traffic/config-rule.md.bak +++ /dev/null @@ -1,176 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/traffic/config-rule/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/traffic/config-rule/ -description: 在 Dubbo 中配置应用级治理规则和服务级治理规则 -linkTitle: 配置规则 -title: 配置规则 -type: docs -weight: 34 ---- - - - - - -## 配置规则概述 -覆盖规则是 Dubbo 设计的在无需重启应用的情况下,动态调整 RPC 调用行为的一种能力。2.7.0 版本开始,支持从**服务**和**应用**两个粒度来调整动态配置。 - -> 请在服务治理控制台查看或修改覆盖规则。 - -### 应用粒度 - -```yaml -# 将应用demo(key:demo)在20880端口上提供(side:provider)的所有服务(scope:application)的权重修改为1000(weight:1000)。 ---- -configVersion: v2.7 -scope: application -key: demo -enabled: true -configs: -- addresses: ["0.0.0.0:20880"] - side: provider - parameters: - weight: 1000 - ... -``` - -### 服务粒度 - -```yaml -# 所有消费(side:consumer)DemoService服务(key:org.apache.dubbo.samples.governance.api.DemoService)的应用实例(addresses:[0.0.0.0]),超时时间修改为6000ms ---- -configVersion: v2.7 -scope: service -key: org.apache.dubbo.samples.governance.api.DemoService -enabled: true -configs: -- addresses: [0.0.0.0] - side: consumer - parameters: - timeout: 6000 - ... -``` -## 配置规则 -### 规则详解 -- `configVersion` 表示 dubbo 的版本 -- `scope`表示配置作用范围,分别是应用(application)或服务(service)粒度。**必填**。 -- `key` 指定规则体作用在哪个服务或应用。**必填**。 - - scope=service时,key取值为[{group}:]{service}[:{version}]的组合 -- scope=application时,key取值为application名称 -- `enabled=true` 覆盖规则是否生效,可不填,缺省生效。 -- `configs` 定义具体的覆盖规则内容,可以指定n(n>=1)个规则体。**必填**。 - - side, - - applications - - services - - parameters - - addresses - - providerAddresses - -**配置场景** -1. 要修改整个应用的配置还是某个服务的配置。 - - 应用:`scope: application, key: app-name`(还可使用`services`指定某几个服务)。 - - 服务:`scope: service, key:group+service+version `。 - -2. 修改是作用到消费者端还是提供者端。 - - 消费者:`side: consumer` ,作用到消费端时(你还可以进一步使用`providerAddress`, `applications`选定特定的提供者示例或应用)。 - - 提供者:`side: provider`。 - -3. 配置是否只对某几个特定实例生效。 - - 所有实例:`addresses: ["0.0.0.0"] `或`addresses: ["0.0.0.0:*"] `具体由side值决定。 - - 指定实例:`addersses[实例地址列表]`。 - -4. 要修改的属性是哪个。 - -### 配置模板 - -```yaml ---- -configVersion: v2.7 -scope: application/service -key: app-name/group+service+version -enabled: true -configs: -- addresses: ["0.0.0.0"] - providerAddresses: ["1.1.1.1:20880", "2.2.2.2:20881"] - side: consumer - applications/services: [] - parameters: - timeout: 1000 - cluster: failfase - loadbalance: random -- addresses: ["0.0.0.0:20880"] - side: provider - applications/services: [] - parameters: - threadpool: fixed - threads: 200 - iothreads: 4 - dispatcher: all - weight: 200 -... -``` - -### 示例 - -**禁用提供者** -> 通常用于临时踢除某台提供者机器,相似的,禁止消费者访问请使用路由规则 - ```yaml - --- - configVersion: v2.7 - scope: application - key: demo-provider - enabled: true - configs: - - addresses: ["10.20.153.10:20880"] - side: provider - parameters: - disabled: true - ... - ``` - -**调整权重** -> 通常用于容量评估,缺省权重为 200 - ```yaml - --- - configVersion: v2.7 - scope: application - key: demo-provider - enabled: true - configs: - - addresses: ["10.20.153.10:20880"] - side: provider - parameters: - weight: 200 - ... - ``` - -**调整负载均衡策略** -> 缺省负载均衡策略为 random - ```yaml - --- - configVersion: v2.7 - scope: application - key: demo-consumer - enabled: true - configs: - - side: consumer - parameters: - loadbalance: random - ... - ``` - -**服务降级** -> 通常用于临时屏蔽某个出错的非关键服务 -```yaml ---- - configVersion: v2.7 - scope: service - key: org.apache.dubbo.samples.governance.api.DemoService - enabled: true - configs: - - side: consumer - parameters: - force: return null - ... -``` \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/traffic/routing-rule.md.bak b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/traffic/routing-rule.md.bak deleted file mode 100644 index ed26f22b4ebc..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/traffic/routing-rule.md.bak +++ /dev/null @@ -1,244 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/traffic/routing-rule/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/traffic/routing-rule/ -description: 通过 Dubbo 中的路由规则做服务治理 -linkTitle: 路由规则 -title: 路由规则 -type: docs -weight: 33 ---- - - - - - -## 路由规则概述 -路由规则在发起一次RPC调用前起到过滤目标服务器地址的作用,过滤后的地址列表,将作为消费端最终发起RPC调用的备选地址。 - -您可以随时在服务治理控制台 [Dubbo-Admin](https://github.com/apache/dubbo-admin) 写入路由规则。 - -- 条件路由。支持以服务或 Consumer 应用为粒度配置路由规则。 -- 标签路由。以 Provider 应用为粒度配置路由规则。 - -### 应用粒度 - - ```yaml - # app1的消费者只能消费所有端口为20880的服务实例 - # app2的消费者只能消费所有端口为20881的服务实例 - --- - scope: application - force: true - runtime: true - enabled: true - key: governance-conditionrouter-consumer - conditions: - - application=app1 => address=*:20880 - - application=app2 => address=*:20881 - ... - ``` - -### 服务粒度 - - ```yaml - # DemoService的sayHello方法只能消费所有端口为20880的服务实例 - # DemoService的sayHi方法只能消费所有端口为20881的服务实例 - --- - scope: service - force: true - runtime: true - enabled: true - key: org.apache.dubbo.samples.governance.api.DemoService - conditions: - - method=sayHello => address=*:20880 - - method=sayHi => address=*:20881 - ... - ``` -> 后续我们计划在 2.6.x 版本的基础上继续增强脚本路由功能。 - -## 规则详解 - -- `scope`表示路由规则的作用粒度,scope的取值会决定key的取值。**必填**。 - - service 服务粒度 - - application 应用粒度 -- `Key`明确规则体作用在哪个服务或应用。**必填**。 - - scope=service时,key取值为[{group}:]{service}[:{version}]的组合 - - scope=application时,key取值为application名称 -- `enabled=true` 当前路由规则是否生效,可不填,缺省生效。 -- `force=false` 当路由结果为空时,是否强制执行,如果不强制执行,路由结果为空的路由规则将自动失效,可不填,缺省为 `false`。 -- `runtime=false` 是否在每次调用时执行路由规则,否则只在提供者地址列表变更时预先执行并缓存结果,调用时直接从缓存中获取路由结果。如果用了参数路由,必须设为 `true`,需要注意设置会影响调用的性能,可不填,缺省为 `false`。 -- `priority=1` 路由规则的优先级,用于排序,优先级越大越靠前执行,可不填,缺省为 `0`。 -- `conditions` 定义具体的路由规则内容。**必填**。 - -### Conditions规则体 -`conditions`部分是规则的主体,由1到任意多条规则组成,下面我们就每个规则的配置语法做详细说明: - -**格式** - -- `=>` 之前的为消费者匹配条件,所有参数和消费者的 URL 进行对比,当消费者满足匹配条件时,对该消费者执行后面的过滤规则。 -- `=>` 之后为提供者地址列表的过滤条件,所有参数和提供者的 URL 进行对比,消费者最终只拿到过滤后的地址列表。 -- 如果匹配条件为空,表示对所有消费方应用,如:`=> host != 10.20.153.11` -- 如果过滤条件为空,表示禁止访问,如:`host = 10.20.153.10 =>` - -**表达式** - -参数支持 - -- 服务调用信息,如:method, argument 等,暂不支持参数路由 -- URL 本身的字段,如:protocol, host, port 等 -- 以及 URL 上的所有参数,如:application, organization 等 - -条件支持 - -- 等号 `=` 表示"匹配",如:`host = 10.20.153.10` -- 不等号 `!=` 表示"不匹配",如:`host != 10.20.153.10` - -值支持 - -- 以逗号 `,` 分隔多个值,如:`host != 10.20.153.10,10.20.153.11` -- 以星号 `*` 结尾,表示通配,如:`host != 10.20.*` -- 以美元符 `$` 开头,表示引用消费者参数,如:`host = $host` - -### Condition示例 - -排除预发布机 - -``` -=> host != 172.22.3.91 -``` - -白名单 - -``` -register.ip != 10.20.153.10,10.20.153.11 => -``` - -> 一个服务只能有一条白名单规则,否则两条规则交叉,就都被筛选掉了 - -黑名单 - -``` -register.ip = 10.20.153.10,10.20.153.11 => -``` - -服务寄宿在应用上,只暴露一部分的机器,防止整个集群挂掉 - -``` -=> host = 172.22.3.1*,172.22.3.2* -``` - -为重要应用提供额外的机器 - -``` -application != kylin => host != 172.22.3.95,172.22.3.96 -``` - -读写分离 - -``` -method = find*,list*,get*,is* => host = 172.22.3.94,172.22.3.95,172.22.3.96 -method != find*,list*,get*,is* => host = 172.22.3.97,172.22.3.98 -``` - -前后台分离 - -``` -application = bops => host = 172.22.3.91,172.22.3.92,172.22.3.93 -application != bops => host = 172.22.3.94,172.22.3.95,172.22.3.96 -``` - -隔离不同机房网段 - -``` -host != 172.22.3.* => host != 172.22.3.* -``` - -提供者与消费者部署在同集群内,本机只访问本机的服务 - -``` -=> host = $host -``` - - - -## 标签路由规则 - -标签路由通过将某一个或多个服务的提供者划分到同一个分组,约束流量只在指定分组中流转,从而实现流量隔离的目的,可以作为蓝绿发布、灰度发布等场景的能力基础。 - -### 规则详解 - -**格式** - -- `Key`明确规则体作用到哪个应用。**必填**。 -- `enabled=true` 当前路由规则是否生效,可不填,缺省生效。 -- `force=false` 当路由结果为空时,是否强制执行,如果不强制执行,路由结果为空的路由规则将自动失效,可不填,缺省为 `false`。 -- `runtime=false` 是否在每次调用时执行路由规则,否则只在提供者地址列表变更时预先执行并缓存结果,调用时直接从缓存中获取路由结果。如果用了参数路由,必须设为 `true`,需要注意设置会影响调用的性能,可不填,缺省为 `false`。 -- `priority=1` 路由规则的优先级,用于排序,优先级越大越靠前执行,可不填,缺省为 `0`。 -- `tags` 定义具体的标签分组内容,可定义任意n(n>=1)个标签并为每个标签指定实例列表。**必填**。 - - name, 标签名称 -- addresses, 当前标签包含的实例列表 - - - -**降级约定** - -1. `dubbo.tag=tag1` 时优先选择 标记了`tag=tag1` 的 provider。若集群中不存在与请求标记对应的服务,默认将降级请求 tag为空的provider;如果要改变这种默认行为,即找不到匹配tag1的provider返回异常,需设置`dubbo.force.tag=true`。 - -2. `dubbo.tag`未设置时,只会匹配tag为空的provider。即使集群中存在可用的服务,若 tag 不匹配也就无法调用,这与约定1不同,携带标签的请求可以降级访问到无标签的服务,但不携带标签/携带其他种类标签的请求永远无法访问到其他标签的服务。 -### Provider - -标签主要是指对Provider端应用实例的分组,目前有两种方式可以完成实例分组,分别是`动态规则打标`和`静态规则打标`,其中动态规则相较于静态规则优先级更高,而当两种规则同时存在且出现冲突时,将以动态规则为准。 - -> 可随时在**服务治理控制台**下发标签归组规则 - -**动态规则打标** -```yaml -# governance-tagrouter-provider应用增加了两个标签分组tag1和tag2 -# tag1包含一个实例 127.0.0.1:20880 -# tag2包含一个实例 127.0.0.1:20881 ---- - force: false - runtime: true - enabled: true - key: governance-tagrouter-provider - tags: - - name: tag1 - addresses: ["127.0.0.1:20880"] - - name: tag2 - addresses: ["127.0.0.1:20881"] -... -``` - - - -**静态打标** - -```xml - -``` - -**or** - -```xml - -``` - -**or** - -```properties -java -jar xxx-provider.jar -Ddubbo.provider.tag={the tag you want, may come from OS ENV} -``` - - - -### Consumer - -```java -RpcContext.getContext().setAttachment(Constants.TAG_KEY,"tag1"); -``` - -> 请求标签的作用域为每一次 invocation,使用 attachment 来传递请求标签,注意保存在 attachment 中的值将会在一次完整的远程调用中持续传递,得益于这样的特性,我们只需要在起始调用时,通过一行代码的设置,达到标签的持续传递。 - -> 目前仅仅支持 hardcoding 的方式设置 dubboTag。注意到 RpcContext 是线程绑定的,优雅的使用 TagRouter 特性,建议通过 servlet 过滤器(在 web 环境下),或者定制的 SPI 过滤器设置 dubboTag。 - -> 自定义路由参考[路由扩展](/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/router/) \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/triple/_index.md b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/triple/_index.md deleted file mode 100755 index b457a3c411e9..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/triple/_index.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/triple/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/triple/ -description: "" -linkTitle: Triple 协议 -title: Dubbo3 通信协议 -- Triple -type: docs -weight: 10 ---- diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/triple/idl.md b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/triple/idl.md deleted file mode 100644 index 91c33bb7df10..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/triple/idl.md +++ /dev/null @@ -1,246 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/triple/idl/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/triple/idl/ -description: "" -linkTitle: 使用 IDL + Protobuf 跨语言定义服务 -title: 使用 IDL + Protobuf 跨语言定义服务 -type: docs -weight: 1 ---- - - - - - - -服务是 Dubbo 中的核心概念,一个服务代表一组 RPC 方法的集合,服务是面向用户编程、服务发现机制等的基本单位。Dubbo 开发的基本流程是:用户定义 RPC 服务,通过约定的配置 -方式将 RPC 声明为 Dubbo 服务,然后就可以基于服务 API 进行编程了。对服务提供者来说是提供 RPC 服务的具体实现,而对服务消费者来说则是使用特定数据发起服务调用。 - -下面从定义服务、编译服务、配置并加载服务三个方面说明如何快速的开发 Dubbo 服务。 - -具体用例可以参考:[dubbo-samples-triple/stub](https://github.com/apache/dubbo-samples/tree/master/3-extensions/protocol/dubbo-samples-triple/src/main/java/org/apache/dubbo/sample/tri/stub); - -## 定义服务 -Dubbo3 推荐使用 IDL 定义跨语言服务,如您更习惯使用特定语言的服务定义方式,请移步[多语言 SDK](/zh-cn/overview/mannual/)查看。 - -```text -syntax = "proto3"; - -option java_multiple_files = true; -option java_package = "org.apache.dubbo.demo"; -option java_outer_classname = "DemoServiceProto"; -option objc_class_prefix = "DEMOSRV"; - -package demoservice; - -// The demo service definition. -service DemoService { - rpc SayHello (HelloRequest) returns (HelloReply) {} -} - -// The request message containing the user's name. -message HelloRequest { - string name = 1; -} - -// The response message containing the greetings -message HelloReply { - string message = 1; -} - -``` - -以上是使用 IDL 定义服务的一个简单示例,我们可以把它命名为 `DemoService.proto`,proto 文件中定义了 RPC 服务名称 `DemoService` 与方法签名 -`SayHello (HelloRequest) returns (HelloReply) {}`,同时还定义了方法的入参结构体、出参结构体 `HelloRequest` 与 `HelloReply`。 -IDL 格式的服务依赖 Protobuf 编译器,用来生成可以被用户调用的客户端与服务端编程 API,Dubbo 在原生 Protobuf Compiler 的基础上提供了适配多种语言的特有插件,用于适配 Dubbo 框架特有的 API 与编程模型。 - -> 使用 Dubbo3 IDL 定义的服务只允许一个入参与出参,这种形式的服务签名有两个优势,一是对多语言实现更友好,二是可以保证服务的向后兼容性,依赖于 Protobuf 序列化的兼容性,我们可以很容易的调整传输的数据结构如增、删字段等,完全不用担心接口的兼容性。 - -## 编译服务 -根据当前采用的语言,配置相应的 Protobuf 插件,编译后将生产语言相关的服务定义 stub。 - -### Java - -Java compiler 配置参考: -```xml - - org.xolstice.maven.plugins - protobuf-maven-plugin - 0.6.1 - - com.google.protobuf:protoc:${protoc.version}:exe:${os.detected.classifier} - - grpc-java - io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier} - - - - dubbo - org.apache.dubbo - dubbo-compiler - 3.0.10 - org.apache.dubbo.gen.tri.Dubbo3TripleGenerator - - - - - - - compile - test-compile - compile-custom - test-compile-custom - - - - -``` - -Java 语言生成的 stub 如下,核心是一个接口定义 -```java -@javax.annotation.Generated( -value = "by Dubbo generator", -comments = "Source: DemoService.proto") -public interface DemoService { - static final String JAVA_SERVICE_NAME = "org.apache.dubbo.demo.DemoService"; - static final String SERVICE_NAME = "demoservice.DemoService"; - - org.apache.dubbo.demo.HelloReply sayHello(org.apache.dubbo.demo.HelloRequest request); - - CompletableFuture sayHelloAsync(org.apache.dubbo.demo.HelloRequest request); -} -``` - -### Golang - -Go 语言生成的 stub 如下,这个 stub 里存了用户定义的接口和数据的类型。 - -```go -func _DUBBO_Greeter_SayHello_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(HelloRequest) - if err := dec(in); err != nil { - return nil, err - } - base := srv.(dgrpc.Dubbo3GrpcService) - args := []interface{}{} - args = append(args, in) - invo := invocation.NewRPCInvocation("SayHello", args, nil) - if interceptor == nil { - result := base.GetProxyImpl().Invoke(ctx, invo) - return result.Result(), result.Error() - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/main.Greeter/SayHello", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - result := base.GetProxyImpl().Invoke(context.Background(), invo) - return result.Result(), result.Error() - } - return interceptor(ctx, in, info, handler) -} -``` - - -## 配置并加载服务 -提供端负责提供具体的 Dubbo 服务实现,也就是遵循 RPC 签名所约束的格式,去实现具体的业务逻辑代码。在实现服务之后,要将服务实现注册为标准的 Dubbo 服务, -之后 Dubbo 框架就能根据接收到的请求转发给服务实现,执行方法,并将结果返回。 - -消费端的配置会更简单一些,只需要声明 IDL 定义的服务为标准的 Dubbo 服务,框架就可以帮助开发者生成相应的 proxy,开发者将完全面向 proxy 编程, -基本上 Dubbo 所有语言的实现都保证了 proxy 依据 IDL 服务定义暴露标准化的接口。 - -### Java -提供端,实现服务 -```java -public class DemoServiceImpl implements DemoService { - private static final Logger logger = LoggerFactory.getLogger(DemoServiceImpl.class); - - @Override - public HelloReply sayHello(HelloRequest request) { - logger.info("Hello " + request.getName() + ", request from consumer: " + RpcContext.getContext().getRemoteAddress()); - return HelloReply.newBuilder() - .setMessage("Hello " + request.getName() + ", response from provider: " - + RpcContext.getContext().getLocalAddress()) - .build(); - } - - @Override - public CompletableFuture sayHelloAsync(HelloRequest request) { - return CompletableFuture.completedFuture(sayHello(request)); - } -} -``` - -提供端,注册服务(以 Spring XML 为例) -```xml - - -``` - -消费端,引用服务 -```xml - -``` - -消费端,使用服务 proxy -```java -public void callService() throws Exception { - ... - DemoService demoService = context.getBean("demoService", DemoService.class); - HelloRequest request = HelloRequest.newBuilder().setName("Hello").build(); - HelloReply reply = demoService.sayHello(request); - System.out.println("result: " + reply.getMessage()); -} -``` - -### Golang - -提供端,实现服务 - -```go -type User struct { - ID string - Name string - Age int32 - Time time.Time -} - -type UserProvider struct { -} - -func (u *UserProvider) GetUser(ctx context.Context, req []interface{}) (*User, error) { - gxlog.CInfo("req:%#v", req) - rsp := User{"A001", "Alex Stocks", 18, time.Now()} - gxlog.CInfo("rsp:%#v", rsp) - return &rsp, nil -} - -func (u *UserProvider) Reference() string { - return "UserProvider" -} - -func (u User) JavaClassName() string { - return "org.apache.dubbo.User" -} - -func main() { - hessian.RegisterPOJO(&User{}) - config.SetProviderService(new(UserProvider)) -} -``` - -消费端,使用服务 proxy - -```go -func main() { - config.Load() - user := &pkg.User{} - err := userProvider.GetUser(context.TODO(), []interface{}{"A001"}, user) - if err != nil { - os.Exit(1) - return - } - gxlog.CInfo("response result: %v\n", user) -} -``` \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/triple/streaming.md b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/triple/streaming.md deleted file mode 100644 index 2f08b1227ca9..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/triple/streaming.md +++ /dev/null @@ -1,305 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/triple/streaming/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/triple/streaming/ -description: "" -linkTitle: Streaming 通信模式 -title: Streaming 通信模式 -type: docs -weight: 3 ---- - - - - - - -具体用例可以参考:[dubbo-samples-triple/pojo](https://github.com/apache/dubbo-samples/tree/master/3-extensions/protocol/dubbo-samples-triple/src/main/java/org/apache/dubbo/sample/tri/pojo); - -## Stream (流) -Stream 是 Dubbo3 新提供的一种调用类型,在以下场景时建议使用流的方式: - -- 接口需要发送大量数据,这些数据无法被放在一个 RPC 的请求或响应中,需要分批发送,但应用层如果按照传统的多次 RPC 方式无法解决顺序和性能的问题,如果需要保证有序,则只能串行发送 -- 流式场景,数据需要按照发送顺序处理, 数据本身是没有确定边界的 -- 推送类场景,多个消息在同一个调用的上下文中被发送和处理 - -Stream 分为以下三种: -- SERVER_STREAM(服务端流) - ![SERVER_STREAM](/imgs/v3/migration/tri/migrate-server-stream.png) -- CLIENT_STREAM(客户端流) - ![CLIENT_STREAM](/imgs/v3/migration/tri/migrate-client-stream.png) -- BIDIRECTIONAL_STREAM(双向流) - ![BIDIRECTIONAL_STREAM](/imgs/v3/migration/tri/migrate-bi-stream.png) - -> 由于 `java` 语言的限制,BIDIRECTIONAL_STREAM 和 CLIENT_STREAM 的实现是一样的。 - -在 Dubbo3 中,流式接口以 `SteamObserver` 声明和使用,用户可以通过使用和实现这个接口来发送和处理流的数据、异常和结束。 - -> 对于 Dubbo2 用户来说,可能会对StreamObserver感到陌生,这是Dubbo3定义的一种流类型,Dubbo2 中并不存在 Stream 的类型,所以对于迁移场景没有任何影响。 - -流的语义保证 -- 提供消息边界,可以方便地对消息单独处理 -- 严格有序,发送端的顺序和接收端顺序一致 -- 全双工,发送不需要等待 -- 支持取消和超时 - -## 非 PB 序列化的流 -1. api -```java -public interface IWrapperGreeter { - - StreamObserver sayHelloStream(StreamObserver response); - - void sayHelloServerStream(String request, StreamObserver response); -} -``` - -> Stream 方法的方法入参和返回值是严格约定的,为防止写错而导致问题,Dubbo3 框架侧做了对参数的检查, 如果出错则会抛出异常。 -> 对于 `双向流(BIDIRECTIONAL_STREAM)`, 需要注意参数中的 `StreamObserver` 是响应流,返回参数中的 `StreamObserver` 为请求流。 - -2. 实现类 -```java -public class WrapGreeterImpl implements WrapGreeter { - - //... - - @Override - public StreamObserver sayHelloStream(StreamObserver response) { - return new StreamObserver() { - @Override - public void onNext(String data) { - System.out.println(data); - response.onNext("hello,"+data); - } - - @Override - public void onError(Throwable throwable) { - throwable.printStackTrace(); - } - - @Override - public void onCompleted() { - System.out.println("onCompleted"); - response.onCompleted(); - } - }; - } - - @Override - public void sayHelloServerStream(String request, StreamObserver response) { - for (int i = 0; i < 10; i++) { - response.onNext("hello," + request); - } - response.onCompleted(); - } -} -``` - -3. 调用方式 -```java -delegate.sayHelloServerStream("server stream", new StreamObserver() { - @Override - public void onNext(String data) { - System.out.println(data); - } - - @Override - public void onError(Throwable throwable) { - throwable.printStackTrace(); - } - - @Override - public void onCompleted() { - System.out.println("onCompleted"); - } -}); - - -StreamObserver request = delegate.sayHelloStream(new StreamObserver() { - @Override - public void onNext(String data) { - System.out.println(data); - } - - @Override - public void onError(Throwable throwable) { - throwable.printStackTrace(); - } - - @Override - public void onCompleted() { - System.out.println("onCompleted"); - } -}); -for (int i = 0; i < n; i++) { - request.onNext("stream request" + i); -} -request.onCompleted(); -``` - -## 使用 Protobuf 序列化的流 - -对于 `Protobuf` 序列化方式,推荐编写 `IDL` 使用 `compiler` 插件进行编译生成。生成的代码大致如下: -```java -public interface PbGreeter { - - static final String JAVA_SERVICE_NAME = "org.apache.dubbo.sample.tri.PbGreeter"; - static final String SERVICE_NAME = "org.apache.dubbo.sample.tri.PbGreeter"; - - static final boolean inited = PbGreeterDubbo.init(); - - //... - - void greetServerStream(org.apache.dubbo.sample.tri.GreeterRequest request, org.apache.dubbo.common.stream.StreamObserver responseObserver); - - org.apache.dubbo.common.stream.StreamObserver greetStream(org.apache.dubbo.common.stream.StreamObserver responseObserver); -} -``` - -### 完整用例 - -1. 编写 Java 接口 - ```java - import org.apache.dubbo.common.stream.StreamObserver; - import org.apache.dubbo.hello.HelloReply; - import org.apache.dubbo.hello.HelloRequest; - - public interface IGreeter { - /** - *
-         *  Sends greeting by stream
-         * 
- */ - StreamObserver sayHello(StreamObserver replyObserver); - - } - ``` - -2. 编写实现类 - ```java - public class IStreamGreeterImpl implements IStreamGreeter { - - @Override - public StreamObserver sayHello(StreamObserver replyObserver) { - - return new StreamObserver() { - private List replyList = new ArrayList<>(); - - @Override - public void onNext(HelloRequest helloRequest) { - System.out.println("onNext receive request name:" + helloRequest.getName()); - replyList.add(HelloReply.newBuilder() - .setMessage("receive name:" + helloRequest.getName()) - .build()); - } - - @Override - public void onError(Throwable cause) { - System.out.println("onError"); - replyObserver.onError(cause); - } - - @Override - public void onCompleted() { - System.out.println("onComplete receive request size:" + replyList.size()); - for (HelloReply reply : replyList) { - replyObserver.onNext(reply); - } - replyObserver.onCompleted(); - } - }; - } - } - ``` - -3. 创建 Provider - - ```java - public class StreamProvider { - public static void main(String[] args) throws InterruptedException { - ServiceConfig service = new ServiceConfig<>(); - service.setInterface(IStreamGreeter.class); - service.setRef(new IStreamGreeterImpl()); - service.setProtocol(new ProtocolConfig(CommonConstants.TRIPLE, 50051)); - service.setApplication(new ApplicationConfig("stream-provider")); - service.setRegistry(new RegistryConfig("zookeeper://127.0.0.1:2181")); - service.export(); - System.out.println("dubbo service started"); - new CountDownLatch(1).await(); - } - } - ``` - -4. 创建 Consumer - - ```java - public class StreamConsumer { - public static void main(String[] args) throws InterruptedException, IOException { - ReferenceConfig ref = new ReferenceConfig<>(); - ref.setInterface(IStreamGreeter.class); - ref.setCheck(false); - ref.setProtocol(CommonConstants.TRIPLE); - ref.setLazy(true); - ref.setTimeout(100000); - ref.setApplication(new ApplicationConfig("stream-consumer")); - ref.setRegistry(new RegistryConfig("zookeeper://mse-6e9fda00-p.zk.mse.aliyuncs.com:2181")); - final IStreamGreeter iStreamGreeter = ref.get(); - - System.out.println("dubbo ref started"); - try { - - StreamObserver streamObserver = iStreamGreeter.sayHello(new StreamObserver() { - @Override - public void onNext(HelloReply reply) { - System.out.println("onNext"); - System.out.println(reply.getMessage()); - } - - @Override - public void onError(Throwable throwable) { - System.out.println("onError:" + throwable.getMessage()); - } - - @Override - public void onCompleted() { - System.out.println("onCompleted"); - } - }); - - streamObserver.onNext(HelloRequest.newBuilder() - .setName("tony") - .build()); - - streamObserver.onNext(HelloRequest.newBuilder() - .setName("nick") - .build()); - - streamObserver.onCompleted(); - } catch (Throwable t) { - t.printStackTrace(); - } - System.in.read(); - } - } - ``` - -5. 运行 Provider 和 Consumer ,可以看到请求正常返回了 - > onNext\ - > receive name:tony\ - > onNext\ - > receive name:nick\ - > onCompleted - -### 常见问题 - -1. protobuf 类找不到 - -由于 Triple 协议底层需要依赖 protobuf 协议进行传输,即使定义的服务接口不使用 protobuf 也需要在环境中引入 protobuf 的依赖。 - -```xml - - com.google.protobuf - protobuf-java - 3.19.4 - -``` diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/triple/wrap.md b/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/triple/wrap.md deleted file mode 100644 index 5d282218b5f8..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/triple/wrap.md +++ /dev/null @@ -1,179 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/advanced-features-and-usage/triple/wrap/ - - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/triple/wrap/ -description: "" -linkTitle: Pojo 序列化兼容模式 -title: Pojo 序列化兼容模式 -type: docs -weight: 2 ---- - - - - - - -这篇教程会通过从零构建一个简单的工程来演示如何基于 POJO 方式使用 Dubbo Triple, 在应用不改变已有接口定义的同时升级到 Triple 协议。**此模式下 Triple 使用方式与 Dubbo 协议一样。** - -具体用例可以参考:[dubbo-samples-triple/pojo](https://github.com/apache/dubbo-samples/tree/master/3-extensions/protocol/dubbo-samples-triple/src/main/java/org/apache/dubbo/sample/tri/pojo); - -### 前置条件 -- [JDK](https://jdk.java.net/) 版本 >= 8 -- 已安装 [Maven](https://maven.apache.org/) -- 已安装并启动 [Zookeeper](https://zookeeper.apache.org/) - -### 创建工程 -1. 首先创建一个空的 maven 工程 - ``` - $ mvn archetype:generate \ - -DgroupId=org.apache.dubbo \ - -DartifactId=tri-pojo-demo \ - -DarchetypeArtifactId=maven-archetype-quickstart \ - -DarchetypeVersion=1.4 \ - -DarchetypeGroupId=org.apache.maven.archetypes \ - -Dversion=1.0-SNAPSHOT - ``` -2. 切换到工程目录 - ``` - $ cd tri-pojo-demo - ``` -3. 在 `pom.xml` 中设置 JDK 版本,添加 Dubbo 依赖和插件 - ```xml - - UTF-8 - 1.8 - 1.8 - - - - - junit - junit - 4.13 - test - - - org.apache.dubbo - dubbo - 3.0.8 - - - org.apache.dubbo - dubbo-dependencies-zookeeper-curator5 - pom - 3.0.8 - - - com.google.protobuf - protobuf-java - 3.19.4 - - - ``` -4. 添加接口定义`src/main/java/org/apache/dubbo/Greeter.java` - ```java - package org.apache.dubbo; - - public interface Greeter { - String sayHello(String name); - } - ``` -5. 添加服务端接口实现`src/main/java/org/apache/dubbo/GreeterImpl.java` - ```java - package org.apache.dubbo; - - public class GreeterImpl implements Greeter { - @Override - public String sayHello(String name) { - return "Hello," + name + "!"; - } - } - ``` -6. 添加服务端启动类 `src/main/java/org/apache/dubbo/MyDubboServer.java` - ```java - package org.apache.dubbo; - - import org.apache.dubbo.common.constants.CommonConstants; - import org.apache.dubbo.config.ApplicationConfig; - import org.apache.dubbo.config.ProtocolConfig; - import org.apache.dubbo.config.RegistryConfig; - import org.apache.dubbo.config.ServiceConfig; - import org.apache.dubbo.config.bootstrap.DubboBootstrap; - - import java.io.IOException; - - public class MyDubboServer { - - public static void main(String[] args) throws IOException { - ServiceConfig service = new ServiceConfig<>(); - service.setInterface(Greeter.class); - service.setRef(new GreeterImpl()); - - DubboBootstrap bootstrap = DubboBootstrap.getInstance(); - bootstrap.application(new ApplicationConfig("tri-pojo-server")) - .registry(new RegistryConfig("zookeeper://127.0.0.1:2181")) - .protocol(new ProtocolConfig(CommonConstants.TRIPLE, 50051)) - .service(service) - .start(); - System.out.println("Dubbo triple pojo server started"); - System.in.read(); - } - } - ``` - -7. 添加客户端启动类`src/main/java/org/apache/dubbo/MyDubboClient.java` - ```java - package org.apache.dubbo; - - import org.apache.dubbo.common.constants.CommonConstants; - import org.apache.dubbo.config.ApplicationConfig; - import org.apache.dubbo.config.ReferenceConfig; - import org.apache.dubbo.config.RegistryConfig; - import org.apache.dubbo.config.bootstrap.DubboBootstrap; - - public class MyDubboClient { - public static void main(String[] args) { - DubboBootstrap bootstrap = DubboBootstrap.getInstance(); - ReferenceConfig ref = new ReferenceConfig<>(); - ref.setInterface(Greeter.class); - ref.setProtocol(CommonConstants.TRIPLE); - ref.setTimeout(3000); - bootstrap.application(new ApplicationConfig("tri-pojo-client")) - .registry(new RegistryConfig("zookeeper://127.0.0.1:2181")) - .reference(ref) - .start(); - - Greeter greeter = ref.get(); - String reply = greeter.sayHello("pojo"); - System.out.println("Received reply:" + reply); - } - } - ``` -8. 编译代码 - ``` - $ mvn clean install - ``` -9. 启动服务端 - ``` - $ mvn org.codehaus.mojo:exec-maven-plugin:3.0.0:java -Dexec.mainClass="org.apache.dubbo.MyDubboServer" - Dubbo triple pojo server started - ``` -10. 打开新的终端,启动客户端 - ``` - $ mvn org.codehaus.mojo:exec-maven-plugin:3.0.0:java -Dexec.mainClass="org.apache.dubbo.MyDubboClient" - Received reply:message: "Hello,Demo!" - ``` -### 常见问题 - -1. protobuf 类找不到 - -由于 Triple 协议底层需要依赖 protobuf 协议进行传输,即使定义的服务接口不使用 protobuf 也需要在环境中引入 protobuf 的依赖。 - -```xml - - com.google.protobuf - protobuf-java - 3.19.4 - -``` \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/0/1.md b/content/zh-cn/overview/mannual/java-sdk/faq/0/1.md deleted file mode 100644 index cbd45f1d3087..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/0/1.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/0/1/ - - /zh-cn/docs3-v2/java-sdk/faq/0/1/ -description: 0-1 - 线程池资源枯竭 -linkTitle: 0-1 - 线程池资源枯竭 -title: 0-1 - 线程池资源枯竭 -type: docs -weight: 1 ---- - - - - - -服务端的线程资源耗尽了。 -默认情况下,Dubbo 服务端的业务线程数是 200 个。如果多个并发请求量超过了 200,就会拒绝新的请求,抛出此错误。 - -### 可能的原因 -1. Consumer 的并发请求量太大,导致 Provider 端创建的线程数量超限。 -2. 可能 Provider 端在执行业务的时候,由于业务调用外部应用接口,导致线程出现阻塞,从而导致线程池回收不了线程。 - -### 排查和解决步骤 -* 开启 Dubbo 的访问日志功能,排查是否有短时间内大量调用 RPC 服务的情况。 -* 通过 `jps` 和 `jstack` 指令检查线程池中各个线程的状态,看下是否有业务调用外部应用接口造成阻塞。 -* 如果是 Consumer 的并发请求量太大,那么调整 Provider 端的 `dubbo.provider.threads` 参数,将 Dubbo 的线程池的数目调大。 -* 如果 Provider 业务的 QPS 实在太大,目前的服务器数目处理不完,那么增加 Provider 端服务器的数量,让更多的服务器分担压力。 - - -> 这个错误码的 FAQ 页面参考了空冥同学的 [《Dubbo 常见错误及解决方法》](https://github.com/StabilityMan/StabilityGuide/blob/master/docs/diagnosis/plugin/rpc/%E7%B3%BB%E7%BB%9F%E7%A8%B3%E5%AE%9A%E6%80%A7%E2%80%94%E2%80%94Dubbo%E5%B8%B8%E8%A7%81%E9%94%99%E8%AF%AF%E5%8F%8A%E8%A7%A3%E5%86%B3%E6%96%B9%E6%B3%95.md) 。 -所引文章通过 [CC-BY-4.0](http://creativecommons.org/licenses/by/4.0/) 协议赋予了汇编的权利。在此向原作者表示感谢。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/0/10.md b/content/zh-cn/overview/mannual/java-sdk/faq/0/10.md deleted file mode 100644 index d10a44db92cc..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/0/10.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/0/10/ - - /zh-cn/docs3-v2/java-sdk/faq/0/10/ -description: 0-10 - 当前调用不在支持 -linkTitle: 0-10 - 当前调用不在支持 -title: 0-10 - 当前调用不在支持 -type: docs -weight: 10 ---- - - - - - - - -### 可能的原因 - -当前调用的方法可能已经被弃用或声明了 `@Deprecated`,不影响执行结果。 - -### 排查和解决步骤 - -请使用其它可替代的 API 方法。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/0/11.md b/content/zh-cn/overview/mannual/java-sdk/faq/0/11.md deleted file mode 100644 index 7aebd7d2dc5d..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/0/11.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/0/11/ - - /zh-cn/docs3-v2/java-sdk/faq/0/11/ -description: 0-11 - 服务停止失败 -linkTitle: 0-11 - 服务停止失败 -title: 0-11 - 服务停止失败 -type: docs -weight: 11 ---- - - - - - - - -### 可能的原因 - -连接没有及时关闭或内存不足,导致服务在停止时会出现一些异常。 - -### 排查和解决步骤 - -在响应内容完成后进行关闭连接。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/0/12.md b/content/zh-cn/overview/mannual/java-sdk/faq/0/12.md deleted file mode 100644 index 84315caab80c..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/0/12.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/0/12/ - - /zh-cn/docs3-v2/java-sdk/faq/0/12/ -description: 0-12 - 未知异常 -linkTitle: 0-12 - 未知异常 -title: 0-12 - 未知异常 -type: docs -weight: 12 ---- - - - - - -未知异常,一般为API使用或配置异常 - -### 可能的原因 - -转码异常、不支持的加解密方法等等 - -### 排查和解决步骤 - -可根据堆栈信息,进行业务代码行定位。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/0/13.md b/content/zh-cn/overview/mannual/java-sdk/faq/0/13.md deleted file mode 100644 index 466456d575fb..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/0/13.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/0/13/ - - /zh-cn/docs3-v2/java-sdk/faq/0/13/ -description: 0-13 - 指标收集器发生异常 -linkTitle: 0-13 - 指标收集器发生异常 -title: 0-13 - 指标收集器发生异常 -type: docs -weight: 13 ---- - - - - - - - -### 可能的原因 - -指标数据在推送过程中发生错误,推送的服务器连接不上或一些配置错误,目前支持 Prometheus。 - -### 排查和解决步骤 - -请参考配置项参考手册[配置项参考手册](/zh-cn/overview/mannual/java-sdk/reference-manual/config/properties/#metrics)。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/0/14.md b/content/zh-cn/overview/mannual/java-sdk/faq/0/14.md deleted file mode 100644 index 3154d8bd5d21..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/0/14.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/0/14/ - - /zh-cn/docs3-v2/java-sdk/faq/0/14/ -description: 0-14 - 监控异常 -linkTitle: 0-14 - 监控异常 -title: 0-14 - 监控异常 -type: docs -weight: 14 ---- - - - - - -用来统计 RPC 调用次数和调用耗时时间,扩展接口为 MonitorFactory,对应的实现类为 DubboMonitorFactroy。 - - -### 可能的原因 - -用户可以实现该层的 MonitorFactory 扩展接口,实现自定义监控统计策略。 -在自定义监控统计策略的实现类,发生了业务运行时异常。 - -### 排查和解决步骤 - -检查 `org.apache.dubbo.monitor.MonitorFactory` 接口的业务类,实现方法可能存在代码逻辑错误。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/0/15.md b/content/zh-cn/overview/mannual/java-sdk/faq/0/15.md deleted file mode 100644 index 8df92639dd9b..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/0/15.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/0/15/ - - /zh-cn/docs3-v2/java-sdk/faq/0/15/ -description: 0-15 - 加载扩展类时发生异常 -linkTitle: 0-15 - 加载扩展类时发生异常 -title: 0-15 - 加载扩展类时发生异常 -type: docs -weight: 15 ---- - - - - - - - -### 可能的原因 - -1. `clazz` 类并没有实现当前扩展点的接口类。 -2. 扩展名可能是个接口或者不存在。 - -### 排查和解决步骤 - -1. 检查扩展类声明,并没有与之相匹配的扩展实现类。 -2. 扩展实现类需实现扩展点接口类以及方法。 - -

\ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/0/16.md b/content/zh-cn/overview/mannual/java-sdk/faq/0/16.md deleted file mode 100644 index 6e32a1051786..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/0/16.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/0/16/ - - /zh-cn/docs3-v2/java-sdk/faq/0/16/ -description: 0-16 - 没有可用的执行器 -linkTitle: 0-16 - 没有可用的执行器 -title: 0-16 - 没有可用的执行器 -type: docs -weight: 16 ---- - - - - - - - -### 可能的原因 - -内部执行器不可用,此时返回空。 - -### 排查和解决步骤 - -不需要进行干预,dubbo 内部会执行`createExecutorIfAbsent` 方法构建一个新的执行器。 - -

\ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/0/17.md b/content/zh-cn/overview/mannual/java-sdk/faq/0/17.md deleted file mode 100644 index bf0d2de7924a..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/0/17.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/0/17/ - - /zh-cn/docs3-v2/java-sdk/faq/0/17/ -description: 0-17 - 执行器在关闭时发生未知异常 -linkTitle: 0-17 - 执行器在关闭时发生未知异常 -title: 0-17 - 执行器在关闭时发生未知异常 -type: docs -weight: 17 ---- - - - - - - - -### 可能的原因 - -可能使用了自定义的执行器,在编写销毁方法时,产生了异常。 - -### 排查和解决步骤 - -检查是否自定义实现 `org.apache.dubbo.common.threadpool.manager.ExecutorRepository`,检查自定义的 `shutdown` 方法。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/0/18.md b/content/zh-cn/overview/mannual/java-sdk/faq/0/18.md deleted file mode 100644 index 6bf762c6d78d..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/0/18.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/0/18/ - - /zh-cn/docs3-v2/java-sdk/faq/0/18/ -description: 0-18 - 线程池执行器被错误使用 -linkTitle: 0-18 - 线程池执行器被错误使用 -title: 0-18 - 线程池执行器被错误使用 -type: docs -weight: 18 ---- - - - - - - - -### 可能的原因 - -自定义设置了线程数量,系统内部发生了未知异常。 - -### 排查和解决步骤 - -可通过一些第三方的工具或者 `jstack [PID] > jstack.log` 分析堆栈信息,进行定位。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/0/19.md b/content/zh-cn/overview/mannual/java-sdk/faq/0/19.md deleted file mode 100644 index 00ea8670fd9d..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/0/19.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/0/19/ - - /zh-cn/docs3-v2/java-sdk/faq/0/19/ -description: 0-19 - 处理任务时发生异常 -linkTitle: 0-19 - 处理任务时发生异常 -title: 0-19 - 处理任务时发生异常 -type: docs -weight: 19 ---- - - - - - - - -### 可能的原因 - -自定义业务类处理逻辑不当。 - -### 排查和解决步骤 - -可通过一些第三方的工具或者 `jstack [PID] > jstack.log` 分析堆栈信息,进行定位。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/0/2.md b/content/zh-cn/overview/mannual/java-sdk/faq/0/2.md deleted file mode 100644 index 8ebd9377dfeb..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/0/2.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/0/2/ - - /zh-cn/docs3-v2/java-sdk/faq/0/2/ -description: 0-2 - 非法属性值 -linkTitle: 0-2 - 非法属性值 -title: 0-2 - 非法属性值 -type: docs -weight: 2 ---- - - - - - - -### 可能的原因 -这个提示是指用户配置的值与属性本身所需的数据类型并不匹配。比如 `dubbo.comsumer.threads` 属性只能接受数值属性,但是用户所输入的值混入了字母。 - -### 排查和解决步骤 -根据[配置项参考手册](../../../reference-manual/config/properties),查找出错的配置项,检查该项指定的类型,检查是否出现类型不一致的情况。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/0/20.md b/content/zh-cn/overview/mannual/java-sdk/faq/0/20.md deleted file mode 100644 index c5a04f39f9e7..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/0/20.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/0/20/ - - /zh-cn/docs3-v2/java-sdk/faq/0/20/ -description: 0-20 - 存储堆栈信息时发生异常 -linkTitle: 0-20 - 存储堆栈信息时发生异常 -title: 0-20 - 存储堆栈信息时发生异常 -type: docs -weight: 20 ---- - - - - - - - -### 可能的原因 - -1. JVM设置了参数 `-XX:+DisableAttachMechanism` -2. 设置了系统不存在的堆栈转储路径,不存在情况,系统会尝试进行创建,创建时发生了 `SecurityException`, 可能是没有权限。 - -### 排查和解决步骤 - -1. 检查 JVM 是否设置了如上参数。 -2. 检查当前启动服务的账号,是否有权限进行创建文件夹。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/0/21.md b/content/zh-cn/overview/mannual/java-sdk/faq/0/21.md deleted file mode 100644 index e898b669f030..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/0/21.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/0/21/ - - /zh-cn/docs3-v2/java-sdk/faq/0/21/ -description: 0-21 - 构建的实例过多 -linkTitle: 0-21 - 构建的实例过多 -title: 0-21 - 构建的实例过多 -type: docs -weight: 21 ---- - - - - - - -### 可能的原因 - -一般指 `org.apache.dubbo.common.timer.HashedWheelTimer` 创建的实例过多。 - -### 排查和解决步骤 - -不影响实例的构建,可能存在内存泄露的风险。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/0/22.md b/content/zh-cn/overview/mannual/java-sdk/faq/0/22.md deleted file mode 100644 index c7c0b1072755..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/0/22.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/0/22/ - - /zh-cn/docs3-v2/java-sdk/faq/0/22/ -description: 0-22 - 输入输出流异常 -linkTitle: 0-22 - 输入输出流异常 -title: 0-22 - 输入输出流异常 -type: docs -weight: 22 ---- - - - - - - - -### 可能的原因 - -1. 读取不再可用的本地文件。 -2. 尝试读取/写入文件但没有权限。 -3. 尝试写入文件但磁盘空间不再可用。 - -### 排查和解决步骤 - -1. 检查本地文件是否存在。 -2. 检查文件权限。 -3. 检查磁盘空间。 - -可通过一些第三方的工具或者 `jstack [PID] > jstack.log` 分析堆栈信息,进行定位。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/0/23.md b/content/zh-cn/overview/mannual/java-sdk/faq/0/23.md deleted file mode 100644 index 4fe2df873131..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/0/23.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/0/23/ - - /zh-cn/docs3-v2/java-sdk/faq/0/23/ -description: 0-23 - 序列化数据转换异常 -linkTitle: 0-23 - 序列化数据转换异常 -title: 0-23 - 序列化数据转换异常 -type: docs -weight: 23 ---- - - - - - - - -### 可能的原因 - -1. 待序列化数据中存在循环引用,导致堆栈溢出。 -2. 引用的 jar 包版本低或存在兼容性问题。 - -### 排查和解决步骤 - -1. 如使用 FastJson,去掉 `SerializerFeature.DisableCircularReferenceDetec` -2. 检查下或升级版本进行尝试。 - -可通过一些第三方的工具或者 `jstack [PID] > jstack.log` 分析堆栈信息,进行定位。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/0/24.md b/content/zh-cn/overview/mannual/java-sdk/faq/0/24.md deleted file mode 100644 index d9a07e38a3ef..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/0/24.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/0/24/ - - /zh-cn/docs3-v2/java-sdk/faq/0/24/ -description: 0-24 - 覆盖字段值异常 -linkTitle: 0-24 - 覆盖字段值异常 -title: 0-24 - 覆盖字段值异常 -type: docs -weight: 24 ---- - - - - - - - -### 可能的原因 - -1. 实体类未设置 setter/getter 方法。 -2. 可能存在嵌套的属性。 - -### 排查和解决步骤 - -1. 检查实体类并设置 setter/getter 方法。 -2. 根据堆栈信息,检查是否使用嵌套注解。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/0/25.md b/content/zh-cn/overview/mannual/java-sdk/faq/0/25.md deleted file mode 100644 index 4641d3b24980..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/0/25.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/0/25/ - - /zh-cn/docs3-v2/java-sdk/faq/0/25/ -description: 0-25 - 加载映射错误 -linkTitle: 0-25 - 加载映射错误 -title: 0-25 - 加载映射错误 -type: docs -weight: 25 ---- - - - - - - - -### 可能的原因 - -文件访问权限不足 - -### 排查和解决步骤 - -检查文件权限。 -可通过一些第三方的工具或者 `jstack [PID] > jstack.log` 分析堆栈信息,进行定位。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/0/26.md b/content/zh-cn/overview/mannual/java-sdk/faq/0/26.md deleted file mode 100644 index 4f6c42d0e955..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/0/26.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/0/26/ - - /zh-cn/docs3-v2/java-sdk/faq/0/26/ -description: 0-26 - 元数据发布服务时的警告信息 -linkTitle: 0-26 - 元数据发布服务时的警告信息 -title: 0-26 - 元数据发布服务时的警告信息 -type: docs -weight: 26 ---- - - - - - - -### 可能的原因 - -元数据在存储接口与应用的映射关系时,显示的提醒类消息。 - -### 排查和解决步骤 - -一般可根据堆栈信息进行分析,也可不处理。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/0/27.md b/content/zh-cn/overview/mannual/java-sdk/faq/0/27.md deleted file mode 100644 index c59ece4d3da5..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/0/27.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/0/27/ - - /zh-cn/docs3-v2/java-sdk/faq/0/27/ -description: 0-27 - 线程池隔离配置异常 -linkTitle: 0-27 - 线程池隔离配置异常 -title: 0-27 - 线程池隔离配置异常 -type: docs -weight: 27 ---- - - - - - - -### 可能的原因 - -未开启应用的线程池隔离能力,但是却在 `ServiceConfig` 中配置了隔离的线程池信息。 - -### 排查和解决步骤 - -配置开启应用的线程池隔离能力:`dubbo.application.executor-management-mode=isolation` \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/0/28.md b/content/zh-cn/overview/mannual/java-sdk/faq/0/28.md deleted file mode 100644 index ba2076233c99..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/0/28.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/0/28/ - - /zh-cn/docs3-v2/java-sdk/faq/0/28/ -description: 0-28 - 操作了可能会引起危险的行为 -linkTitle: 0-28 - 危险的行为 -title: 0-28 - 操作了可能会引起危险的行为 -type: docs -weight: 28 ---- - - - - - - -### 可能的原因 - -你执行了以下操作之一: -* 尝试或已经调整了 accesslog 的输出位置 - -### 排查和解决步骤 - -请检查应用配置中的 `accesslog.fixed.path=true` 开关是否处于开启状态,如未开启则可忽略;如果当前是开启状态,则请确认是否 acesslog 路径切换的行为是否为可信任的人所执行,以避免可能的安全风险。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/0/29.md b/content/zh-cn/overview/mannual/java-sdk/faq/0/29.md deleted file mode 100644 index 6fcf5d8c1e82..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/0/29.md +++ /dev/null @@ -1,38 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/0/29/ - - /zh-cn/docs3-v2/java-sdk/faq/0/29/ -description: 0-29 - 未找到Tracer依赖 -linkTitle: 0-29 - 未找到Tracer依赖 -title: 0-29 - 未找到Tracer依赖 -type: docs -weight: 29 ---- - -### 可能的原因 - -你已在配置文件中开启了tracing,但未找到Tracer依赖。 - -目前Tracer支持两种,OpenTelemetry和Brave。 - -### 排查和解决步骤 - -选择一个Tracer依赖到你的项目中: - -```xml - - - io.micrometer - micrometer-tracing-bridge-otel - true - -``` - -```xml - - - io.micrometer - micrometer-tracing-bridge-brave - true - -``` \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/0/3.md b/content/zh-cn/overview/mannual/java-sdk/faq/0/3.md deleted file mode 100644 index 0aa5772050a9..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/0/3.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/0/3/ - - /zh-cn/docs3-v2/java-sdk/faq/0/3/ -description: 0-3 - 无法访问缓存路径 -linkTitle: 0-3 - 无法访问缓存路径 -title: 0-3 - 无法访问缓存路径 -type: docs -weight: 3 ---- - - - - - - -其它模块复用了 Common 层的基于文件的缓存机制(目前是元数据模块),而 Common 层的文件缓存机制无法访问它指定的目录。 - -``` -2022-08-29 00:35:00,189 ERROR [org.apache.dubbo.common.cache.FileCacheStoreFactory:?] - [DUBBO] Cache store path can't be created: , dubbo version: , current host: 10.0.1.1, error code: 0-3. This may be caused by inaccessible of cache path, go to https://dubbo.apache.org/faq/0/3 to find instructions. -java.nio.file.FileAlreadyExistsException: [Path] - at java.base/sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:87) - at java.base/sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:103) - at java.base/sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:108) - at java.base/sun.nio.fs.WindowsFileSystemProvider.createDirectory(WindowsFileSystemProvider.java:521) - at java.base/java.nio.file.Files.createDirectory(Files.java:700) - at java.base/java.nio.file.Files.createAndCheckIsDirectory(Files.java:807) - at java.base/java.nio.file.Files.createDirectories(Files.java:753) - at org.apache.dubbo.common.cache.FileCacheStoreFactory.getInstance(FileCacheStoreFactory.java:90) - ... -``` - -### 可能的原因 -1. 多个 Dubbo 进程(或其他 Java 进程)使用了同一个缓存文件。 -2. 由于缓存文件所在目录的文件系统权限问题,导致读写失败。 - -### 排查和解决步骤 -1. 根据下面显示的实际异常找到访问不了的目录,确定下它的文件访问权限。 -2. 确定下是否有别的 Dubbo 实例正在访问这个路径。 -3. 尝试配置 **Java System Property(用 -D 配置的 Java 系统属性)** `dubbo.meta.cache.filePath` 和 `dubbo.mapping.cache.filePath`,将它指定成一个当前用户能够完全控制的目录下。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/0/4.md b/content/zh-cn/overview/mannual/java-sdk/faq/0/4.md deleted file mode 100644 index 66343f96033a..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/0/4.md +++ /dev/null @@ -1,57 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/0/4/ - - /zh-cn/docs3-v2/java-sdk/faq/0/4/ -description: 0-4 - 缓存条目超限 -linkTitle: 0-4 - 缓存条目超限 -title: 0-4 - 缓存条目超限 -type: docs -weight: 4 ---- - - - - - -其它模块复用了 Common 层的基于文件的缓存机制(目前是元数据模块),而 Common 层的文件缓存机制 “发觉” 条目超限。 - - -### 可能的原因 -用户不合理地配置了 **Java System Property** (用 -D 配置的 Java 系统属性) `dubbo.mapping.cache.entrySize` 或者 `dubbo.meta.cache.entrySize` - -**默认值** - - - - - - - - - - - - -
dubbo.mapping.cache.entrySizedubbo.meta.cache.entrySize
10000100
- -### 排查和解决步骤 -1. 尝试重新配置上述 **Java System Property(用 -D 配置的 Java 系统属性)**。 -2. 如果确实没有配置这些 **System Property**,请到 [GitHub Issue Tracker](https://github.com/apache/dubbo/issues) 下发 Issue。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/0/5.md b/content/zh-cn/overview/mannual/java-sdk/faq/0/5.md deleted file mode 100644 index 2c361d5605e1..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/0/5.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/0/5/ - - /zh-cn/docs3-v2/java-sdk/faq/0/5/ -description: 0-5 - 缓存文件大小超限 -linkTitle: 0-5 - 缓存文件大小超限 -title: 0-5 - 缓存文件大小超限 -type: docs -weight: 5 ---- - - - - - -其它模块复用了 Common 层的基于文件的缓存机制(目前是元数据模块),而 Common 层的文件缓存机制 “发觉” 文件大小超限。 - - -### 可能的原因 -1. 用户不合理地配置了 Java System Property (用 -D 配置的 Java 系统属性) `dubbo.mapping.cache.maxFileSize` 或者 `dubbo.meta.cache.maxFileSize` -2. 缓存文件因文件系统或磁盘错误而被破坏。 - - -> `dubbo.mapping.cache.maxFileSize` 和 `dubbo.meta.cache.maxFileSize` 没有显示默认值, -而根据 `org.apache.dubbo.common.cache.FileCacheStore.LimitedLengthBufferedWriter` 的逻辑而查到的最大文件大小的默认值为:`Long.MAX_VALUE` ( 263-1 ) 。 - - - -### 排查和解决步骤 -1. 尝试重新配置上述 **Java System Property(用 -D 配置的 Java 系统属性)**。 -2. 删除缓存文件夹重启 **Provider** 和 **Consumer** (缓存文件夹的位置一般在 `~/.dubbo`。如果配置了 `dubbo.meta.cache.filePath` 和 `dubbo.mapping.cache.filePath` 则为该路径)。 -3. 如果确实没有配置这些 **System Property**,请到 [GitHub Issue Tracker](https://github.com/apache/dubbo/issues) 下发 Issue。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/0/6.md b/content/zh-cn/overview/mannual/java-sdk/faq/0/6.md deleted file mode 100644 index c2ffe485fc7b..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/0/6.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/0/6/ - - /zh-cn/docs3-v2/java-sdk/faq/0/6/ -description: 0-6 - 线程中断异常 -linkTitle: 0-6 - 线程中断异常 -title: 0-6 - 线程中断异常 -type: docs -weight: 6 ---- - - - - - - - -### 可能的原因 - -运行中的线程在处于 `wait、sleep、join` 时,被显示调用 `interrupt()` - -### 排查和解决步骤 - -正常运行的线程在调用了 `interrupt()` 方法后,将对当前线程中断状态设置为 true,但线程的执行并不会受到影响。 -可根据实际情况进行操作或检查业务代码有无被错误使用。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/0/7.md b/content/zh-cn/overview/mannual/java-sdk/faq/0/7.md deleted file mode 100644 index 03ce13cd899a..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/0/7.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/0/7/ - - /zh-cn/docs3-v2/java-sdk/faq/0/7/ -description: 0-7 - 未找到反射类 -linkTitle: 0-7 - 未找到反射类 -title: 0-7 - 未找到反射类 -type: docs -weight: 7 ---- - - - - - - - -### 可能的原因 - -1. 一般是 `Class.forName(className)` 执行此方法时,找不到 `className` 当前类。 -2. 业务代码上显示排除了当前 `className` 类,导致加载时未找到。 - -### 排查和解决步骤 - -1. 检查 `Class.forName(className)` 中,`className` 是否存在。 -2. 排查业务代码,有没有使用配置或扫描注解 `exclude` 排除了一些类或包。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/0/8.md b/content/zh-cn/overview/mannual/java-sdk/faq/0/8.md deleted file mode 100644 index 3ab457b2caa8..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/0/8.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/0/8/ - - /zh-cn/docs3-v2/java-sdk/faq/0/8/ -description: 0-8 - 反射失败 -linkTitle: 0-8 - 反射失败 -title: 0-8 - 反射失败 -type: docs -weight: 8 ---- - - - - - - - -### 可能的原因 - -在反射调用某方法时,未对当前方法设置正确的参数类型值,也就是参数类型不匹配。 - -### 排查和解决步骤 - -检查是否存在未正确设置相匹配的类型值。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/0/9.md b/content/zh-cn/overview/mannual/java-sdk/faq/0/9.md deleted file mode 100644 index 3c8891ba9cbe..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/0/9.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/0/9/ - - /zh-cn/docs3-v2/java-sdk/faq/0/9/ -description: 0-9 - 通知事件失败 -linkTitle: 0-9 - 通知事件失败 -title: 0-9 - 通知事件失败 -type: docs -weight: 9 ---- - - - - - - - -### 可能的原因 - -自定义的监听器,在处理上产生了运行时异常。 - -### 排查和解决步骤 - -检查实现 `org.apache.dubbo.rpc.ExporterListener` 接口的业务类,实现方法可能存在代码逻辑错误。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/0/99.md b/content/zh-cn/overview/mannual/java-sdk/faq/0/99.md deleted file mode 100644 index b5d0b5ac1899..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/0/99.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/0/99/ - - /zh-cn/docs3-v2/java-sdk/faq/0/99/ -description: 0-99 - 调用了过时 (Deprecated) 的方法 -linkTitle: 0-99 - 调用了过时 (Deprecated) 的方法 -title: 0-99 - 调用了过时 (Deprecated) 的方法 -type: docs -weight: 99 ---- - - - - - - -### 可能的原因 - -用户调用了过时 (Deprecated) 的方法。 - -### 排查和解决步骤 - -检查用户代码有没有调用了什么在目前所用的版本声明为 @Deprecated 的方法,如果有则按照其对应方法替代,如无则忽略即可。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/0/_index.md b/content/zh-cn/overview/mannual/java-sdk/faq/0/_index.md deleted file mode 100644 index 98d5762eb02b..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/0/_index.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/0/ - - /zh-cn/docs3-v2/java-sdk/faq/0/ -description: 0 - Common 层 -linkTitle: 0 - Common 层 -title: 0 - Common 层 -type: docs -weight: 1 ---- - - - - - - -这里主要是用于表示各个层通用的组件上所发生的错误。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/1/1.md b/content/zh-cn/overview/mannual/java-sdk/faq/1/1.md deleted file mode 100644 index 97310820fa0f..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/1/1.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/1/1/ - - /zh-cn/docs3-v2/java-sdk/faq/1/1/ -description: 1-1 - 地址非法 -linkTitle: 1-1 - 地址非法 -title: 1-1 - 地址非法 -type: docs -weight: 1 ---- - - - - - - -此日志可以忽略,服务版本或分组不匹配。仅出现在 zookeeper 注册中心中,在 3.1.7 版本中已经取消此检查。 - -### 可能的原因 -1. Provider 端配置的 `service.group` 和 Consumer 端配置的 `reference.group` (即服务分组的配置)不匹配。 -2. Provider 端配置的 `service.version` 和 Consumer 端配置的 `reference.version` (即服务版本的配置)不匹配。 - -### 排查和解决步骤 -可以忽略,在 3.1.7 版本中已经取消此检查。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/1/10.md b/content/zh-cn/overview/mannual/java-sdk/faq/1/10.md deleted file mode 100644 index 9207c2f1f847..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/1/10.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/1/10/ - - /zh-cn/docs3-v2/java-sdk/faq/1/10/ -description: 1-10 - 读写注册中心服务缓存失败 -linkTitle: 1-10 - 读写注册中心服务缓存失败 -title: 1-10 - 读写注册中心服务缓存失败 -type: docs -weight: 10 ---- - - - - - - -### 可能的原因 -1. 多个 Dubbo 进程使用了同一个缓存文件。 -2. 在多注册中心的情况下,指定了多个注册中心使用同一文件存储。 - -### 排查和解决步骤 -该错误常与 1-9 错误共同出现。检查是否有多个 Dubbo 进程使用了同一个缓存文件或者是否指定多个注册中心使用同一缓存文件。 - -> 另请参阅 -[注册中心的配置项参考手册](/zh-cn/overview/mannual/java-sdk/reference-manual/config/properties/#registry) \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/1/11.md b/content/zh-cn/overview/mannual/java-sdk/faq/1/11.md deleted file mode 100644 index f1551d976e68..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/1/11.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/1/11/ - - /zh-cn/docs3-v2/java-sdk/faq/1/11/ -description: 1-11 - 注册服务实例创建失败 -linkTitle: 1-11 - 注册服务实例创建失败 -title: 1-11 - 注册服务实例创建失败 -type: docs -weight: 11 ---- - - - - - - -### 可能的原因 -可能是 Registry 的 SPI/IOC 配置出错导致。 -### 排查和解决步骤 -该错误为 Dubbo 内部错误,如果您遇到可以在 github 创建 Issue 并提供错误信息以及复现步骤,我们将协助您解决问题。 - -> 另请参阅 -[Dubbo社区](https://github.com/apache/dubbo) \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/1/12.md b/content/zh-cn/overview/mannual/java-sdk/faq/1/12.md deleted file mode 100644 index 777fb5622f95..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/1/12.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/1/12/ - - /zh-cn/docs3-v2/java-sdk/faq/1/12/ -description: 1-12 - “注册服务” 的实例均已销毁 -linkTitle: 1-12 - “注册服务” 的实例均已销毁 -title: 1-12 - “注册服务” 的实例均已销毁 -type: docs -weight: 12 ---- - - - - - - -### 可能的原因 -在 Dubbo 优雅停机的过程中,通过调用 `AbstractRegistryFactory` 的 `destroyAll` 进行解注册。 - -销毁 `Registryprotocol` 的 `unexport` 的过程中,会通过 `AbstractRegistryFactory` 的 `getRegistry` 来试图获得已经被销毁的 registry ,这导致了 “注册服务” 的实例均已销毁。 - -### 排查和解决步骤 -> 另请参阅 -[配置项参考手册](../../../reference-manual/config/properties) \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/1/13.md b/content/zh-cn/overview/mannual/java-sdk/faq/1/13.md deleted file mode 100644 index 548db3f41bd8..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/1/13.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/1/13/ - - /zh-cn/docs3-v2/java-sdk/faq/1/13/ -description: 1-13 - 执行重试任务失败 -linkTitle: 1-13 - 执行重试任务失败 -title: 1-13 - 执行重试任务失败 -type: docs -weight: 13 ---- - - - - - - -### 可能的原因 -1. 注册中心离线。 - -### 排查和解决步骤 - -1. 检查注册中心是否正常工作。 -2. 检查注册中心所在服务器及其网络是否正常工作。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/1/14.md b/content/zh-cn/overview/mannual/java-sdk/faq/1/14.md deleted file mode 100644 index e2d997269ead..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/1/14.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/1/14/ - - /zh-cn/docs3-v2/java-sdk/faq/1/14/ -description: 1-14 - 动态配置识别失败 -linkTitle: 1-14 - 动态配置识别失败 -title: 1-14 - 动态配置识别失败 -type: docs -weight: 14 ---- - - - - - - -### 可能的原因 - 在使用 dubbo admin 的服务治理功能进行动态配置时,配置文件的内容或者格式不正确会导致无法解析动态配置的内容,产生 1-14 错误。 -### 排查和解决步骤 - 请检查动态配置文件的内容或者格式是否正确。 - - -### 另请参阅 -> [配置项参考手册](../../../reference-manual/config/properties) \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/1/15.md b/content/zh-cn/overview/mannual/java-sdk/faq/1/15.md deleted file mode 100644 index 1840cfc3c3ba..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/1/15.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/1/15/ - - /zh-cn/docs3-v2/java-sdk/faq/1/15/ -description: 1-15 - 销毁服务失败 -linkTitle: 1-15 - 销毁服务失败 -title: 1-15 - 销毁服务失败 -type: docs -weight: 15 ---- - - - - - - -### 可能的原因 - 在 RegistryDirectory 中销毁所有的 invoker 时抛出异常则可能触发 1-15 错误。 - -### 排查和解决步骤 -该错误为 Dubbo 内部错误,如果您遇到可以在 github 创建 Issue 并提供错误信息以及复现步骤,我们将协助您解决问题。 - - -> 另请参阅 [Dubbo 社区](https://github.com/apache/dubbo) \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/1/16.md b/content/zh-cn/overview/mannual/java-sdk/faq/1/16.md deleted file mode 100644 index 00edaa94c7b4..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/1/16.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/1/16/ - - /zh-cn/docs3-v2/java-sdk/faq/1/16/ -description: 1-16 - 存在不支持的类别 -linkTitle: 1-16 - 存在不支持的类别 -title: 1-16 - 存在不支持的类别 -type: docs -weight: 16 ---- - - - - - - -### 可能的原因 - 当注册中心的发生变化时,会 notify 对应的 listener。在 notify 的时候如果 category 非法,则会产生存在不支持的类别。 - - -### 排查和解决步骤 - 该错误为 Dubbo 内部错误,如果您遇到可以在 github 创建 Issue 并提供错误信息以及复现步骤,我们将协助您解决问题。 - - -> 另请参阅 -[Dubbo社区](https://github.com/apache/dubbo) \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/1/17.md b/content/zh-cn/overview/mannual/java-sdk/faq/1/17.md deleted file mode 100644 index a27e63fece33..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/1/17.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/1/17/ - - /zh-cn/docs3-v2/java-sdk/faq/1/17/ -description: 1-17 - metadata Server 失效 -linkTitle: 1-17 - metadata Server 失效 -title: 1-17 - metadata Server 失效 -type: docs -weight: 17 ---- - - - - - - -### 可能的原因 -可能是 metadata 的相关参数配置出现问题,特别是 `metadataServiceProtocol` 和 `metadataServicePort`. - -### 排查和解决步骤 -1. 查看是否和未提供 metadata service 端口同时出现,如果同时出现优先尝试解决未提供 metadata service 端口。**(1-18 FAQ)** -2. 排查 `metadataServicePort` 端口号是否存在冲突问题。Provider 和 Consumer 所配置端口同时存在冲突,会产生 metadata Server 失效。 - -> 另请参阅 -[配置项参考手册](../../../reference-manual/config/properties) \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/1/18.md b/content/zh-cn/overview/mannual/java-sdk/faq/1/18.md deleted file mode 100644 index 48dabcc7edb9..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/1/18.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/1/18/ - - /zh-cn/docs3-v2/java-sdk/faq/1/18/ -description: 1-18 - 未提供 metadata service 端口 -linkTitle: 1-18 - 未提供 metadata service 端口 -title: 1-18 - 未提供 metadata service 端口 -type: docs -weight: 18 ---- - - - - - - -### 可能的原因 -可能是由于`metadataType`为 local 模式,且 `metadataServicePort` 配置出错。 - -### 排查和解决步骤 -1.检查 Provider 侧的 `metadataType` 属性值。 -2.检查 Provider 侧的 `metadataServicePort` 配置是否正确,特别注意是否和其他应用端口存在冲突。 - -> 另请参阅 -[配置项参考手册](../../../reference-manual/config/properties) \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/1/19.md b/content/zh-cn/overview/mannual/java-sdk/faq/1/19.md deleted file mode 100644 index 5da43438abbe..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/1/19.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/1/19/ - - /zh-cn/docs3-v2/java-sdk/faq/1/19/ -description: 1-19 - K8S监听异常 -linkTitle: 1-19 - K8S监听异常 -title: 1-19 - K8S监听异常 -type: docs -weight: 19 ---- - - - - - - -### 可能的原因 - -1. K8S 自定义的资源类型,配置被修改或已被容器移除。 -2. K8S 容器与服务已断开连接。 - -### 排查和解决步骤 - -1. 检查自定义的资源类型,配置是否正确。语法或可请参考 K8S 的官方文档。 -2. 检查网络是否正常或端口映射是否正确。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/1/20.md b/content/zh-cn/overview/mannual/java-sdk/faq/1/20.md deleted file mode 100644 index e277b4b99309..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/1/20.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/1/20/ - - /zh-cn/docs3-v2/java-sdk/faq/1/20/ -description: 1-20 - K8S Pod不存在 -linkTitle: 1-20 - K8S Pod不存在 -title: 1-20 - K8S Pod不存在 -type: docs -weight: 20 ---- - - - - - - -### 可能的原因 -1. 控制器 Pending -2. Pod 可能不存在或已被容器移除。 - -### 排查和解决步骤 - -可通过一些第三方的工具或者 `jstack [PID] > jstack.log` 分析堆栈信息,进行定位。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/1/21.md b/content/zh-cn/overview/mannual/java-sdk/faq/1/21.md deleted file mode 100644 index ce14e8335295..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/1/21.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/1/21/ - - /zh-cn/docs3-v2/java-sdk/faq/1/21/ -description: 1-21 - K8S 无可用服务 -linkTitle: 1-21 - K8S 无可用服务 -title: 1-21 - K8S 无可用服务 -type: docs -weight: 21 ---- - - - - - - -### 可能的原因 - -1. 当前服务未正确加载。 -2. 配置的Pod确实不存在当前实例服务。 - -### 排查和解决步骤 - -可通过一些第三方的工具或者 `jstack [PID] > jstack.log` 分析堆栈信息,进行定位。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/1/22.md b/content/zh-cn/overview/mannual/java-sdk/faq/1/22.md deleted file mode 100644 index d696a0cc75e7..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/1/22.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/1/22/ - - /zh-cn/docs3-v2/java-sdk/faq/1/22/ -description: 1-22 - K8S 配置地址错误 -linkTitle: 1-22 - K8S 配置地址错误 -title: 1-22 - K8S 配置地址错误 -type: docs -weight: 22 ---- - - - - - - -### 可能的原因 - -K8S url 配置错误,无法正常访问。 - -### 排查和解决步骤 - -检查 K8S url 配置信息,确保端口映射也可正常访问。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/1/26.md b/content/zh-cn/overview/mannual/java-sdk/faq/1/26.md deleted file mode 100644 index 784bd57ba969..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/1/26.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/1/26/ - - /zh-cn/docs3-v2/java-sdk/faq/1/26/ -description: 1-26 - xDS 证书生成失败 -linkTitle: 1-26 - xDS 证书生成失败 -title: 1-26 - xDS 证书生成失败 -type: docs -weight: 26 ---- - - - - - - -### 可能的原因 - -系统可能不支持算法 `secp256r1` 和 `RSA` 生成证书。 - -### 排查和解决步骤 - -检测操作系统是否支持 `secp256r1` 和 `RSA` 算法。需下载对于的 dll 文件或 lib \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/1/27.md b/content/zh-cn/overview/mannual/java-sdk/faq/1/27.md deleted file mode 100644 index 5a7e09846e72..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/1/27.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/1/27/ - - /zh-cn/docs3-v2/java-sdk/faq/1/27/ -description: 1-27 - K8S监听异常 -linkTitle: 1-27 - K8S监听异常 -title: 1-27 - K8S监听异常 -type: docs -weight: 27 ---- - - - - - - -### 可能的原因 - -系统可能不支持算法 `secp256r1` 和 `RSA` 生成证书。 - -### 排查和解决步骤 - -检测操作系统是否支持 `secp256r1` 和 `RSA` 算法。需下载对于的 dll 文件或 lib \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/1/28.md b/content/zh-cn/overview/mannual/java-sdk/faq/1/28.md deleted file mode 100644 index 65c834c3afab..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/1/28.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/1/28/ - - /zh-cn/docs3-v2/java-sdk/faq/1/28/ -description: 1-28 - xDS 存根错误 -linkTitle: 1-28 - xDS 存根错误 -title: 1-28 - xDS 存根错误 -type: docs -weight: 28 ---- - - - - - - -### 可能的原因 - -当前 pod 或已宕机。 - -### 排查和解决步骤 - -可通过一些第三方的工具或者 `jstack [PID] > jstack.log` 分析堆栈信息,进行定位。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/1/29.md b/content/zh-cn/overview/mannual/java-sdk/faq/1/29.md deleted file mode 100644 index b2412c390bbe..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/1/29.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/1/29/ - - /zh-cn/docs3-v2/java-sdk/faq/1/29/ -description: 1-29 - xDS 读取文件失败 -linkTitle: 1-29 - xDS 读取文件失败 -title: 1-29 - xDS 读取文件失败 -type: docs -weight: 29 ---- - - - - - - -### 可能的原因 - -网络断开或目标文件此时已损坏。 - -### 排查和解决步骤 - -1. 网络是否正常。 -2. 可通过一些第三方的工具或者 `jstack [PID] > jstack.log` 分析堆栈信息,进行定位。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/1/3.md b/content/zh-cn/overview/mannual/java-sdk/faq/1/3.md deleted file mode 100644 index 93256f75d074..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/1/3.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/1/3/ - - /zh-cn/docs3-v2/java-sdk/faq/1/3/ -description: 1-3 - URL 销毁失败 -linkTitle: 1-3 - URL 销毁失败 -title: 1-3 - URL 销毁失败 -type: docs -weight: 3 ---- - - - - - - -### 可能的原因 -当`FrameworkExecutorRepository`被销毁以后,调用`CacheableFailbackRegistry.evictURLCache`会导致销毁失败,产生错误码。 - -### 排查和解决步骤 - -> 另请参阅 [配置项参考手册](../../../reference-manual/config/properties) \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/1/30.md b/content/zh-cn/overview/mannual/java-sdk/faq/1/30.md deleted file mode 100644 index 19fc528b375f..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/1/30.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/1/30/ - - /zh-cn/docs3-v2/java-sdk/faq/1/30/ -description: 1-30 - xDS 请求失败 -linkTitle: 1-30 - xDS 请求失败 -title: 1-30 - xDS 请求失败 -type: docs -weight: 30 ---- - - - - - - -### 可能的原因 - -1. 版本可能不一致或不兼容。 -2. 读取数据时超时。 -3. 参数配置有问题。 - -### 排查和解决步骤 - -1. 可根据第三方官网介绍进行适配。 -2. 确认是否是超时时间设置过短或服务端存在问题。 -3. 检测端口的映射关系是否正确。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/1/31.md b/content/zh-cn/overview/mannual/java-sdk/faq/1/31.md deleted file mode 100644 index fb97b9a9a2e5..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/1/31.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/1/31/ - - /zh-cn/docs3-v2/java-sdk/faq/1/31/ -description: 1-31 - xDS 响应失败 -linkTitle: 1-31 - xDS 响应失败 -title: 1-31 - xDS 响应失败 -type: docs -weight: 31 ---- - - - - - - -### 可能的原因 - -1. 客户端服务已断开与服务端的连接。 -2. 服务端不可用或已脱机。 - -### 排查和解决步骤 - -1. 排查服务端是否已脱机或客户端的网络断开。 -2. 排查服务端服务是否正常,并可通过网络进行接口请求。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/1/32.md b/content/zh-cn/overview/mannual/java-sdk/faq/1/32.md deleted file mode 100644 index 6f0cb93dca90..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/1/32.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/1/32/ - - /zh-cn/docs3-v2/java-sdk/faq/1/32/ -description: 1-32 - xDS Channel 初始化失败 -linkTitle: 1-32 - xDS Channel 初始化失败 -title: 1-32 - xDS Channel 初始化失败 -type: docs -weight: 32 ---- - - - - - - -### 可能的原因 - -1. 版本可能不一致或不兼容。 -2. 读取数据时超时。 -3. 参数配置有问题。 - -### 排查和解决步骤 - -1. 可根据第三方官网介绍进行适配。 -2. 确认是否是超时时间设置过短或服务端存在问题。 -3. 检测端口的映射关系是否正确。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/1/33.md b/content/zh-cn/overview/mannual/java-sdk/faq/1/33.md deleted file mode 100644 index 1270b0302a01..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/1/33.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/1/33/ - - /zh-cn/docs3-v2/java-sdk/faq/1/33/ -description: 1-33 - xDS 服务发现初始化失败 -linkTitle: 1-33 - xDS 服务发现初始化失败 -title: 1-33 - xDS 服务发现初始化失败 -type: docs -weight: 33 ---- - - - - - - -### 可能的原因 - -1. xDS 模式下的注册中心,地址配置错误。 -2. 防火墙及第三方防护软件,导致无法对外提供连接。 - -### 排查和解决步骤 - -1. 检查 xDS 配置是否正确,检查 Istio 状态是否正常。 -2. 检查防火墙配置或使用 cmd 的 `ping` 命令进行基本检测。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/1/34.md b/content/zh-cn/overview/mannual/java-sdk/faq/1/34.md deleted file mode 100644 index 3bf15a4d8d4a..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/1/34.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/1/34/ - - /zh-cn/docs3-v2/java-sdk/faq/1/34/ -description: 1-34 - xDS 解析发生错误 -linkTitle: 1-34 - xDS 解析发生错误 -title: 1-34 - xDS 解析发生错误 -type: docs -weight: 34 ---- - - - - - - -### 可能的原因 - -xDS 协议内容存在错误。 - -### 排查和解决步骤 - -可根据堆栈打印的 Endpoints List 进行原因定位。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/1/35.md b/content/zh-cn/overview/mannual/java-sdk/faq/1/35.md deleted file mode 100644 index b916e33f6288..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/1/35.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/1/35/ - - /zh-cn/docs3-v2/java-sdk/faq/1/35/ -description: 1-35 - ZK 异常 -linkTitle: 1-35 - ZK 异常 -title: 1-35 - ZK 异常 -type: docs -weight: 35 ---- - - - - - - -### 可能的原因 - -1. ZK 无法连接里或连接超时。 -2. ZNode 在创建时已存在。 - -### 排查和解决步骤 - -1. 检查 ZK 配置 IP 和 端口号是否正确。可使用第三方工具 ZooInspector 进行连接测试。 -2. 根据堆栈提醒 ZNode 信息进行判断,是否可清理当前节点。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/1/36.md b/content/zh-cn/overview/mannual/java-sdk/faq/1/36.md deleted file mode 100644 index d16af12813e3..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/1/36.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/1/36/ - - /zh-cn/docs3-v2/java-sdk/faq/1/36/ -description: 1-36 - 未知异常 -linkTitle: 1-36 - 未知异常 -title: 1-36 - 未知异常 -type: docs -weight: 36 ---- - - - - - - -### 可能的原因 -该错误码的意义已经调整。对于 Dubbo 3.1.4、3.2.0-beta.3 及其之前的版本的该错误码的出错,请参考错误码 [99-0](/zh-cn/overview/mannual/java-sdk/faq/99/0/)。 - -### 排查和解决步骤 -(该错误码目前空缺) \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/1/37.md b/content/zh-cn/overview/mannual/java-sdk/faq/1/37.md deleted file mode 100644 index 2c7092d61192..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/1/37.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/1/37/ - - /zh-cn/docs3-v2/java-sdk/faq/1/37/ -description: 1-37 - Nacos 异常 -linkTitle: 1-37 - Nacos 异常 -title: 1-37 - Nacos 异常 -type: docs -weight: 37 ---- - - - - - - -### 可能的原因 - -Nacos 配置信息未正确配置。 - -### 排查和解决步骤 - -检查配置 Nacos 的 ip 和端口号是否正确,如果开启了 Nacos 的安全认证,检查用户名和密码配置是否正确。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/1/38.md b/content/zh-cn/overview/mannual/java-sdk/faq/1/38.md deleted file mode 100644 index 43751051f8fb..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/1/38.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/1/38/ - - /zh-cn/docs3-v2/java-sdk/faq/1/38/ -description: 1-38 - Socket 连接异常 -linkTitle: 1-38 - Socket 连接异常 -title: 1-38 - Socket 连接异常 -type: docs -weight: 38 ---- - - - - - - -### 可能的原因 - -1. 连接被拒绝。 -2. 连接已经关闭。 - -### 排查和解决步骤 - -可通过一些第三方的工具或者 `jstack [PID] > jstack.log` 分析堆栈信息,进行定位。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/1/39.md b/content/zh-cn/overview/mannual/java-sdk/faq/1/39.md deleted file mode 100644 index ef96e0d452eb..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/1/39.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/1/39/ - - /zh-cn/docs3-v2/java-sdk/faq/1/39/ -description: 1-39 - 获取元数据失败 -linkTitle: 1-39 - 获取元数据失败 -title: 1-39 - 获取元数据失败 -type: docs -weight: 39 ---- - - - - - - -### 可能的原因 - -1. 元数据中心已与应用服务断开连接。 -2. 元数据中心的数据或已被修改。 - -### 排查和解决步骤 - -1. 检查网络通信是否正常,可使用一些简单的 cmd 命令进行检测,如 `ping` 等。 -2. 通过第三方工具进行连接,以及内容的查看。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/1/4.md b/content/zh-cn/overview/mannual/java-sdk/faq/1/4.md deleted file mode 100644 index d0e67f24f241..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/1/4.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/1/4/ - - /zh-cn/docs3-v2/java-sdk/faq/1/4/ -description: 1-4 - 空地址 -linkTitle: 1-4 - 空地址 -title: 1-4 - 空地址 -type: docs -weight: 4 ---- - - - - - - -### 可能的原因 -1. registry.integration.RegistryDirectory 中的1-4错误是refreshInvoker过程中invokerUrls为空导致的,可以忽略。 -2. registry.support.CacheableFailbackRegistry 中的1-4错误可能是consumer和provider不匹配,并且关闭了“空保护”所导致。 - -### 排查和解决步骤 -1. 确保 Provider 和 Consumer 端的服务分组配置相对应。 -2. 确保 Provider 和 Consumer 端的服务版本配置相对应。 -3. 检查注册中心的`enable-empty-protection`是否为true(默认为true)。 - -> 另请参阅 -[配置项参考手册](../../../reference-manual/config/properties) \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/1/40.md b/content/zh-cn/overview/mannual/java-sdk/faq/1/40.md deleted file mode 100644 index e85e570b273a..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/1/40.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/1/40/ - - /zh-cn/docs3-v2/java-sdk/faq/1/40/ -description: 1-40 - 路由等待时间过长 -linkTitle: 1-40 - 路由等待时间过长 -title: 1-40 - 路由等待时间过长 -type: docs -weight: 40 ---- - - - - - - -### 可能的原因 - -路由计算的时间过长,导致地址通知无法等待到一个合适的时间进行地址更新。 - -### 排查和解决步骤 - -1. 检查应用 QPS,如果 QPS 非常高,这个是预期的日志 -2. 检查自定义路由的实现,排查是否有异常实现,例如死锁、死循环等 -3. 可通过一些第三方的工具或者 `jstack [PID] > jstack.log` 分析堆栈信息,进行定位。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/1/41.md b/content/zh-cn/overview/mannual/java-sdk/faq/1/41.md deleted file mode 100644 index 3bbf65b57ba7..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/1/41.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/1/41/ - - /zh-cn/docs3-v2/java-sdk/faq/1/41/ -description: 1-41 - Istio 异常 -linkTitle: 1-41 - Istio 异常 -title: 1-41 - Istio 异常 -type: docs -weight: 41 ---- - - - - - - -### 可能的原因 - -获取 istio 的配置文件失败 - -### 排查和解决步骤 - -检查应用是否部署在 Kubernetes Pod 环境中,目前暂不支持 VM 部署。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/1/42.md b/content/zh-cn/overview/mannual/java-sdk/faq/1/42.md deleted file mode 100644 index 9a8e74000ded..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/1/42.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/1/42/ - - /zh-cn/docs3-v2/java-sdk/faq/1/42/ -description: 1-42 - Nacos 存在低版本服务 -linkTitle: 1-42 - Nacos 存在低版本服务 -title: 1-42 - Nacos 存在低版本服务 -type: docs -weight: 42 ---- - -### 可能的原因 - -Nacos 注册中心订阅到了老版本的服务,通常是服务端 Dubbo 版本低于 2.7.3 导致的。 - -### 排查和解决步骤 - -升级服务端到最新稳定版本。 diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/1/5.md b/content/zh-cn/overview/mannual/java-sdk/faq/1/5.md deleted file mode 100644 index 5f447e91d6d6..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/1/5.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/1/5/ - - /zh-cn/docs3-v2/java-sdk/faq/1/5/ -description: 1-5 - 接收到没有任何参数的 URL -linkTitle: 1-5 - 接收到没有任何参数的 URL -title: 1-5 - 接收到没有任何参数的 URL -type: docs -weight: 5 ---- - - - - - - -### 可能的原因 -在调用 `CacheableFailbackRegistry.toUrlsWithoutEmpty` 时,若传入的参数 `Collectionproviders` 中存在某个 provider 其没有任何参数的话,就会接收到没有任何参数的 URL。 -### 排查和解决步骤 -该错误为 Dubbo 内部错误,如果您遇到可以在 github 创建 Issue 并提供错误信息以及复现步骤,我们将协助您解决问题。 - -> 另请参阅 -[Dubbo社区](https://github.com/apache/dubbo) \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/1/6.md b/content/zh-cn/overview/mannual/java-sdk/faq/1/6.md deleted file mode 100644 index 44de6725a912..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/1/6.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/1/6/ - - /zh-cn/docs3-v2/java-sdk/faq/1/6/ -description: 1-6 - 清空URL缓存出错 -linkTitle: 1-6 - 清空URL缓存出错 -title: 1-6 - 清空URL缓存出错 -type: docs -weight: 6 ---- - - - - - - -### 可能的原因 -在`CacheableFailbackRegistry.RemovalTask`清空 url 缓存时候出错将会触发清空 URL 缓存出错。 - -### 排查和解决步骤 -该错误为 Dubbo 内部错误,如果您遇到可以在 github 创建 **issues** 并提供错误信息以及复现步骤,我们将协助您解决问题。 - -> 另请参阅 -[Dubbo社区](https://github.com/apache/dubbo) \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/1/7.md b/content/zh-cn/overview/mannual/java-sdk/faq/1/7.md deleted file mode 100644 index d7593c97fe7a..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/1/7.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/1/7/ - - /zh-cn/docs3-v2/java-sdk/faq/1/7/ -description: 1-7 - 通知注册事件失败 -linkTitle: 1-7 - 读写注册中心服务缓存失败 -title: 1-7 - 通知注册事件失败 -type: docs -weight: 7 ---- - - - - - - -### 可能的原因 - -1. 在应用于基于 xDS 协议的相关平台时,在更新元数据时,需要通知 consumer ,如果某个 consumer 离线会导致通知失败,并移除对应 consumer 的 listener。 - -### 排查和解决步骤 - -> 另请参阅 -[注册中心-配置项参考手册](/zh-cn/overview/mannual/java-sdk/reference-manual/config/properties/#registry) \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/1/8.md b/content/zh-cn/overview/mannual/java-sdk/faq/1/8.md deleted file mode 100644 index 4bda34865f4e..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/1/8.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/1/8/ - - /zh-cn/docs3-v2/java-sdk/faq/1/8/ -description: 1-8 - 销毁时注销(取消订阅)地址失败 -linkTitle: 1-8 - 销毁时注销(取消订阅)地址失败 -title: 1-8 - 销毁时注销(取消订阅)地址失败 -type: docs -weight: 8 ---- - - - - - - -### 可能的原因 -1. 可能是注册中心宕机导致造成的消费者注销或者取消订阅时出现错误。 -2. 可能是对应的 provider 未能成功发布。 - -### 排查和解决步骤 -1. 排查注册中心是否在正常运行。 -2. 排查 provider 是否成功发布。 -3. 排查 provider 的注册中心相关参数比如 `registry` `config-center` `metadata-report`是否配置正确。 - -> 另请参阅 -[配置项参考手册](../../../reference-manual/config/properties) \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/1/9.md b/content/zh-cn/overview/mannual/java-sdk/faq/1/9.md deleted file mode 100644 index 30503ce44ae1..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/1/9.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/1/9/ - - /zh-cn/docs3-v2/java-sdk/faq/1/9/ -description: 1-9 - 读写注册中心服务缓存失败 -linkTitle: 1-9 - 读写注册中心服务缓存失败 -title: 1-9 - 读写注册中心服务缓存失败 -type: docs -weight: 9 ---- - - - - - - -### 可能的原因 -1. 多个 Dubbo 进程(或其他 Java 进程)使用了同一个缓存文件。 -2. 由于缓存文件所在目录的文件系统权限问题,导致读写失败。 -3. `dubbo.registry.file` 的值输入错误。 -4. 不小心指定了两个注册中心使用同一文件存储。 - -> **提示:** -如未指定 `dubbo.registry.file`,则注册中心服务缓存路径默认为 `~/.dubbo` 目录 -(其中 `~` 为用户的 HOME 目录) - -### 排查和解决步骤 -1. 检查 `dubbo.registry.file` 的值有无拼写错误。 -2. 检查是否有其它进程使用了同一份缓存文件。 -3. 如果指定了 `dubbo.registry.file`,那么检查下它在文件系统的权限。 -4. 排查是否出现了“两个注册中心使用了同一文件存储” 这一情况,如果出现则调整。 - -> 另请参阅 -[注册中心的配置项参考手册](/zh-cn/overview/mannual/java-sdk/reference-manual/config/properties/#registry) \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/1/_index.md b/content/zh-cn/overview/mannual/java-sdk/faq/1/_index.md deleted file mode 100755 index 7337794300f1..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/1/_index.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/1/ - - /zh-cn/docs3-v2/java-sdk/faq/1/ -description: 1 - 注册中心层 -linkTitle: 1 - 注册中心层 -title: 1 - 注册中心层 -type: docs -weight: 1 ---- - - - - - - -这里主要是用于表示注册中心层上所发生的错误。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/2/1.md b/content/zh-cn/overview/mannual/java-sdk/faq/2/1.md deleted file mode 100644 index 83f2a6e1ef7b..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/2/1.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/2/1/ - - /zh-cn/docs3-v2/java-sdk/faq/2/1/ -description: 2-1 - 路由选址执行失败 -linkTitle: 2-1 - 路由选址执行失败 -title: 2-1 - 路由选址执行失败 -type: docs -weight: 1 ---- - - - - - - -## 路由选址执行失败 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/2/10.md b/content/zh-cn/overview/mannual/java-sdk/faq/2/10.md deleted file mode 100644 index 10d2b601e466..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/2/10.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/2/10/ - - /zh-cn/docs3-v2/java-sdk/faq/2/10/ -description: 2-10 - 调用服务提供方失败 -linkTitle: 2-10 - 调用服务提供方失败 -title: 2-10 - 调用服务提供方失败 -type: docs -weight: 10 ---- - - - - - - -### 可能的原因 - -* Dubbo 调用服务提供方失败,并开始重试。 -* Dubbo 重试调用服务提供方持续失败。 -* Dubbo 重试调用服务提供方达到上限。 - -### 排查和解决步骤 -1. 检查消费方提供方之间网络连接耗时等网络资源。 -2. 通过 telnet 等手段检查提供方对应端口是否能正常响应。 -3. 检查提供方程序是否运行正常。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/2/11.md b/content/zh-cn/overview/mannual/java-sdk/faq/2/11.md deleted file mode 100644 index f5e56267d989..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/2/11.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/2/11/ - - /zh-cn/docs3-v2/java-sdk/faq/2/11/ -description: 2-11 - 标签路由规则不合法 -linkTitle: 2-11 - 标签路由规则不合法 -title: 2-11 - 标签路由规则不合法 -type: docs -weight: 11 ---- - - - - - - -### 可能的原因 - -* 用户配置的标签路由规则不合法。 -* 用户配置的标签路由地址不合法。 - -### 排查和解决步骤 -> 参照社区标签路由配置规范,检查标签路由配置。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/2/12.md b/content/zh-cn/overview/mannual/java-sdk/faq/2/12.md deleted file mode 100644 index ffd3a9a9b0c4..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/2/12.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/2/12/ - - /zh-cn/docs3-v2/java-sdk/faq/2/12/ -description: 2-12 - 标签路由获取提供方应用名为空 -linkTitle: 2-12 - 标签路由获取提供方应用名为空 -title: 2-12 - 标签路由获取提供方应用名为空 -type: docs -weight: 12 ---- - - - - - - -### 可能的原因 - -* 标签路由从推送提供方地址列表中获取提供方应用名为空。 - -### 排查和解决步骤 -> 该异常为 Dubbo 框架自身异常,请在社区提 Issue ,提供环境现场信息及复现步骤。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/2/13.md b/content/zh-cn/overview/mannual/java-sdk/faq/2/13.md deleted file mode 100644 index ae50a3709be6..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/2/13.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/2/13/ - - /zh-cn/docs3-v2/java-sdk/faq/2/13/ -description: 2-13 - 接收加载mesh的路由规则失败 -linkTitle: 2-13 - 接收加载mesh的路由规则失败 -title: 2-13 - 接收加载mesh的路由规则失败 -type: docs -weight: 13 ---- - - - - - - -### 可能的原因 - -* mesh 路由配置的规则不合法,加载异常。 - -### 排查和解决步骤 -> 检查 mesh 路由规则配置。[mesh示例](/zh-cn/overview/tasks/mesh/)。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/2/14.md b/content/zh-cn/overview/mannual/java-sdk/faq/2/14.md deleted file mode 100644 index 29b4eca5b047..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/2/14.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/2/14/ - - /zh-cn/docs3-v2/java-sdk/faq/2/14/ -description: 2-14 - 脚本路由执行失败 -linkTitle: 2-14 - 脚本路由执行失败 -title: 2-14 - 脚本路由执行失败 -type: docs -weight: 14 ---- - - - - - - -### 可能的原因 - -* 脚本路由规则不合法,导致规则解析失败。 -* Dubbo 框架执行脚本失败。 - -### 排查和解决步骤 -检查脚本是否按照规范编写。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/2/15.md b/content/zh-cn/overview/mannual/java-sdk/faq/2/15.md deleted file mode 100644 index 6ce1c5a1128a..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/2/15.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/2/15/ - - /zh-cn/docs3-v2/java-sdk/faq/2/15/ -description: 2-15 - 路由规则解析失败 -linkTitle: 2-15 - 路由规则解析失败 -title: 2-15 - 路由规则解析失败 -type: docs -weight: 15 ---- - - - - - - -### 可能的原因 - -* 用户配置的路由规则不合法。 - -### 排查和解决步骤 -排查配置的路由规则。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/2/16.md b/content/zh-cn/overview/mannual/java-sdk/faq/2/16.md deleted file mode 100644 index c648e428258a..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/2/16.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/2/16/ - - /zh-cn/docs3-v2/java-sdk/faq/2/16/ -description: 2-16 - 请求重试多次失败 -linkTitle: 2-16 - 请求重试多次失败 -title: 2-16 - 请求重试多次失败 -type: docs -weight: 16 ---- - - - - - - -### 可能的原因 -提供方异常,导致消费方重试多次失败。 - -### 排查和解决步骤 -排查提供方健康状况。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/2/17.md b/content/zh-cn/overview/mannual/java-sdk/faq/2/17.md deleted file mode 100644 index 292bc64053b9..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/2/17.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/2/17/ - - /zh-cn/docs3-v2/java-sdk/faq/2/17/ -description: 2-17 - mock请求失败 -linkTitle: 2-17 - mock请求失败 -title: 2-17 - mock请求失败 -type: docs -weight: 17 ---- - - - - - - -### 可能的原因 -* 配置了强制 mock,提示性日志。 -* 执行 mock 请求异常。 - -### 排查和解决步骤 -1. 检查是否配置了强制 mock。 -2. 检查 mock 响应是否正常。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/2/18.md b/content/zh-cn/overview/mannual/java-sdk/faq/2/18.md deleted file mode 100644 index e114be7187c8..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/2/18.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/2/18/ - - /zh-cn/docs3-v2/java-sdk/faq/2/18/ -description: 2-18 - mesh路由规则未被监听 -linkTitle: 2-18 - mesh路由规则未被监听 -title: 2-18 - mesh路由规则未被监听 -type: docs -weight: 18 ---- - - - - - - -### 可能的原因 - -mesh 下发了路由规则,但是该规则未被监听。 - -### 排查和解决步骤 -检查 mesh 路由规则配置是否符合规范。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/2/19.md b/content/zh-cn/overview/mannual/java-sdk/faq/2/19.md deleted file mode 100644 index 5b43b5afafd3..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/2/19.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/2/19/ - - /zh-cn/docs3-v2/java-sdk/faq/2/19/ -description: 2-19 - 异步请求失败 -linkTitle: 2-19 - 异步请求失败 -title: 2-19 - 异步请求失败 -type: docs -weight: 19 ---- - - - - - - -### 可能的原因 - -1. 提供方异常,导致消费方异步请求失败。 -2. 网络异常,导致消费方异步请求失败。 - -### 排查和解决步骤 -1. 排查提供方健康状况。 -2. 排查网络状况。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/2/2.md b/content/zh-cn/overview/mannual/java-sdk/faq/2/2.md deleted file mode 100644 index 2c0cf3dd11af..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/2/2.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/2/2/ - - /zh-cn/docs3-v2/java-sdk/faq/2/2/ -description: 2-2 - 没有可用的 Provider(地址找不到) -linkTitle: 2-2 - 没有可用的 Provider(地址找不到) -title: 2-2 - 没有可用的 Provider(地址找不到) -type: docs -weight: 2 ---- - - - - - - -### 可能的原因 -* Provider 服务没启动,或者注册中心(比如 ZooKeeper,Nacos,Consul)宕机了。 -* Dubbo 的服务配置有误差,必须保证服务名,组别 (默认是 Dubbo),version 三者都正确。 -* 访问的环境有误:通常我们会有开发环境、测试环境、线上生产环境等多套环境。有时候发布的服务到了测试环境,而访问调用时却走了开发环境。 - -### 排查和解决步骤 -1. 访问注册中心的 Ops 系统,查询对应的服务是否有提供者列表;同时检查调用者应用所在服务器的日志(一般每种注册服务的客户端都会有对应的日志记录),查看是否有地址信息的推送/拉取记录。 -2. 如无,则表明发布者发布服务失败,检查发布者的应用启动是否成功。 -3. 如有服务,则检查调用者应用所连接的注册中心,确认跟预期的环境要匹配。 -4. 如上述都没有问题,检查是否配置了路由过滤的规则等。 - - -> 这个错误码的 FAQ 页面参考了空冥同学的 [《Dubbo 常见错误及解决方法》](https://github.com/StabilityMan/StabilityGuide/blob/master/docs/diagnosis/plugin/rpc/%E7%B3%BB%E7%BB%9F%E7%A8%B3%E5%AE%9A%E6%80%A7%E2%80%94%E2%80%94Dubbo%E5%B8%B8%E8%A7%81%E9%94%99%E8%AF%AF%E5%8F%8A%E8%A7%A3%E5%86%B3%E6%96%B9%E6%B3%95.md) 。 - -> 所引文章通过 [CC-BY-4.0](http://creativecommons.org/licenses/by/4.0/) 协议赋予了汇编的权利。在此向原作者表示感谢。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/2/20.md b/content/zh-cn/overview/mannual/java-sdk/faq/2/20.md deleted file mode 100644 index 8e02922fceec..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/2/20.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/2/20/ - - /zh-cn/docs3-v2/java-sdk/faq/2/20/ -description: 2-20 - 获取分组结果合并时失败 -linkTitle: 2-20 - 获取分组结果合并时失败 -title: 2-20 - 获取分组结果合并时失败 -type: docs -weight: 20 ---- - - - - - - -### 可能的原因 - -获取分组结果合并时失败。 - -### 排查和解决步骤 - -返回结果时,可能出现业务逻辑上的运行时异常,可根据控制台指定的代码行数进行回溯定位。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/2/3.md b/content/zh-cn/overview/mannual/java-sdk/faq/2/3.md deleted file mode 100644 index d0027b536b78..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/2/3.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/2/3/ - - /zh-cn/docs3-v2/java-sdk/faq/2/3/ -description: 2-3 - 路由关闭失败 -linkTitle: 2-3 - 路由关闭失败 -title: 2-3 - 路由关闭失败 -type: docs -weight: 3 ---- - - - - - - -### 可能的原因 - -* 用户自定义路由未按规范编写。 - -### 排查和解决步骤 -> 参照社区SPI扩展使用手册,检查用户自定义路由 [《SPI 扩展使用手册》](/zh-cn/overview/mannual/java-sdk/reference-manual/spi/)。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/2/4.md b/content/zh-cn/overview/mannual/java-sdk/faq/2/4.md deleted file mode 100644 index ef2e95060102..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/2/4.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/2/4/ - - /zh-cn/docs3-v2/java-sdk/faq/2/4/ -description: 2-4 - Merger接口加载失败 -linkTitle: 2-4 - Merger接口加载失败 -title: 2-4 - Merger接口加载失败 -type: docs -weight: 4 ---- - - - - - - -### 可能的原因 - -* Dubbo 提供了聚合下游所有提供方响应的 SPI 扩展 Merger 接口,Dubbo 在加载用户在自定义扩展 Merger 接口时,加载配置失败。 - -### 排查和解决步骤 -> 参照社区 SPI 扩展使用手册,检查用户自定义扩展 Merger 接口实现 [《SPI 扩展使用手册》](/zh-cn/overview/mannual/java-sdk/reference-manual/spi/)。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/2/5.md b/content/zh-cn/overview/mannual/java-sdk/faq/2/5.md deleted file mode 100644 index 6ab4567d838d..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/2/5.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/2/5/ - - /zh-cn/docs3-v2/java-sdk/faq/2/5/ -description: 2-5 - 筛选提供方失败 -linkTitle: 2-5 - 筛选提供方失败 -title: 2-5 - 筛选提供方失败 -type: docs -weight: 5 ---- - - - - - - -### 可能的原因 - -* Dubbo 在负载均衡时会从提供方列表中最终选择一个提供方发起调用,在选择过程中提供方列表变动,发生读写冲突,导致筛选异常。 -* Dubbo 重试机制在调用提供方失败时,会重新筛选另一个提供方发起调用,重新筛选过程发生异常。 - -### 排查和解决步骤 -1. 检查注册中心提供方列表,与对应提供方可用性。 -2. 在社区提 Issue,提供环境现场信息及复现步骤。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/2/6.md b/content/zh-cn/overview/mannual/java-sdk/faq/2/6.md deleted file mode 100644 index cda8f53f558f..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/2/6.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/2/6/ - - /zh-cn/docs3-v2/java-sdk/faq/2/6/ -description: 2-6 - 条件路由筛选提供方列表为空 -linkTitle: 2-6 - 条件路由筛选提供方列表为空 -title: 2-6 - 条件路由筛选提供方列表为空 -type: docs -weight: 6 ---- - - - - - - -### 可能的原因 - -* 条件路由提供方过滤条件为空。 -* 条件路由在强制降级下筛选提供方列表仍为空。 - -### 排查和解决步骤 -> 参照社区请求路由示例,调整条件路由配置。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/2/7.md b/content/zh-cn/overview/mannual/java-sdk/faq/2/7.md deleted file mode 100644 index 2fcda3189e7a..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/2/7.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/2/7/ - - /zh-cn/docs3-v2/java-sdk/faq/2/7/ -description: 2-7 - 条件路由执行异常 -linkTitle: 2-7 - 条件路由执行异常 -title: 2-7 - 条件路由执行异常 -type: docs -weight: 7 ---- - - - - - - -### 可能的原因 - -* 条件路由规则未按照规范配置,导致执行条件路由筛选时执行异常。 - -## 排查和解决步骤 -> 参照社区请求路由示例。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/2/8.md b/content/zh-cn/overview/mannual/java-sdk/faq/2/8.md deleted file mode 100644 index 2f6c7c87fc32..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/2/8.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/2/8/ - - /zh-cn/docs3-v2/java-sdk/faq/2/8/ -description: 2-8 - 提供方返回异常响应 -linkTitle: 2-8 - 提供方返回异常响应 -title: 2-8 - 提供方返回异常响应 -type: docs -weight: 8 ---- - - - - - - -### 可能的原因 - -* 提供方自身处理结果抛出异常。 - -### 排查和解决步骤 - -检查提供方程序是否正常。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/2/9.md b/content/zh-cn/overview/mannual/java-sdk/faq/2/9.md deleted file mode 100644 index d0646bee9051..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/2/9.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/2/9/ - - /zh-cn/docs3-v2/java-sdk/faq/2/9/ -description: 2-9 - 增加超时检查任务失败 -linkTitle: 2-9 - 增加超时检查任务失败 -title: 2-9 - 增加超时检查任务失败 -type: docs -weight: 9 ---- - - - - - - -### 可能的原因 - -* Dubbo 框架会对请求调用增加一个超时检查任务,增加超时检查任务失败。 - -### 排查和解决步骤 -> 该异常为 Dubbo 框架自身异常,请在社区提 Issue ,提供环境现场信息及复现步骤。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/2/_index.md b/content/zh-cn/overview/mannual/java-sdk/faq/2/_index.md deleted file mode 100644 index 85e45b32b744..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/2/_index.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/2/ - - /zh-cn/docs3-v2/java-sdk/faq/2/ -description: 2 - 路由层 -linkTitle: 2 - 路由层 -title: 2 - 路由层 -type: docs -weight: 2 ---- diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/3/1.md b/content/zh-cn/overview/mannual/java-sdk/faq/3/1.md deleted file mode 100644 index fce76233db55..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/3/1.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/3/1/ - - /zh-cn/docs3-v2/java-sdk/faq/3/1/ -description: 3-1 - 将地址转换成 Invoker 失败 -linkTitle: 3-1 - 将地址转换成 Invoker 失败 -title: 3-1 - 将地址转换成 Invoker 失败 -type: docs -weight: 1 ---- - - - - - - -### 可能的原因 - -1. 客户端配置的协议与服务端配置的协议并不匹配。(如客户端配置的协议是 Dubbo 协议,但服务端只能提供 Rest 协议的服务) -2. 注册中心(或配置中心)不可靠,推送了并不合法的数据。 - - - -### 排查和解决步骤 - -1. 检查提供方和消费方双方的协议配置。 -2. 更新注册中心的版本。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/3/2.md b/content/zh-cn/overview/mannual/java-sdk/faq/3/2.md deleted file mode 100644 index f75605ddc79d..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/3/2.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/3/2/ - - /zh-cn/docs3-v2/java-sdk/faq/3/2/ -description: 3-2 - 发布或推送服务失败 -linkTitle: 3-2 - 发布或推送服务失败 -title: 3-2 - 发布或推送服务失败 -type: docs -weight: 2 ---- - - - - - - -### 可能的原因 - -1. 注册中心无法连接。 -2. 注册中心无法对外提供服务。 - -### 排查和解决步骤 - -1. 服务与注册中心网络是否正常。 -2. 注册中心是否正常启动,并可通过第三方工具进行连接。 -3. 服务引用的版本与注册中心的版本是否存在版本兼容性问题。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/3/3.md b/content/zh-cn/overview/mannual/java-sdk/faq/3/3.md deleted file mode 100644 index 701f5ef56be8..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/3/3.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/3/3/ - - /zh-cn/docs3-v2/java-sdk/faq/3/3/ -description: 3-3 - 通过Javassist生成字节码失败 -linkTitle: 3-3 - 通过Javassist生成字节码失败 -title: 3-3 - 通过Javassist生成字节码失败 -type: docs -weight: 3 ---- - - - - - - -### 可能的原因 -该错误码的意义已经调整。对于 Dubbo 3.1.4、3.2.0-beta.3 及其之前的版本的该错误码的出错,请参考错误码 [3-8](/zh-cn/overview/mannual/java-sdk/faq/3/8/)。 - -### 排查和解决步骤 -(该错误码目前空缺) \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/3/4.md b/content/zh-cn/overview/mannual/java-sdk/faq/3/4.md deleted file mode 100644 index 4829c5198fd4..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/3/4.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/3/4/ - - /zh-cn/docs3-v2/java-sdk/faq/3/4/ -description: 3-4 - 客户端发送请求超时 -linkTitle: 3-4 - 客户端发送请求超时 -title: 3-4 - 客户端发送请求超时 -type: docs -weight: 4 ---- - - - - - - -### 可能的原因 - -1. 客户端连接数过高,响应较慢, 无法及时向服务端发出请求。 -2. 网络的一些原因。 - -### 排查和解决步骤 - -1. 网络是否正常。 -2. 可通过一些第三方的工具或者`jstack [PID] > jstack.log` 分析堆栈信息,进行定位。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/3/5.md b/content/zh-cn/overview/mannual/java-sdk/faq/3/5.md deleted file mode 100644 index 42b088ea8acf..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/3/5.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/3/5/ - - /zh-cn/docs3-v2/java-sdk/faq/3/5/ -description: 3-5 - 异步响应出现异常 -linkTitle: 3-5 - 异步响应出现异常 -title: 3-5 - 异步响应出现异常 -type: docs -weight: 5 ---- - - - - - - -### 可能的原因 - -1. 业务逻辑确实出现运行时异常。 -2. 网络原因,连接被拒绝。 - -### 排查和解决步骤 - -1. 业务代码请根据堆栈提示行,回溯定位排查。 -2. 检查服务提供方的网络是否正常。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/3/6.md b/content/zh-cn/overview/mannual/java-sdk/faq/3/6.md deleted file mode 100644 index 27c7391fb734..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/3/6.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/3/6/ - - /zh-cn/docs3-v2/java-sdk/faq/3/6/ -description: 3-6 - 代理执行服务发生异常 -linkTitle: 3-6 - 代理执行服务发生异常 -title: 3-6 - 代理执行服务发生异常 -type: docs -weight: 6 ---- - - - - - - -### 可能的原因 - -1. 当前服务参数已显示入参 `deprecated`。 -2. 泛型声明类可能出现此提醒。 - -### 排查和解决步骤 - -1. 确认URL中是否存在显示入参 `deprecated=true` -2. 泛型声明类如果出现此错误,会试图创建没有实际接口类的代理。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/3/7.md b/content/zh-cn/overview/mannual/java-sdk/faq/3/7.md deleted file mode 100644 index c08548b27d59..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/3/7.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/3/7/ - - /zh-cn/docs3-v2/java-sdk/faq/3/7/ -description: 3-7 - 服务端响应结果超时 -linkTitle: 3-7 - 服务端响应结果超时 -title: 3-7 - 服务端响应结果超时 -type: docs -weight: 7 ---- - - - - - -服务端未在客户端设定的时间内获得响应。 - -### 可能的原因 - -1. 服务端的业务处理逻辑较复杂,无法在有效时间内响应。 -2. 服务端与客户端的连接断开,网络丢包。 -3. 服务端负荷过高。 - -### 排查和解决步骤 - -1. 检查服务端的业务处理能力是否确实存在性能瓶颈。 -2. 网络是否正常。 -3. 可通过一些第三方的工具或者`jstack [PID] > jstack.log` 分析堆栈信息,进行定位。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/3/8.md b/content/zh-cn/overview/mannual/java-sdk/faq/3/8.md deleted file mode 100644 index 78abb67b83c4..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/3/8.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/3/8/ - - /zh-cn/docs3-v2/java-sdk/faq/3/8/ -description: 3-8 - 代理失败 -linkTitle: 3-8 - 代理失败 -title: 3-8 - 代理失败 -type: docs -weight: 8 ---- - - - - - - -生成动态代理失败。 - -### 可能的原因 - -1. 存在动态类加载 -2. 类格式异常 - -### 排查和解决步骤 - -1. 如果日志中提示 `Fallback to use JDK proxy success`, -则意味着 Dubbo 自动回落到 JDK 代理后成功创建动态代理了,如果程序正常运行,则可以忽略 -2. 如果日志中提示 `Fallback to use JDK proxy is also failed`, -请根据异常堆栈信息检查对应的类加载情况是否正常,可以通过 arthas 等工具辅助排查 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/3/_index.md b/content/zh-cn/overview/mannual/java-sdk/faq/3/_index.md deleted file mode 100644 index 5c7a4a1d5fb4..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/3/_index.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/3/ - - /zh-cn/docs3-v2/java-sdk/faq/3/ -description: 3 - 动态代理层 -linkTitle: 3 - 动态代理层 -title: 3 - 动态代理层 -type: docs -weight: 3 ---- diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/4/1.md b/content/zh-cn/overview/mannual/java-sdk/faq/4/1.md deleted file mode 100644 index 71bb9b2d2294..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/4/1.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/4/1/ - - /zh-cn/docs3-v2/java-sdk/faq/4/1/ -description: 4-1 - 不支持的协议 -linkTitle: 4-1 - 不支持的协议 -title: 4-1 - 不支持的协议 -type: docs -weight: 1 ---- - - - - - - -### 可能的原因 -这种情况可能出现在自定义 Protocol 的场景下。Dubbo 的 SPI 机制找不到 URL 中所指定的 Protocol。 - - -### 排查和解决步骤 -1. 确定 Consumer 中有服务端所用到的 Protocol 的依赖。 -2. 确定 Protocol 的依赖包的 SPI 配置文件的名字没有写错。 - -> 另请参阅 -[Dubbo SPI 概述](/zh-cn/overview/mannual/java-sdk/reference-manual/spi/overview/) -[协议扩展说明](/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/protocol/) \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/4/10.md b/content/zh-cn/overview/mannual/java-sdk/faq/4/10.md deleted file mode 100644 index 603679ce1d8a..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/4/10.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/4/10/ - - /zh-cn/docs3-v2/java-sdk/faq/4/10/ -description: 4-10 - Triple 序列化结果失败 -linkTitle: 4-10 - Triple 序列化结果失败 -title: 4-10 - Triple 序列化结果失败 -type: docs -weight: 10 ---- - - - - - - -### 可能的原因 - -一般为内部错误。 -见于三种log格式: -1. 在序列化并且发送数据时发生异常,日志格式为 `Serialize triple request failed, service=%s method=%s` -2. 接收到response的reset code时触发,日志格式为:`Triple Client received remote reset errorCode=xxx` -3. 处理response时有异常情况时触发,日志格式为: `Meet Exception on ClientResponseHandler, status code is:xxx` - -### 排查和解决步骤 - -针对第一种错误,是在调用{service}#{method}方法过程中出现的,具体对应到sendMessage,并且该日志与`java.util.concurrent.ExecutionException: org.apache.dubbo.rpc.StatusRpcException: INTERNAL : Serialize request failed`同时出现,排查{method}方法参数中自定义类是否实现序列化接口导致序列化失败 - -针对第二种错误,是Provider端处理发生错误,排查Provider端服务,排查方式参考第一种错误 - -针对第三种错误,仅单元测试使用到,目前用户侧不会出现 - -其次可通过一些第三方的工具或者 `jstack [PID] > jstack.log` 分析堆栈信息,进行定位。 - -> 同时请在社区提交Issue,帮助我们更好的完善Triple -> 直接点击右上角 **提交项目问题** 按钮即可快速链接至Github页面 diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/4/11.md b/content/zh-cn/overview/mannual/java-sdk/faq/4/11.md deleted file mode 100644 index b1d90b1ebacb..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/4/11.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/4/11/ - - /zh-cn/docs3-v2/java-sdk/faq/4/11/ -description: 4-11 - 发起请求失败 -linkTitle: 4-11 - 发起请求失败 -title: 4-11 - 发起请求失败 -type: docs -weight: 11 ---- - - - - - - -### 可能的原因 - -1. 服务方已关闭。 -2. 调用方的 IP 不在服务方的白名单内。 -3. 请求具体的地址服务不存在。 - -### 排查和解决步骤 - -1. 检查服务方启动运行情况。 -2. 检查或使用第三方工具,测试网络环境是否可正常连接。 -3. 根据堆栈的 serviceName, 在管理平台里查看或模拟调用,看是否正常。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/4/12.md b/content/zh-cn/overview/mannual/java-sdk/faq/4/12.md deleted file mode 100644 index 895aa65f517f..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/4/12.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/4/12/ - - /zh-cn/docs3-v2/java-sdk/faq/4/12/ -description: 4-12 - 创建Triple流失败 -linkTitle: 4-12 - 创建Triple流失败 -title: 4-12 - 创建Triple流失败 -type: docs -weight: 12 ---- - - - - - - -### 可能的原因 - -一般为内部错误。 - -### 排查和解决步骤 - -可通过一些第三方的工具或者 `jstack [PID] > jstack.log` 分析堆栈信息,进行定位。 - -> 同时请在社区提交Issue。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/4/13.md b/content/zh-cn/overview/mannual/java-sdk/faq/4/13.md deleted file mode 100644 index 1fd9e90227fb..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/4/13.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/4/13/ - - /zh-cn/docs3-v2/java-sdk/faq/4/13/ -description: 4-13 - 服务端超时 -linkTitle: 4-13 - 服务端超时 -title: 4-13 - 服务端超时 -type: docs -weight: 13 ---- - - - - - - -### 可能的原因 - -1. 服务端逻辑处理相对耗时。 -2. 服务端负载请求过高,无法响应。 -3. 当前的超时参数设置阈值与现实情况相差较大。 - -### 排查和解决步骤 - -1. 根据接口名称查看是否存在耗时处理情况。 -2. 可监控服务器状态,及服务端调用的服务调用情况。 -3. 尝试将超时参数调大一些。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/4/14.md b/content/zh-cn/overview/mannual/java-sdk/faq/4/14.md deleted file mode 100644 index 60760428a3ea..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/4/14.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/4/14/ - - /zh-cn/docs3-v2/java-sdk/faq/4/14/ -description: 4-14 - 响应结果失败 -linkTitle: 4-14 - 响应结果失败 -title: 4-14 - 响应结果失败 -type: docs -weight: 14 ---- - - - - - - -### 可能的原因 - -1. 服务端管道可能因网络原因暂时断开。 -2. 当前使用版本较低或可检查当前的参数配置,是否启用 `send.reconnect=true`, 高版本默认为 true。 - -### 排查和解决步骤 - -1. 检查直连网络是否通畅,有无丢包现象。 -2. 检查上述参数值,或尝试使用高版本。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/4/15.md b/content/zh-cn/overview/mannual/java-sdk/faq/4/15.md deleted file mode 100644 index 5357c5851c2c..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/4/15.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/4/15/ - - /zh-cn/docs3-v2/java-sdk/faq/4/15/ -description: 4-15 - 客户端流监听器 -linkTitle: 4-15 - 客户端流监听器 -title: 4-15 - 客户端流监听器 -type: docs -weight: 15 ---- - - - - - - -### 可能的原因 - -当收到服务端的响应之后,客户端流监听器会输出此信息,用于提醒。 - -### 排查和解决步骤 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/4/16.md b/content/zh-cn/overview/mannual/java-sdk/faq/4/16.md deleted file mode 100644 index 286e3f1d7cb7..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/4/16.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/4/16/ - - /zh-cn/docs3-v2/java-sdk/faq/4/16/ -description: 4-16 - 服务已关闭 -linkTitle: 4-16 - 服务已关闭 -title: 4-16 - 服务已关闭 -type: docs -weight: 16 ---- - - - - - - -### 可能的原因 - -在错误的状态下继续调用 `org.apache.dubbo.rpc.protocol.tri.service.TriHealthImpl#enterTerminalState` 或者 `org.apache.dubbo.rpc.protocol.ReferenceCountInvokerWrapper#invoke`,在调用时已经是 terminal 或 destory状态。 - -### 排查和解决步骤 - -多次调用上述方法会进行提醒。一般仅用于单元测试。 diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/4/17.md b/content/zh-cn/overview/mannual/java-sdk/faq/4/17.md deleted file mode 100644 index 809a73be20f5..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/4/17.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/4/17/ - - /zh-cn/docs3-v2/java-sdk/faq/4/17/ -description: 4-17 - 关闭所有调用程序时发生错误 -linkTitle: 4-17 - 关闭所有调用程序时发生错误 -title: 4-17 - 关闭所有调用程序时发生错误 -type: docs -weight: 17 ---- - - - - - - -### 可能的原因 - -一般为内部错误。 - -### 排查和解决步骤 - -可通过一些第三方的工具或者 `jstack [PID] > jstack.log` 分析堆栈信息,进行定位。 - -> 同时请在社区提交issue. \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/4/18.md b/content/zh-cn/overview/mannual/java-sdk/faq/4/18.md deleted file mode 100644 index 25e7a169ebd1..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/4/18.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/4/18/ - - /zh-cn/docs3-v2/java-sdk/faq/4/18/ -description: 4-18 - 无法从调用中获取服务模型 -linkTitle: 4-18 - 无法从调用中获取服务模型 -title: 4-18 - 无法从调用中获取服务模型 -type: docs -weight: 18 ---- - - - - - - -### 可能的原因 - -当前仅用于单元测试场景,服务模型默认会进行初始化。 - -### 排查和解决步骤 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/4/19.md b/content/zh-cn/overview/mannual/java-sdk/faq/4/19.md deleted file mode 100644 index 99386cb3cff2..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/4/19.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/4/19/ - - /zh-cn/docs3-v2/java-sdk/faq/4/19/ -description: 4-19 - 参数值有出错的可能 -linkTitle: 4-19 - 参数值有出错的可能 -title: 4-19 - 参数值有出错的可能 -type: docs -weight: 19 ---- - - - - - - -### 可能的原因 -这个错误码提示参数值可能不再正确。 - -目前出现在同一个协议同时监听多个端口下。由于设计限制,单个协议只能监听一个端口,否则端口配置会被覆盖掉。 - -### 排查和解决步骤 -调整协议和端口的监听关系。 - -> 该错误码的意义已经调整。对于 Dubbo 3.1.4、3.2.0-beta.3 及其之前的版本的该错误码的出错,请参考错误码 [0-2](/zh-cn/overview/mannual/java-sdk/faq/0/2/)。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/4/2.md b/content/zh-cn/overview/mannual/java-sdk/faq/4/2.md deleted file mode 100644 index 5092464061a6..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/4/2.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/4/2/ - - /zh-cn/docs3-v2/java-sdk/faq/4/2/ -description: 4-2 - 序列化优化器初始发生错误 -linkTitle: 4-2 - 序列化优化器初始发生错误 -title: 4-2 - 序列化优化器初始发生错误 -type: docs -weight: 2 ---- - - - - - - -### 可能的原因 - -当前使用了 Kryo 和 FST 的序列化配置。 - -### 排查和解决步骤 - -[Kryo 和 FST 序列化](/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/serialization/) \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/4/20.md b/content/zh-cn/overview/mannual/java-sdk/faq/4/20.md deleted file mode 100644 index 105fa19f3010..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/4/20.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/4/20/ - - /zh-cn/docs3-v2/java-sdk/faq/4/20/ -description: 4-20 - 数据解码失败 -linkTitle: 4-20 - 数据解码失败 -title: 4-20 - 数据解码失败 -type: docs -weight: 20 ---- - - - - - - -### 可能的原因 - -只发生在解码阶段,可能服务方和调用方的dubbo版本不匹配。 - -### 排查和解决步骤 - -检查当前使用的 dubbo 版本,尽量保持一致或向下兼容的高版本。 diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/4/21.md b/content/zh-cn/overview/mannual/java-sdk/faq/4/21.md deleted file mode 100644 index c2d206fff16a..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/4/21.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/4/21/ - - /zh-cn/docs3-v2/java-sdk/faq/4/21/ -description: 4-21 - 检测到不安全的序列化数据 -linkTitle: 4-21 - 检测到不安全的序列化数据 -title: 4-21 - 检测到不安全的序列化数据 -type: docs -weight: 21 ---- - - - - - - -### 可能的原因 - -当前服务端可能受到攻击或者是 Dubbo 内置的类检查逻辑没有扫描到您所定义的类。 - -### 排查和解决步骤 - -1. 如果请求源是攻击源,请及时进行安全加固。 -2. 如果请求源是预期的,请在 `security/serialize.allowlist` 资源文件中声明您所使用的类名,Dubbo 将自动将其加载到安全列表中。请参考 [类检查机制](/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/security/class-check/) 一文。 - - -> 当前 Dubbo 可以工作在监控模式和限制模式下。监控模式只打印日志,不进行拦截;限制模型将进行拦截。 diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/4/3.md b/content/zh-cn/overview/mannual/java-sdk/faq/4/3.md deleted file mode 100644 index b1187086455f..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/4/3.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/4/3/ - - /zh-cn/docs3-v2/java-sdk/faq/4/3/ -description: 4-3 - 接口引用调用失败 -linkTitle: 4-3 - 接口引用调用失败 -title: 4-3 - 接口引用调用失败 -type: docs -weight: 3 ---- - - - - - - -### 可能的原因 - -根据指定的协议参数,未找到暴露的服务接口或方法。 - -### 排查和解决步骤 - -可根据接口 URL 及方法名称,确认服务端是否存在。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/4/4.md b/content/zh-cn/overview/mannual/java-sdk/faq/4/4.md deleted file mode 100644 index 47e7e93c6dea..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/4/4.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/4/4/ - - /zh-cn/docs3-v2/java-sdk/faq/4/4/ -description: 4-4 - 非安全序列化方式 -linkTitle: 4-4 - 非安全序列化方式 -title: 4-4 - 非安全序列化方式 -type: docs -weight: 4 ---- - - - - - - -### 可能的原因 - -当前在使用非安全的序列化器, 并不推荐。具体配置为:`serialization="java"` - -> Java 序列化是不安全的。Dubbo 团队不推荐任何人使用它。如果你仍然想使用它,请遵循 [JEP 290](https://openjdk.java.net/jeps/290) 来设置序列化过滤器,以防止反序列化泄露。 - -### 排查和解决步骤 - -修改`serialization`的参数值. 将 protocol 内的序列化参数值修改为其他,如hessian2,fastjson2等。 diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/4/5.md b/content/zh-cn/overview/mannual/java-sdk/faq/4/5.md deleted file mode 100644 index d2f8c70f0991..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/4/5.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/4/5/ - - /zh-cn/docs3-v2/java-sdk/faq/4/5/ -description: 4-5 - 流关闭异常 -linkTitle: 4-5 - 流关闭异常 -title: 4-5 - 流关闭异常 -type: docs -weight: 5 ---- - - - - - - -### 可能的原因 - -提示信息,不影响程序的执行结果。 - -### 排查和解决步骤 - -可通过一些第三方的工具或者`jstack [PID] > jstack.log` 分析堆栈信息,进行定位。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/4/6.md b/content/zh-cn/overview/mannual/java-sdk/faq/4/6.md deleted file mode 100644 index 7edb3622ca88..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/4/6.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/4/6/ - - /zh-cn/docs3-v2/java-sdk/faq/4/6/ -description: 4-6 - 反序列化失败 -linkTitle: 4-6 - 反序列化失败 -title: 4-6 - 反序列化失败 -type: docs -weight: 6 ---- - - - - - - -### 可能的原因 - -发生在使用自定义的序列化方式的时候,在自定义 SPI `org.apache.dubbo.common.serialize.Serialization` 序列化方法在使用时发生错误。 - -### 排查和解决步骤 - -可通过一些第三方的工具或者 `jstack [PID] > jstack.log` 分析堆栈信息,获取引起错误的对象内容,再配合自定义实现进行修改。 - -> 参考 [序列化扩展](https://cn.dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/serialize/) diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/4/7.md b/content/zh-cn/overview/mannual/java-sdk/faq/4/7.md deleted file mode 100644 index a7eb76e9b0b0..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/4/7.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/4/7/ - - /zh-cn/docs3-v2/java-sdk/faq/4/7/ -description: 4-7 - 关闭客户端时发生错误 -linkTitle: 4-7 - 关闭客户端时发生错误 -title: 4-7 - 关闭客户端时发生错误 -type: docs -weight: 7 ---- - - - - - - -### 可能的原因 - -见于各种 `Connect Client` 进行`close`或者`destory`的时候报错,不影响最终效果。 - -### 排查和解决步骤 - -可通过一些第三方的工具或者 `jstack [PID] > jstack.log` 分析堆栈信息,进行定位。 diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/4/8.md b/content/zh-cn/overview/mannual/java-sdk/faq/4/8.md deleted file mode 100644 index 7bcbba50a33c..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/4/8.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/4/8/ - - /zh-cn/docs3-v2/java-sdk/faq/4/8/ -description: 4-8 - 关闭服务端时发生错误 -linkTitle: 4-8 - 关闭服务端时发生错误 -title: 4-8 - 关闭服务端时发生错误 -type: docs -weight: 8 ---- - - - - - - -### 可能的原因 - -与4-7相似,都是发生在close时。 - -### 排查和解决步骤 - -可通过一些第三方的工具或者`jstack [PID] > jstack.log` 分析堆栈信息,进行定位。 diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/4/9.md b/content/zh-cn/overview/mannual/java-sdk/faq/4/9.md deleted file mode 100644 index 193c32bd395d..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/4/9.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/4/9/ - - /zh-cn/docs3-v2/java-sdk/faq/4/9/ -description: 4-9 - 解析失败 -linkTitle: 4-9 - 解析失败 -title: 4-9 - 解析失败 -type: docs -weight: 9 ---- - - - - - - -### 可能的原因 - -一般为参数值不符合规则,在强转时发生错误。 -如: - -```java -String timeoutString = httpMetadata.headers().getFirst(TripleHeaderEnum.SERVICE_TIMEOUT.getHeader()); -Long timeout = Long.parseLong(timeoutString); - -Long timeout = GrpcUtils.parseTimeoutToMills(timeoutString); -invocation.put(CommonConstants.TIMEOUT_KEY, timeout); -``` - -### 排查和解决步骤 - -根据堆栈信息提示的 key 名称进行相对应的配置修改到符合转换规则即可。 diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/4/_index.md b/content/zh-cn/overview/mannual/java-sdk/faq/4/_index.md deleted file mode 100644 index 526ecd98b722..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/4/_index.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/4/ - - /zh-cn/docs3-v2/java-sdk/faq/4/ -description: 4 - 协议层 -linkTitle: 4 - 协议层 -title: 4 - 协议层 -type: docs -weight: 4 ---- diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/5/1.md b/content/zh-cn/overview/mannual/java-sdk/faq/5/1.md deleted file mode 100644 index eda716babb58..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/5/1.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/5/1/ - - /zh-cn/docs3-v2/java-sdk/faq/5/1/ -description: 5-1 - 配置中心连接失败 -linkTitle: 5-1 - 配置中心连接失败 -title: 5-1 - 配置中心连接失败 -type: docs -weight: 1 ---- - - - - - - -### 可能的原因 - -1. 配置中心所在的服务器关机或宕机。 -2. IP 或者端口号写错。 -3. 防火墙错误拦截了配置中心的端口。 - - -### 排查和解决步骤 - -1. 检查配置中心 IP 以及端口的配置。 -2. 检查服务器是否开机,是否正常工作。 -3. 检查防火墙等是否放行配置中心所用的端口。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/5/10.md b/content/zh-cn/overview/mannual/java-sdk/faq/5/10.md deleted file mode 100644 index cb4c48cf1125..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/5/10.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/5/10/ - - /zh-cn/docs3-v2/java-sdk/faq/5/10/ -description: 5-10 - 服务的注册接口应用程序映射失败 -linkTitle: 5-10 - 服务的注册接口应用程序映射失败 -title: 5-10 - 服务的注册接口应用程序映射失败 -type: docs -weight: 10 ---- - - - - - - -### 可能的原因 - -服务暴露的服务元数据与应用程序不匹配,或被篡改。 - -### 排查和解决步骤 - -检查配置中心的元数据内容是否与应用程序内的匹配。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/5/11.md b/content/zh-cn/overview/mannual/java-sdk/faq/5/11.md deleted file mode 100644 index d6de835d7a19..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/5/11.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/5/11/ - - /zh-cn/docs3-v2/java-sdk/faq/5/11/ -description: 5-11 - 注册实例错误 -linkTitle: 5-11 - 注册实例错误 -title: 5-11 - 注册实例错误 -type: docs -weight: 11 ---- - - - - - - -### 可能的原因 - -1. 配置中心的服务无法连接。 -2. 配置的协议、IP、端口不正确。 -3. 使用配置中心客户端版本与服务端版本冲突,无法建立有效连接。 - -### 排查和解决步骤 - -1. 检查配置中心的服务状态是否正常。 -2. 检查配置的协议、IP、端口不正确。 -3. 检查使用的配置中心客户端版本与服务端版本是否兼容。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/5/12.md b/content/zh-cn/overview/mannual/java-sdk/faq/5/12.md deleted file mode 100644 index 3a18cd91bad8..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/5/12.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/5/12/ - - /zh-cn/docs3-v2/java-sdk/faq/5/12/ -description: 5-12 - 刷新实例和元数据错误 -linkTitle: 5-12 - 刷新实例和元数据错误 -title: 5-12 - 刷新实例和元数据错误 -type: docs -weight: 12 ---- - - - - - - -### 可能的原因 - -1. 配置中心的服务无法连接。 -2. 配置的协议、IP、端口不正确。 -3. 使用配置中心客户端版本与服务端版本冲突,无法建立有效连接。 - -### 排查和解决步骤 - -1. 检查配置中心的服务状态是否正常。 -2. 检查配置的协议、IP、端口不正确。 -3. 检查使用的配置中心客户端版本与服务端版本是否兼容。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/5/13.md b/content/zh-cn/overview/mannual/java-sdk/faq/5/13.md deleted file mode 100644 index e23978f993e4..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/5/13.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/5/13/ - - /zh-cn/docs3-v2/java-sdk/faq/5/13/ -description: 5-13 - 无法销毁模型 -linkTitle: 5-13 - 无法销毁模型 -title: 5-13 - 无法销毁模型 -type: docs -weight: 13 ---- - - - - - - -### 可能的原因 - -自定义销毁方法,业务处理上存在异常。 - -### 排查和解决步骤 - -检查自定义销毁方法,业务处理逻辑是否存在运行时异常。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/5/14.md b/content/zh-cn/overview/mannual/java-sdk/faq/5/14.md deleted file mode 100644 index 4fcf8097d571..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/5/14.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/5/14/ - - /zh-cn/docs3-v2/java-sdk/faq/5/14/ -description: 5-14 - 模型启动错误 -linkTitle: 5-14 - 模型启动错误 -title: 5-14 - 模型启动错误 -type: docs -weight: 14 ---- - - - - - - -### 可能的原因 - -1. 服务在等待发布或订阅时,连接被断开。 -2. 网络连接超时。 - -### 排查和解决步骤 - -1. 检查应用服务器与配置中心的连接是否正常。 -2. 检查网络连接是否存在超时等。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/5/15.md b/content/zh-cn/overview/mannual/java-sdk/faq/5/15.md deleted file mode 100644 index 449d8607a350..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/5/15.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/5/15/ - - /zh-cn/docs3-v2/java-sdk/faq/5/15/ -description: 5-15 - 模型引用错误 -linkTitle: 5-15 - 模型引用错误 -title: 5-15 - 模型引用错误 -type: docs -weight: 15 ---- - - - - - - -### 可能的原因 - -Dubbo 核心处理类的方法被错误使用或被篡改。 - -### 排查和解决步骤 - -检查应用程序上是否存在错误使用或反编译修改情况。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/5/16.md b/content/zh-cn/overview/mannual/java-sdk/faq/5/16.md deleted file mode 100644 index 5cb536446bf6..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/5/16.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/5/16/ - - /zh-cn/docs3-v2/java-sdk/faq/5/16/ -description: 5-16 - 无法找到任何有效的协议 -linkTitle: 5-16 - 无法找到任何有效的协议 -title: 5-16 - 无法找到任何有效的协议 -type: docs -weight: 16 ---- - - - - - - -### 可能的原因 - -配置的协议不支持。 - -### 排查和解决步骤 - -目前支持的协议有 dubbo、rmi、hessian、http、webservice、thrift、redis 等。 - -> 另请参阅 -[配置项参考手册](/zh-cn/overview/mannual/java-sdk/reference-manual/config/) \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/5/17.md b/content/zh-cn/overview/mannual/java-sdk/faq/5/17.md deleted file mode 100644 index 917311b4ccb1..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/5/17.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/5/17/ - - /zh-cn/docs3-v2/java-sdk/faq/5/17/ -description: 5-17 - 参数值格式错误 -linkTitle: 5-17 - 参数值格式错误 -title: 5-17 - 参数值格式错误 -type: docs -weight: 17 ---- - - - - - - -### 可能的原因 - -1. 属性配置值长度过长,一般设置在 200 个字符以内。 -2. 属性配置值格式错误,目前支持数字、 -、 _ 等 - -### 排查和解决步骤 - -1. 检查属性配置值内容是否过长,具体参考提示信息进行修改。 -2. 检查属性配置值内容是否包含特殊字符,如 @#$%^& 等,具体请参考提示信息进行修改。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/5/18.md b/content/zh-cn/overview/mannual/java-sdk/faq/5/18.md deleted file mode 100644 index 05526a0dccd9..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/5/18.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/5/18/ - - /zh-cn/docs3-v2/java-sdk/faq/5/18/ -description: 5-18 - 通知注册事件失败 -linkTitle: 5-18 - 通知注册事件失败 -title: 5-18 - 通知注册事件失败 -type: docs -weight: 18 ---- - - - - - - -### 可能的原因 - -1. 通知已发送,业务处理逻辑上出现意外错误。 -2. 配置中心无法连接,超时错误。 - -### 排查和解决步骤 - -1. 检查自定义业务逻辑实现,是否存在运行时异常。 -2. 检查配置中心是否能够正常连接。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/5/2.md b/content/zh-cn/overview/mannual/java-sdk/faq/5/2.md deleted file mode 100644 index d3099d72f9be..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/5/2.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/5/2/ - - /zh-cn/docs3-v2/java-sdk/faq/5/2/ -description: 5-2 - 注册/注销关闭钩子方法失败 -linkTitle: 5-2 - 注册/注销关闭钩子方法失败 -title: 5-2 - 注册/注销关闭钩子方法失败 -type: docs -weight: 2 ---- - - - - - - -### 可能的原因 - -自定义钩子方法,业务处理逻辑存在异常。 - -### 排查和解决步骤 - -检查自定义钩子方法,业务处理逻辑是否存在运行时异常。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/5/20.md b/content/zh-cn/overview/mannual/java-sdk/faq/5/20.md deleted file mode 100644 index 924e0d7f3110..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/5/20.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/5/20/ - - /zh-cn/docs3-v2/java-sdk/faq/5/20/ -description: 5-20 - 停止 dubbo 模块时发生错误 -linkTitle: 5-20 - 停止 dubbo 模块时发生错误 -title: 5-20 - 停止 dubbo 模块时发生错误 -type: docs -weight: 20 ---- - - - - - - -### 可能的原因 - -1. 自定义实现销毁方法,可能存在业务逻辑运行时异常。 -2. 未优雅停止服务,可能存在业务逻辑未处理完成情况。 - -### 排查和解决步骤 - -1. 检查自定义实现销毁方法,业务逻辑。 -2. 检查停止服务时,是否存在耗时的业务处理逻辑。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/5/21.md b/content/zh-cn/overview/mannual/java-sdk/faq/5/21.md deleted file mode 100644 index 108a58734f32..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/5/21.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/5/21/ - - /zh-cn/docs3-v2/java-sdk/faq/5/21/ -description: 5-21 - 服务销毁时发生异常错误 -linkTitle: 5-21 - 服务销毁时发生异常错误 -title: 5-21 - 服务销毁时发生异常错误 -type: docs -weight: 21 ---- - - - - - - - -### 可能的原因 - -服务发现实例已销毁完成 - -> 当前方法在 3.1 版本已停止使用 - -### 排查和解决步骤 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/5/22.md b/content/zh-cn/overview/mannual/java-sdk/faq/5/22.md deleted file mode 100644 index a8d219b5c812..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/5/22.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/5/22/ - - /zh-cn/docs3-v2/java-sdk/faq/5/22/ -description: 5-22 - 注册中心在初始化时发生错误 -linkTitle: 5-22 - 注册中心在初始化时发生错误 -title: 5-22 - 注册中心在初始化时发生错误 -type: docs -weight: 22 ---- - - - - - - - -### 可能的原因 - -1. 注册中心的地址配置错误。 -2. 配置的地址信息无法通过网络正常连接。 -3. 配置中心客户端的版本与实际服务端的版本不符,存在兼容性异常。 - -### 排查和解决步骤 - -1. 检查配置地址是否正确。 -2. 检查网络是否通畅并可通过第三方客户端进行连接。 -3. 检查是否存在兼容性匹配问题,可参考第三方网站进行版本适配。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/5/23.md b/content/zh-cn/overview/mannual/java-sdk/faq/5/23.md deleted file mode 100644 index 394bb906dc1a..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/5/23.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/5/23/ - - /zh-cn/docs3-v2/java-sdk/faq/5/23/ -description: 5-23 - 等待导出/引用服务发生异常 -linkTitle: 5-23 - 等待导出/引用服务发生异常 -title: 5-23 - 等待导出/引用服务发生异常 -type: docs -weight: 23 ---- - - - - - - - -### 可能的原因 - -导出/引用服务时,注册中心异常停止或无法对外提供正常服务。 - -### 排查和解决步骤 - -检查注册中心的是否可正常连接,并检查当前客户端版本是否与服务端兼容匹配。 - -> 导出/引用单方法内都对异常做了处理,理论上此异常不会被抛出。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/5/24.md b/content/zh-cn/overview/mannual/java-sdk/faq/5/24.md deleted file mode 100644 index ba42ef96d850..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/5/24.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/5/24/ - - /zh-cn/docs3-v2/java-sdk/faq/5/24/ -description: 5-24 - 异步等待引用服务发生异常 -linkTitle: 5-24 - 异步等待引用服务发生异常 -title: 5-24 - 异步等待引用服务发生异常 -type: docs -weight: 24 ---- - - - - - - - -### 可能的原因 - -注册中心异常停止或无法对外提供正常服务。 - -### 排查和解决步骤 - -检查注册中心的是否可正常连接,并检查当前客户端版本是否与服务端兼容匹配。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/5/25.md b/content/zh-cn/overview/mannual/java-sdk/faq/5/25.md deleted file mode 100644 index 318fcce3c333..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/5/25.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/5/25/ - - /zh-cn/docs3-v2/java-sdk/faq/5/25/ -description: 5-25 - 自定义实现发生未定义异常 -linkTitle: 5-25 - 自定义实现发生未定义异常 -title: 5-25 - 自定义实现发生未定义异常 -type: docs -weight: 25 ---- - - - - - - -### 可能的原因 - -自定义实现的 `org.apache.dubbo.rpc.Protocol` 协议,在方法调用 destory 时发生业务逻辑异常。 - -### 排查和解决步骤 - -检查自定义实现类代码的 `destory` 方法。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/5/26.md b/content/zh-cn/overview/mannual/java-sdk/faq/5/26.md deleted file mode 100644 index 3de42b275bd0..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/5/26.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/5/26/ - - /zh-cn/docs3-v2/java-sdk/faq/5/26/ -description: 5-26 - 元数据已导出 -linkTitle: 5-26 - 元数据已导出 -title: 5-26 - 元数据已导出 -type: docs -weight: 26 ---- - - - - - - -### 可能的原因 - -元数据在当前 JVM 已被导出。 - -### 排查和解决步骤 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/5/27.md b/content/zh-cn/overview/mannual/java-sdk/faq/5/27.md deleted file mode 100644 index 7e5d9a142f97..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/5/27.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/5/27/ - - /zh-cn/docs3-v2/java-sdk/faq/5/27/ -description: 5-27 - 内部类API被错误使用 -linkTitle: 5-27 - 内部类API被错误使用 -title: 5-27 - 内部类API被错误使用 -type: docs -weight: 27 ---- - - - - - - -### 可能的原因 - -`org.apache.dubbo.config.ReferenceConfig` 和 `org.apache.dubbo.common.config.ReferenceCache` 或被定义为非单例模式。 - -### 排查和解决步骤 - -检查自定义注解或配置,将核心应用类定以了为非单例模式,检查 `scope` 配置。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/5/28.md b/content/zh-cn/overview/mannual/java-sdk/faq/5/28.md deleted file mode 100644 index 72ae78589994..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/5/28.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/5/28/ - - /zh-cn/docs3-v2/java-sdk/faq/5/28/ -description: 5-28 - 未发现可用注解 -linkTitle: 5-28 - 未发现可用注解 -title: 5-28 - 未发现可用注解 -type: docs -weight: 28 ---- - - - - - - -### 可能的原因 - -扫描包配置下未发现可靠注解。主要为 `@DubboService` 或 `@Service` - -### 排查和解决步骤 - -检查当前使用的版本,2.7.7 之前将扫描 `@Service` 注解,之后为 `@DubboService` \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/5/29.md b/content/zh-cn/overview/mannual/java-sdk/faq/5/29.md deleted file mode 100644 index a4db53a64701..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/5/29.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/5/29/ - - /zh-cn/docs3-v2/java-sdk/faq/5/29/ -description: 5-29 - 扫描包未配置 -linkTitle: 5-29 - 扫描包未配置 -title: 5-29 - 扫描包未配置 -type: docs -weight: 29 ---- - - - - - - -### 可能的原因 - -`@EnableDubbo.scanBasePackages` 注解参数值未配置。 - -### 排查和解决步骤 - -`@EnableDubbo.scanBasePackages` 配置即可。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/5/3.md b/content/zh-cn/overview/mannual/java-sdk/faq/5/3.md deleted file mode 100644 index ab7e1abc16bf..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/5/3.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/5/3/ - - /zh-cn/docs3-v2/java-sdk/faq/5/3/ -description: 5-3 - 销毁方法调用时发生意外错误 -linkTitle: 5-3 - 销毁方法调用时发生意外错误 -title: 5-3 - 销毁方法调用时发生意外错误 -type: docs -weight: 3 ---- - - - - - - -### 可能的原因 - -自定义销毁方法,业务处理上存在异常。 - -### 排查和解决步骤 - -检查自定义销毁方法,业务处理逻辑是否存在运行时异常。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/5/30.md b/content/zh-cn/overview/mannual/java-sdk/faq/5/30.md deleted file mode 100644 index f462cecdbe6c..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/5/30.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/5/30/ - - /zh-cn/docs3-v2/java-sdk/faq/5/30/ -description: 5-30 - 声明bean定义重复 -linkTitle: 5-30 - 声明bean定义重复 -title: 5-30 - 声明bean定义重复 -type: docs -weight: 30 ---- - - - - - - -### 可能的原因 - -声明的对象 id 或名称重复。 - -### 排查和解决步骤 - -根据控制台输出的全限定类名称,名称修改唯一即可。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/5/31.md b/content/zh-cn/overview/mannual/java-sdk/faq/5/31.md deleted file mode 100644 index e6fc1429f88c..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/5/31.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/5/31/ - - /zh-cn/docs3-v2/java-sdk/faq/5/31/ -description: 5-31 - 状态检查错误 -linkTitle: 5-31 - 状态检查错误 -title: 5-31 - 状态检查错误 -type: docs -weight: 31 ---- - - - - - - -### 可能的原因 - -当前运行的服务器状态,系统 CPU 使用率过高或内存等指标太低 - -### 排查和解决步骤 - -检查当前服务器的内存使用状态,及 CPU 使用率等其他指标,可能存在宕机的危险。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/5/32.md b/content/zh-cn/overview/mannual/java-sdk/faq/5/32.md deleted file mode 100644 index c8406182a109..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/5/32.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/5/32/ - - /zh-cn/docs3-v2/java-sdk/faq/5/32/ -description: 5-32 - Apollo 断开连接时发生错误 -linkTitle: 5-32 - Apollo 断开连接时发生错误 -title: 5-32 - Apollo 断开连接时发生错误 -type: docs -weight: 32 ---- - - - - - - -### 可能的原因 - -Apollo 配置中心可能已关闭或者网络已断开。 - -### 排查和解决步骤 - -检查 Apollo 服务端服务状态,及网络间是否可正常通信。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/5/33.md b/content/zh-cn/overview/mannual/java-sdk/faq/5/33.md deleted file mode 100644 index 50e904f0df05..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/5/33.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/5/33/ - - /zh-cn/docs3-v2/java-sdk/faq/5/33/ -description: 5-33 - Apollo 配置更新事件发生异常 -linkTitle: 5-33 - Apollo 配置更新事件发生异常 -title: 5-33 - Apollo 配置更新事件发生异常 -type: docs -weight: 33 ---- - - - - - - -### 可能的原因 - -Apollo 配置 API 使用错误。 - -### 排查和解决步骤 - -请参考动态配置中心使用文档中关于 Apollo 部分的描述。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/5/34.md b/content/zh-cn/overview/mannual/java-sdk/faq/5/34.md deleted file mode 100644 index 086c3ce5a546..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/5/34.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/5/34/ - - /zh-cn/docs3-v2/java-sdk/faq/5/34/ -description: 5-34 - NACOS 发生错误 -linkTitle: 5-34 - NACOS 发生错误 -title: 5-34 - NACOS 发生错误 -type: docs -weight: 34 ---- - - - - - - -### 可能的原因 - -NACOS 配置 API 使用错误。 - -### 排查和解决步骤 - -请参考动态配置中心使用文档中关于 NACOS 部分的描述。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/5/35.md b/content/zh-cn/overview/mannual/java-sdk/faq/5/35.md deleted file mode 100644 index 03f5e6040d91..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/5/35.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/5/35/ - - /zh-cn/docs3-v2/java-sdk/faq/5/35/ -description: 5-35 - 容器初始化失败 -linkTitle: 5-35 - 容器初始化失败 -title: 5-35 - 容器初始化失败 -type: docs -weight: 35 ---- - - - - - - -## 可能的原因 - -未定义接口的 `org.apache.dubbo.container.Container` SPI 实现。 - -附:目前在`org.apache.dubbo.container.Main` 类中测试使用。 - -## 排查和解决步骤 - - -

\ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/5/36.md b/content/zh-cn/overview/mannual/java-sdk/faq/5/36.md deleted file mode 100644 index 392698b9e375..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/5/36.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/5/36/ - - /zh-cn/docs3-v2/java-sdk/faq/5/36/ -description: 5-36 - 过滤器校验时发生错误 -linkTitle: 5-36 - 过滤器校验时发生错误 -title: 5-36 - 过滤器校验时发生错误 -type: docs -weight: 36 ---- - - - - - - -### 可能的原因 - -自定义过滤器扩展类中重写的 `invoke` 方法,发生业务代码异常。 - -### 排查和解决步骤 -1. 使用 ps -eaf |grep <错误服务> -2. 可通过一些第三方的工具或者 `jstack [PID] > jstack.log` 分析堆栈信息,进行定位。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/5/37.md b/content/zh-cn/overview/mannual/java-sdk/faq/5/37.md deleted file mode 100644 index 5eafb4aea10f..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/5/37.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/5/37/ - - /zh-cn/docs3-v2/java-sdk/faq/5/37/ -description: 5-37 - 动态配置监听处理发生错误 -linkTitle: 5-37 - 动态配置监听处理发生错误 -title: 5-37 - 动态配置监听处理发生错误 -type: docs -weight: 37 ---- - - - - - -文件发生变化时,监听事件处理失败 - -### 可能的原因 - -文件权限发生变化或目录权限发生变化。 - -### 排查和解决步骤 - -可根据控制台的堆栈信息,进行代码定位。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/5/38.md b/content/zh-cn/overview/mannual/java-sdk/faq/5/38.md deleted file mode 100644 index de9b02550952..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/5/38.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/5/38/ - - /zh-cn/docs3-v2/java-sdk/faq/5/38/ -description: 5-38 - 配置参数未定义 -linkTitle: 5-38 - 配置参数未定义 -title: 5-38 - 配置参数未定义 -type: docs -weight: 38 ---- - - - - - - -### 可能的原因 - -配置参数未定义 - -### 排查和解决步骤 - -多为测试用例中使用,可根据提示明细,进行参数的设置。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/5/39.md b/content/zh-cn/overview/mannual/java-sdk/faq/5/39.md deleted file mode 100644 index 63563556664e..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/5/39.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/5/39/ - - /zh-cn/docs3-v2/java-sdk/faq/5/39/ -description: 5-39 - Dubbo配置bean初始化器发生错误 -linkTitle: 5-39 - Dubbo配置bean初始化器发生错误 -title: 5-39 - Dubbo配置bean初始化器发生错误 -type: docs -weight: 39 ---- - - - - - - -### 可能的原因 - -源代码或被修改 - -### 排查和解决步骤 - -检查业务代码未对核心类进行源码修改或加载的顺序修改。 -如:`org.apache.dubbo.config.spring.context.DubboConfigBeanInitializer` \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/5/4.md b/content/zh-cn/overview/mannual/java-sdk/faq/5/4.md deleted file mode 100644 index b3e90dd23cae..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/5/4.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/5/4/ - - /zh-cn/docs3-v2/java-sdk/faq/5/4/ -description: 5-4 - 服务接口中找不到方法 -linkTitle: 5-4 - 服务接口中找不到方法 -title: 5-4 - 服务接口中找不到方法 -type: docs -weight: 4 ---- - - - - - - -### 可能的原因 - -1. 消费端调用的接口名#方法不存在。 -2. 服务端未正确的暴露当前接口。 - -### 排查和解决步骤 - -1. 检查消费端调用的接口名#方法是否存在。 -2. 检查服务端暴露的服务列表内是否存在。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/5/40.md b/content/zh-cn/overview/mannual/java-sdk/faq/5/40.md deleted file mode 100644 index 5bb8bfa6c8fd..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/5/40.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/5/40/ - - /zh-cn/docs3-v2/java-sdk/faq/5/40/ -description: 5-40 - Dubbo配置bean未找到 -linkTitle: 5-40 - Dubbo配置bean未找到 -title: 5-40 - Dubbo配置bean未找到 -type: docs -weight: 40 ---- - - - - - - -### 可能的原因 - -源代码或被修改 - -### 排查和解决步骤 - -检查业务代码未对核心类进行源码修改或加载的顺序修改。 -如:`org.apache.dubbo.config.spring.context.DubboConfigBeanInitializer` \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/5/41.md b/content/zh-cn/overview/mannual/java-sdk/faq/5/41.md deleted file mode 100644 index dfd2dd826133..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/5/41.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/5/41/ - - /zh-cn/docs3-v2/java-sdk/faq/5/41/ -description: 5-41 - SSL证书读取失败 -linkTitle: 5-41 - SSL证书读取失败 -title: 5-41 - SSL证书读取失败 -type: docs -weight: 41 ---- - - - - - - -### 可能的原因 - -SSL 证书配置异常 - -### 排查和解决步骤 - -检查 SSL 证书的配置,查看对应文件是否存在 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/5/42.md b/content/zh-cn/overview/mannual/java-sdk/faq/5/42.md deleted file mode 100644 index 1ae4e75fd16b..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/5/42.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/5/42/ - - /zh-cn/docs3-v2/java-sdk/faq/5/42/ -description: 5-42 - Dubbo 证书签发失败 -linkTitle: 5-42 - Dubbo 证书签发失败 -title: 5-42 - Dubbo 证书签发失败 -type: docs -weight: 42 ---- - - - - - - -### 可能的原因 - -Dubbo 请求远程 CA 签发证书失败 - -### 排查和解决步骤 - -- 检查 CA 连接配置 -- 检查 CA 运行状态 -- 检查 CA 日志 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/5/43.md b/content/zh-cn/overview/mannual/java-sdk/faq/5/43.md deleted file mode 100644 index 6cab512292e1..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/5/43.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/5/43/ - - /zh-cn/docs3-v2/java-sdk/faq/5/43/ -description: 5-43 - Dubbo 证书签发连接不安全 -linkTitle: 5-43 - Dubbo 证书签发连接不安全 -title: 5-43 - Dubbo 证书签发连接不安全 -type: docs -weight: 43 ---- - - - - - - -### 可能的原因 - -Dubbo 与远程 CA 的连接不安全 - -### 排查和解决步骤 - -- 检查 Dubbo 进程是否已经正确配置了 CA 证书信息以及 OIDC(OpenID Connect)的 Token 获取方式 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/5/5.md b/content/zh-cn/overview/mannual/java-sdk/faq/5/5.md deleted file mode 100644 index 2f48fa867b8a..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/5/5.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/5/5/ - - /zh-cn/docs3-v2/java-sdk/faq/5/5/ -description: 5-5 - 无法获得env变量 -linkTitle: 5-5 - 无法获得env变量 -title: 5-5 - 无法获得env变量 -type: docs -weight: 5 ---- - - - - - - -### 可能的原因 - -环境变量无法获取。 - -### 排查和解决步骤 - -检查提示的变量名,是否配置并可以正常读取加载。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/5/6.md b/content/zh-cn/overview/mannual/java-sdk/faq/5/6.md deleted file mode 100644 index 1218b22d9a23..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/5/6.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/5/6/ - - /zh-cn/docs3-v2/java-sdk/faq/5/6/ -description: 5-6 - 接口类型的属性冲突 -linkTitle: 5-6 - 接口类型的属性冲突 -title: 5-6 - 接口类型的属性冲突 -type: docs -weight: 6 ---- - - - - - - -### 可能的原因 - -泛化定义配置不正确。 - -### 排查和解决步骤 - -检查泛化定义是否正确。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/5/7.md b/content/zh-cn/overview/mannual/java-sdk/faq/5/7.md deleted file mode 100644 index 6f91dab68b62..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/5/7.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/5/7/ - - /zh-cn/docs3-v2/java-sdk/faq/5/7/ -description: 5-7 - 取消导出时发生意外错误 -linkTitle: 5-7 - 取消导出时发生意外错误 -title: 5-7 - 取消导出时发生意外错误 -type: docs -weight: 7 ---- - - - - - - -### 可能的原因 - -1. 配置中心的服务无法连接。 -2. 配置的协议、IP、端口不正确。 -3. 使用配置中心客户端版本与服务端版本冲突,无法建立有效连接。 - -### 排查和解决步骤 - -1. 检查配置中心的服务状态是否正常。 -2. 检查配置的协议、IP、端口不正确。 -3. 检查使用的配置中心客户端版本与服务端版本是否兼容。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/5/8.md b/content/zh-cn/overview/mannual/java-sdk/faq/5/8.md deleted file mode 100644 index 06de1d49f1fd..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/5/8.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/5/8/ - - /zh-cn/docs3-v2/java-sdk/faq/5/8/ -description: 5-8 - 协议将使用随机可用端口 -linkTitle: 5-8 - 协议将使用随机可用端口 -title: 5-8 - 协议将使用随机可用端口 -type: docs -weight: 8 ---- - - - - - - -### 可能的原因 - -协议指定的端口被占用,随机选择端口进行启动。 - -### 排查和解决步骤 - -检查当前配置端口是否被其它应用程序占用。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/5/9.md b/content/zh-cn/overview/mannual/java-sdk/faq/5/9.md deleted file mode 100644 index 43c2fb69ea7c..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/5/9.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/5/9/ - - /zh-cn/docs3-v2/java-sdk/faq/5/9/ -description: 5-9 - 服务配置导出失败 -linkTitle: 5-9 - 服务配置导出失败 -title: 5-9 - 服务配置导出失败 -type: docs -weight: 9 ---- - - - - - - -### 可能的原因 - -1. 配置中心的服务无法连接。 -2. 配置的协议、IP、端口不正确。 -3. 使用配置中心客户端版本与服务端版本冲突,无法建立有效连接。 - -### 排查和解决步骤 - -1. 检查配置中心的服务状态是否正常。 -2. 检查配置的协议、IP、端口不正确。 -3. 检查使用的配置中心客户端版本与服务端版本是否兼容。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/5/_index.md b/content/zh-cn/overview/mannual/java-sdk/faq/5/_index.md deleted file mode 100644 index 0cbeaaa4eaf6..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/5/_index.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/5/ - - /zh-cn/docs3-v2/java-sdk/faq/5/ -description: 5 - 配置(中心)层 -linkTitle: 5 - 配置(中心)层 -title: 5 - 配置(中心)层 -type: docs -weight: 5 ---- diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/6/1.md b/content/zh-cn/overview/mannual/java-sdk/faq/6/1.md deleted file mode 100644 index a5e20d76faf9..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/6/1.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/6/1/ - - /zh-cn/docs3-v2/java-sdk/faq/6/1/ -description: 6-1 - 服务端连接失败 -linkTitle: 6-1 - 服务端连接失败 -title: 6-1 - 服务端连接失败 -type: docs -weight: 1 ---- - - - - - -网络通信层,在连接服务提供者服务时失败 - -### 可能的原因 - -服务提供者的网络异常断开或受防火墙及第三方工具的拦截,无法对外提供服务。 - -### 排查和解决步骤 - -1. 如果为 rest 连接,检查请求的服务端配置是否正确。 -2. 检查网络通信是否正常,可使用一些简单的 cmd 命令进行检测,如 `ping` 等。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/6/10.md b/content/zh-cn/overview/mannual/java-sdk/faq/6/10.md deleted file mode 100644 index cd8014ecee82..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/6/10.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/6/10/ - - /zh-cn/docs3-v2/java-sdk/faq/6/10/ -description: 6-10 - 超过有效载荷限制异常 -linkTitle: 6-10 - 超过有效载荷限制异常 -title: 6-10 - 超过有效载荷限制异常 -type: docs -weight: 10 ---- - - - - - - -### 可能的原因 - -> 默认 `payload=8M`,请检查各项配置 - -### 排查和解决步骤 - -各组件支持的具体配置项及含义请参考 [配置项手册](/zh-cn/overview/mannual/java-sdk/reference-manual/config/properties/) \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/6/11.md b/content/zh-cn/overview/mannual/java-sdk/faq/6/11.md deleted file mode 100644 index 05a27d4d079f..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/6/11.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/6/11/ - - /zh-cn/docs3-v2/java-sdk/faq/6/11/ -description: 6-11 - 字符集不被支持 -linkTitle: 6-11 - 字符集不被支持 -title: 6-11 - 字符集不被支持 -type: docs -weight: 11 ---- - - - - - - -## 可能的原因 - -> 默认 `UTF-8` 字符集 - -## 排查和解决步骤 - -结果会最终以 `UTF-8` 字符集进行处理。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/6/12.md b/content/zh-cn/overview/mannual/java-sdk/faq/6/12.md deleted file mode 100644 index 1c8744c76166..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/6/12.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/6/12/ - - /zh-cn/docs3-v2/java-sdk/faq/6/12/ -description: 6-12 - ZK客户端销毁时发生错误 -linkTitle: 6-12 - ZK客户端销毁时发生错误 -title: 6-12 - ZK客户端销毁时发生错误 -type: docs -weight: 12 ---- - - - - - - - -### 可能的原因 - -客户端与服务端连接已被拒绝 -客户端在销毁时,可能服务端正在进行选举或者其他操作,导致发生的异常。 - -### 排查和解决步骤 - -关闭方法,可针对堆栈信息进行查询。一般可不处理。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/6/13.md b/content/zh-cn/overview/mannual/java-sdk/faq/6/13.md deleted file mode 100644 index 1771fd395f1b..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/6/13.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/6/13/ - - /zh-cn/docs3-v2/java-sdk/faq/6/13/ -description: 6-13 - 流关闭异常 -linkTitle: 6-13 - 流关闭异常 -title: 6-13 - 流关闭异常 -type: docs -weight: 13 ---- - - - - - - - -### 可能的原因 - -当前流已关闭 `Stream is closed` 或流关闭时,其他线程正在读取。 - -### 排查和解决步骤 - -一般为代码关闭流的顺序上发生了颠倒。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/6/14.md b/content/zh-cn/overview/mannual/java-sdk/faq/6/14.md deleted file mode 100644 index f33f8c488035..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/6/14.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/6/14/ - - /zh-cn/docs3-v2/java-sdk/faq/6/14/ -description: 6-14 - 服务端响应失败 -linkTitle: 6-14 - 服务端响应失败 -title: 6-14 - 服务端响应失败 -type: docs -weight: 14 ---- - - - - - - -### 可能的原因 - -在服务端与客户端交互发生数据时,客户端异常关闭。 - -### 排查和解决步骤 - -客户端异常终止或服务器宕机。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/6/15.md b/content/zh-cn/overview/mannual/java-sdk/faq/6/15.md deleted file mode 100644 index 2a5d0e531fa6..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/6/15.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/6/15/ - - /zh-cn/docs3-v2/java-sdk/faq/6/15/ -description: 6-15 - 跳过未读完的流数据 -linkTitle: 6-15 - 跳过未读完的流数据 -title: 6-15 - 跳过未读完的流数据 -type: docs -weight: 15 ---- - - - - - - -### 可能的原因 - -解码时,如流中还有未读数据时会跳过未读完的流 - -### 排查和解决步骤 - -解码时会把数据全部一次性读取 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/6/16.md b/content/zh-cn/overview/mannual/java-sdk/faq/6/16.md deleted file mode 100644 index aa1abed1307e..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/6/16.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/6/16/ - - /zh-cn/docs3-v2/java-sdk/faq/6/16/ -description: 6-16 - 重连时发生异常 -linkTitle: 6-16 - 重连时发生异常 -title: 6-16 - 重连时发生异常 -type: docs -weight: 16 ---- - - - - - - -### 可能的原因 - -每次发生重连时提示,网络不稳定造成的延迟重连。 - -### 排查和解决步骤 - -检查是否有网络丢包情况。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/6/2.md b/content/zh-cn/overview/mannual/java-sdk/faq/6/2.md deleted file mode 100644 index f939796c7bc6..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/6/2.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/6/2/ - - /zh-cn/docs3-v2/java-sdk/faq/6/2/ -description: 6-2 - 客户端超时 -linkTitle: 6-2 - 客户端超时 -title: 6-2 - 客户端超时 -type: docs -weight: 2 ---- - - - - - -超时是调用端发生在请求发出后,无法在指定的时间内获得对应的响应。 - -### 可能的原因 -1. 服务端确实处理比较慢,无法在指定的时间返回结果,调用端就自动返回一个超时的异常响应来结束此次调用。 -2. 服务端如果响应的比较快,但当客户端 Load 很高,负载压力很大的时候,会因为客户端请求发不出去、响应卡在 TCP Buffer 等问题,造成超时。因为客户端接收到服务端发来的数据或者请求服务端的数据,都会在系统层面排队,如果系统负载比较高,在内核态的时间占比就会加长,从而造成客户端获取到值时已经超时。 -3. 通常是业务处理太慢,可在服务提供方机器上执行:`jstack [PID] > jstack.log` 分析线程都卡在哪个方法调用上,这里就是慢的原因。如果不能调优性能,请调高 timeout 阈值。 - - -### 排查和解决步骤 - -1. 两边可能有 GC,检查服务端和客户端 GC 日志,耗时很长的 GC,会导致超时。超时的发生很可能意味着调用端或者服务端的资源(CPU,内存或者网络)出现了瓶颈,需要检查服务端的问题还是调用端的问题来排除 GC 抖动等嫌疑。 -2. 检查服务端的网络质量,比如重传率来排除网络嫌疑。 -3. 借助链路跟踪的分析服务(比如阿里的 [ARMS](https://help.aliyun.com/document_detail/63796.html) ,开源的 [OpenTracing](https://github.com/opentracing/opentracing-java) -系的实现 [Zipkin](https://github.com/openzipkin/zipkin) 、[SkyWalking](https://github.com/apache/skywalking) 等)来分析下各个点的耗时情况。 - - -> 这个错误码的 FAQ 页面参考了空冥同学的 [《Dubbo 常见错误及解决方法》](https://github.com/StabilityMan/StabilityGuide/blob/master/docs/diagnosis/plugin/rpc/%E7%B3%BB%E7%BB%9F%E7%A8%B3%E5%AE%9A%E6%80%A7%E2%80%94%E2%80%94Dubbo%E5%B8%B8%E8%A7%81%E9%94%99%E8%AF%AF%E5%8F%8A%E8%A7%A3%E5%86%B3%E6%96%B9%E6%B3%95.md) 。 -所引文章通过 [CC-BY-4.0](http://creativecommons.org/licenses/by/4.0/) 协议赋予了汇编的权利。在此向原作者表示感谢。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/6/3.md b/content/zh-cn/overview/mannual/java-sdk/faq/6/3.md deleted file mode 100644 index 60730203dc2e..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/6/3.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/6/3/ - - /zh-cn/docs3-v2/java-sdk/faq/6/3/ -description: 6-3 - 网络连接关闭失败 -linkTitle: 6-3 - 网络连接关闭失败 -title: 6-3 - 网络连接关闭失败 -type: docs -weight: 3 ---- - - - - - - -### 可能的原因 - -非优雅关闭服务,此时服务端可能在对外输出流未完成。 - -### 排查和解决步骤 - -一般为提示类警告信息,不影响后续的程序执行。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/6/4.md b/content/zh-cn/overview/mannual/java-sdk/faq/6/4.md deleted file mode 100644 index 01044b0fa057..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/6/4.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/6/4/ - - /zh-cn/docs3-v2/java-sdk/faq/6/4/ -description: 6-4 - 网络通讯层未知异常 -linkTitle: 6-4 - 网络通讯层未知异常 -title: 6-4 - 网络通讯层未知异常 -type: docs -weight: 4 ---- - - - - - - -### 可能的原因 -> 该错误码的意义已经调整。对于 Dubbo 3.1.4、3.2.0-beta.3 及其之前的版本的该错误码的出错,请参考错误码 [99-0](/zh-cn/overview/mannual/java-sdk/faq/99/0/)。 - -### 排查和解决步骤 -(该错误码目前空缺) \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/6/5.md b/content/zh-cn/overview/mannual/java-sdk/faq/6/5.md deleted file mode 100644 index b207b5cf71db..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/6/5.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/6/5/ - - /zh-cn/docs3-v2/java-sdk/faq/6/5/ -description: 6-5 - 网络连接断开失败 -linkTitle: 6-5 - 网络连接断开失败 -title: 6-5 - 网络连接断开失败 -type: docs -weight: 5 ---- - - - - - - - -### 可能的原因 - -超时是调用端发生在请求发出后,无法在指定的时间内获得对应的响应,出现客户端主动断开连接 - -### 排查和解决步骤 - -一般为提示类警告信息,不影响后续的程序执行。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/6/6.md b/content/zh-cn/overview/mannual/java-sdk/faq/6/6.md deleted file mode 100644 index f0f7fe42f150..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/6/6.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/6/6/ - - /zh-cn/docs3-v2/java-sdk/faq/6/6/ -description: 6-6 - 不支持的消息 -linkTitle: 6-6 - 不支持的消息 -title: 6-6 - 不支持的消息 -type: docs -weight: 6 ---- - - - - - - - -### 可能的原因 - -返回的数据序列化错误,或超出序列化最大值 - -### 排查和解决步骤 - -可通过一些第三方的工具或者 `jstack [PID] > jstack.log` 分析堆栈信息,进行定位。 - -各组件支持的具体配置项及含义请参考 [配置项手册](/zh-cn/overview/mannual/java-sdk/reference-manual/config/properties/) \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/6/7.md b/content/zh-cn/overview/mannual/java-sdk/faq/6/7.md deleted file mode 100644 index cca4df2d1a5c..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/6/7.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/6/7/ - - /zh-cn/docs3-v2/java-sdk/faq/6/7/ -description: 6-7 - 线程连接数超限警告 -linkTitle: 6-7 - 服务端连接失败 -title: 6-7 - 线程连接数超限警告 -type: docs -weight: 7 ---- - - - - - - -### 可能的原因 - -连接数超过限制时的提醒消息,配置或连接数超过配置数的警告提醒。 - -### 排查和解决步骤 - -默认配置项 `connect.queue.warning.size=1000`,可通过配置进行调整。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/6/8.md b/content/zh-cn/overview/mannual/java-sdk/faq/6/8.md deleted file mode 100644 index 18887f69f222..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/6/8.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/6/8/ - - /zh-cn/docs3-v2/java-sdk/faq/6/8/ -description: 6-8 - 返回数据解码失败 -linkTitle: 6-8 - 返回数据解码失败 -title: 6-8 - 返回数据解码失败 -type: docs -weight: 8 ---- - - - - - - - -### 可能的原因 - -返回数据格式错误或解码失败 - -### 排查和解决步骤 - -可通过 debug/warn 日志模式,输出具体服务类名称和返回的消息及堆栈信息。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/6/9.md b/content/zh-cn/overview/mannual/java-sdk/faq/6/9.md deleted file mode 100644 index 9ef4669ad7d7..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/6/9.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/6/9/ - - /zh-cn/docs3-v2/java-sdk/faq/6/9/ -description: 6-9 - 序列号ID存在重复 -linkTitle: 6-9 - 服务端连接失败 -title: 6-9 - 序列号ID存在重复 -type: docs -weight: 9 ---- - - - - - - - -### 可能的原因 - -1. 返回了一个空对象。 -2. 自定义序列号类,`org.apache.dubbo.common.serialize.Serialization#getContentTypeId` 与系统内置存在重复, -此时在加载时,以首个加载到的 SPI 实例为准。其他项将跳过。 - -### 排查和解决步骤 - -1. 检查返回结果。 -2. 内置值可参考类 `org.apache.dubbo.common.serialize.Constants` \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/6/_index.md b/content/zh-cn/overview/mannual/java-sdk/faq/6/_index.md deleted file mode 100644 index 7f6733d5078d..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/6/_index.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/6/ - - /zh-cn/docs3-v2/java-sdk/faq/6/ -description: 6 - 网络传输层 -linkTitle: 6 - 网络传输层 -title: 6 - 网络传输层 -type: docs -weight: 6 ---- diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/7/1.md b/content/zh-cn/overview/mannual/java-sdk/faq/7/1.md deleted file mode 100644 index 260ace9a9e13..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/7/1.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/7/1/ - - /zh-cn/docs3-v2/java-sdk/faq/7/1/ -description: 7-1 - QOS 已关闭 -linkTitle: 7-1 - QOS 已关闭 -title: 7-1 - QOS 已关闭 -type: docs -weight: 1 ---- - - - - - - -### 可能的原因 - -QOS 已关闭 - -### 排查和解决步骤 - - -> 请参考[QOS 操作手册](/zh-cn/overview/mannual/java-sdk/reference-manual/qos/)。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/7/2.md b/content/zh-cn/overview/mannual/java-sdk/faq/7/2.md deleted file mode 100644 index cc9b5db7bedc..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/7/2.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/7/2/ - - /zh-cn/docs3-v2/java-sdk/faq/7/2/ -description: 7-2 - QOS 已开启 -linkTitle: 7-2 - QOS 已开启 -title: 7-2 - QOS 已开启 -type: docs -weight: 2 ---- - - - - - - -### 可能的原因 - -QOS 已开启,默认为开启状态。 - -### 排查和解决步骤 - - -> 请参考[QOS 操作手册](/zh-cn/overview/mannual/java-sdk/reference-manual/qos/)。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/7/3.md b/content/zh-cn/overview/mannual/java-sdk/faq/7/3.md deleted file mode 100644 index 489fca34c168..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/7/3.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/7/3/ - - /zh-cn/docs3-v2/java-sdk/faq/7/3/ -description: 7-3 - 设置超时时间的警告百分比值 -linkTitle: 7-3 - 设置超时时间的警告百分比值 -title: 7-3 - 设置超时时间的警告百分比值 -type: docs -weight: 3 ---- - - - - - - -## 可能的原因 - -QOS 设置超时时间的警告百分比值, 默认为0.75。修改后,控制台会打印此消息。 - -## 排查和解决步骤 - - -请参考 QOS 操作手册[性能采样命令](/zh-cn/overview/mannual/java-sdk/reference-manual/qos/profiler/)。 -

\ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/7/4.md b/content/zh-cn/overview/mannual/java-sdk/faq/7/4.md deleted file mode 100644 index 22f25956b930..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/7/4.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/7/4/ - - /zh-cn/docs3-v2/java-sdk/faq/7/4/ -description: 7-4 - QOS 服务启动失败 -linkTitle: 7-4 - QOS 服务启动失败 -title: 7-4 - QOS 服务启动失败 -type: docs -weight: 4 ---- - - - - - - -### 可能的原因 - -QOS 参数值未正确设置。主要参数有 `qos.host` 和 `qos.port` - -### 排查和解决步骤 - - -> 请参考QOS 操作手册[QOS 概述](/zh-cn/overview/mannual/java-sdk/reference-manual/qos/overview/)。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/7/5.md b/content/zh-cn/overview/mannual/java-sdk/faq/7/5.md deleted file mode 100644 index f95f2946f258..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/7/5.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/7/5/ - - /zh-cn/docs3-v2/java-sdk/faq/7/5/ -description: 7-5 - QOS 命令未找到 -linkTitle: 7-5 - QOS 命令未找到 -title: 7-5 - QOS 命令未找到 -type: docs -weight: 5 ---- - - - - - - -### 可能的原因 - -QOS 命令拼写错误。 - -## 排查和解决步骤 - -QOS 命令不存在。 - -> 请参考 QOS 操作手册[基础命令手册](/zh-cn/overview/mannual/java-sdk/reference-manual/qos/command/)。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/7/6.md b/content/zh-cn/overview/mannual/java-sdk/faq/7/6.md deleted file mode 100644 index d0771f377e42..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/7/6.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/7/6/ - - /zh-cn/docs3-v2/java-sdk/faq/7/6/ -description: 7-6 - QOS 发生未知异常 -linkTitle: 7-6 - QOS 发生未知异常 -title: 7-6 - QOS 发生未知异常 -type: docs -weight: 6 ---- - - - - - - -### 可能的原因 - -QOS 发生未知异常 - -### 排查和解决步骤 - -1. 检查当前请求的服务是否可正常访问。 -2. 可能由于某些原因,未能正确加载或返回 `CommandContext` 实例。可根据控制台的错误提醒信息,进行排查定位。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/7/7.md b/content/zh-cn/overview/mannual/java-sdk/faq/7/7.md deleted file mode 100644 index 837b3c00e31d..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/7/7.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/7/7/ - - /zh-cn/docs3-v2/java-sdk/faq/7/7/ -description: 7-7 - QOS 无权限访问 -linkTitle: 7-7 - QOS 无权限访问 -title: 7-7 - QOS 无权限访问 -type: docs -weight: 7 ---- - - - - - - -### 可能的原因 - -本次 QoS 请求无权限访问对应的资源,通常出现在有恶意攻击的场景下 - -### 排查和解决步骤 - -检查请求是否是预期发生的,如果非预期请检查是否有恶意攻击源。 -> 如果是预期的,请参考 [QoS 安全](/zh-cn/overview/mannual/java-sdk/reference-manual/qos/overview/#%E5%AE%89%E5%85%A8) 一文配置对应的权限信息。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/7/_index.md b/content/zh-cn/overview/mannual/java-sdk/faq/7/_index.md deleted file mode 100644 index decf987dbebb..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/7/_index.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/7/ - - /zh-cn/docs3-v2/java-sdk/faq/7/ -description: 7 - QoS 插件模块 -linkTitle: 7 - QoS 插件模块 -title: 7 - QoS 插件模块 -type: docs -weight: 7 ---- diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/81/1.md b/content/zh-cn/overview/mannual/java-sdk/faq/81/1.md deleted file mode 100644 index 81c2858f8833..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/81/1.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/81/1/ - - /zh-cn/docs3-v2/java-sdk/faq/81/1/ -description: 81-1 - ZK 启动异常 -linkTitle: 81-1 - ZK 启动异常 -title: 81-1 - ZK 启动异常 -type: docs -weight: 1 ---- - - - - - - -### 可能的原因 - -1. zk 的服务端版本与客户端版本存在不兼容问题,无法进行连接。 -2. zk 服务未正常启动或防火墙等原因不能对外提供服务。 - -### 排查和解决步骤 - -1. 确认客户端版本与服务端版本一致。 -2. zk 能够正常启动或对外能够提供正常服务。 - -可通过一些第三方的工具或者`jstack [PID] > jstack.log` 分析堆栈信息,进行定位。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/81/2.md b/content/zh-cn/overview/mannual/java-sdk/faq/81/2.md deleted file mode 100644 index 1d9f641fb83c..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/81/2.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/81/2/ - - /zh-cn/docs3-v2/java-sdk/faq/81/2/ -description: 81-2 - ZK 销毁异常 -linkTitle: 81-2 - ZK 销毁异常 -title: 81-2 - ZK 销毁异常 -type: docs -weight: 2 ---- - - - - - - -### 可能的原因 - -当前实例已销毁完成。 -网络或已断开。 - -### 排查和解决步骤 - -可通过一些第三方的工具或者 `jstack [PID] > jstack.log` 分析堆栈信息,进行定位。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/81/3.md b/content/zh-cn/overview/mannual/java-sdk/faq/81/3.md deleted file mode 100644 index 9965bf51954d..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/81/3.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/81/3/ - - /zh-cn/docs3-v2/java-sdk/faq/81/3/ -description: 81-3 - 通过url无法下载文件 -linkTitle: 81-3 - 通过url无法下载文件 -title: 81-3 - 通过url无法下载文件 -type: docs -weight: 3 ---- - - - - - - -### 可能的原因 - -1. url 映射文件不存在。 -2. url 无法连接。 - -### 排查和解决步骤 - -1. 检查 url 映射文件是否存在。 -2. 通过浏览器或其他工具,能否正常访问。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/81/4.md b/content/zh-cn/overview/mannual/java-sdk/faq/81/4.md deleted file mode 100644 index e4410955707e..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/81/4.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/81/4/ - - /zh-cn/docs3-v2/java-sdk/faq/81/4/ -description: 81-4 - 嵌入式ZooKeeper运行异常 -linkTitle: 81-4 - 嵌入式ZooKeeper运行异常 -title: 81-4 - 嵌入式ZooKeeper运行异常 -type: docs -weight: 4 ---- - - - - - - -### 可能的原因 - -1. ZooKeeper 服务运行异常或宕机。 -2. Zookeeper 客户端版本与服务端启动版本不兼容,无法连接。 -3. 应用服务器与 ZooKeeper 服务连接中断。 -4. 受限防火墙或第三方防护工具。 - -### 排查和解决步骤 - -1. 检查 ZooKeeper 服务及所在服务器健康状态。 -2. 检查 Zookeeper 客户端版本与服务端启动版本是否存在兼容问题,保持版本一致。 -3. 检查应用服务器与 ZooKeeper 服务端口是否通畅。 -4. 检查防火墙或第三方防护工具设置,是否已禁止。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/81/_index.md b/content/zh-cn/overview/mannual/java-sdk/faq/81/_index.md deleted file mode 100644 index a165a18b4845..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/81/_index.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/81/ - - /zh-cn/docs3-v2/java-sdk/faq/81/ -description: 81 - 单元测试辅助模块(注册中心) -linkTitle: 81 - 单元测试辅助模块(注册中心) -title: 81 - 单元测试辅助模块(注册中心) -type: docs -weight: 81 ---- - - - - - - -这里主要是 `dubbo-test` 模块中用于测试注册中心模块的代码的相关错误码。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/99/1.md b/content/zh-cn/overview/mannual/java-sdk/faq/99/1.md deleted file mode 100644 index 7a897c613d5c..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/99/1.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/99/1/ - - /zh-cn/docs3-v2/java-sdk/faq/99/1/ -description: 99-1 - 程序被打断 -linkTitle: 99-1 - 程序被打断 -title: 99-1 - 程序被打断 -type: docs -weight: 2 ---- - - - - - -Dubbo 内部的未知错误。 - -### 可能的原因 - -程序收到来自 JVM 层面的打断通知,被迫停止阻塞等待 - -### 排查和解决步骤 - -此异常通常发生在线程池关闭或者应用关闭的过程中。 -请检查是否影响业务正常使用,如无影响可以忽略,如果有影响请参照对应的排查手册。 -更多的排查思路可以参考 [99-0](../0/) 一文。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/99/_index.md b/content/zh-cn/overview/mannual/java-sdk/faq/99/_index.md deleted file mode 100644 index a34155a24a0b..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/99/_index.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/99/ - - /zh-cn/docs3-v2/java-sdk/faq/99/ -description: 99 - 其它未知错误 -linkTitle: 99 - 其它未知错误 -title: 99 - 其它未知错误 -type: docs -weight: 99 ---- diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/_index.md b/content/zh-cn/overview/mannual/java-sdk/faq/_index.md deleted file mode 100755 index 9dfd2a783956..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/faq/_index.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/faq/ - - /zh-cn/docs3-v2/java-sdk/faq/ -description: 错误码 FAQ -linkTitle: 错误码 FAQ -title: 错误码 FAQ -type: docs -weight: 6 ---- - - - - - - -这里主要是提供 Java SDK 中各个错误码的可能原因和解决方法。 diff --git a/content/zh-cn/overview/mannual/java-sdk/quick-start/_index.md b/content/zh-cn/overview/mannual/java-sdk/quick-start/_index.md index 78185a2d9265..cea661e66260 100755 --- a/content/zh-cn/overview/mannual/java-sdk/quick-start/_index.md +++ b/content/zh-cn/overview/mannual/java-sdk/quick-start/_index.md @@ -2,9 +2,13 @@ aliases: - /zh/docs3-v2/java-sdk/quick-start/ - /zh-cn/docs3-v2/java-sdk/quick-start/ + - /zh/overview/quickstart/java/ + - /zh-cn/overview/quickstart/java/ + - /zh/overview/quickstart/ + - /zh-cn/overview/quickstart/ description: "" linkTitle: 快速入门 title: 快速入门 type: docs -weight: 1 +weight: 2 --- diff --git a/content/zh-cn/overview/mannual/java-sdk/quick-start/api.md b/content/zh-cn/overview/mannual/java-sdk/quick-start/api.md deleted file mode 100644 index 955470c5f4f9..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/quick-start/api.md +++ /dev/null @@ -1,287 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/quick-start/api/ - - /zh-cn/docs3-v2/java-sdk/quick-start/api/ - - /zh/overview/quickstart/java/api/ - - /zh-cn/overview/quickstart/java/api/ -description: 本文将基于 Dubbo Samples 示例演示如何通过 Dubbo API 快速开发微服务应用。 -linkTitle: 基于 Dubbo API 开发微服务应用 -title: 2 - 基于 Dubbo API 开发微服务应用 -type: docs -weight: 2 ---- - - - - - - -## 目标 - -从零上手开发基于 Dubbo 的微服务 - -## 难度 - -低 - -## 环境要求 - -- 系统:Windows、Linux、MacOS - -- JDK 8 及以上(推荐使用 JDK17) - -- Git - -- IntelliJ IDEA(可选) - -- Docker (可选) - -## 动手实践 - -本章将通过手把手的教程一步一步教你如何从零开发一个微服务应用。 - -### 1. 启动注册中心 - -对于一个微服务化的应用来说,注册中心是不可或缺的一个组件。只有通过注册中心,消费端才可以成功发现服务端的地址信息,进而进行调用。 - -为了让本教程更易于上手,我们提供了一个基于 Apache Zookeeper 注册中心的简易启动器,如果您需要在生产环境部署注册中心,请参考[生产环境初始化](/)一文部署高可用的注册中心。 - -```bash -Windows: -git clone --depth=1 --branch master git@github.com:apache/dubbo-samples.git -cd dubbo-samples -./mvnw.cmd clean compile exec:java -pl tools/embedded-zookeeper - -Linux / MacOS: -git clone --depth=1 --branch master git@github.com:apache/dubbo-samples.git -cd dubbo-samples -./mvnw clean compile exec:java -pl tools/embedded-zookeeper - -Docker: -docker run --name some-zookeeper --restart always -d zookeeper -``` - -### 2. 初始化项目 - -从本小节开始,将基于 IntelliJ IDEA 进行工程的搭建以及测试。 - -![img](/imgs/docs3-v2/java-sdk/quickstart/2023-01-31-10-50-33-image.png) - -如上图所示,可以建立一个基础的项目。 - -![img](/imgs/docs3-v2/java-sdk/quickstart/2023-01-31-15-42-11-image.png) - -在初始化完项目之后,需要在 `src/main/java` 目录下创建 `org.apache.dubbo.samples.api` 、`org.apache.dubbo.samples.client` 和 `org.apache.dubbo.samples.provider` 三个 package。 - -后续我们将在 `api` 下创建对应的接口,在 `client` 下创建对应客户端订阅服务的功能,在 `provider` 下创建对应服务端的实现以及发布服务的功能。 - -上述三个 package 分别对应了应用共同依赖的 api、消费端应用的模块、服务端应用的模块。在实际部署中需要拆成三个工程,消费端和服务的共同依赖 api 模块。从简单出发,本教程将在同一个工程中进行开发,区分多个启动类。 - -### 3. 添加 Maven 依赖 - -在初始化完项目以后,我们需要先添加 Dubbo 相关的 maven 依赖。 - -![img](/imgs/docs3-v2/java-sdk/quickstart/2023-01-31-10-51-06-image.png) - -编辑 `pom.xml` 这个文件,添加下列配置。 - -```xml - - - org.apache.dubbo - dubbo - 3.2.0-beta.4 - - - - org.apache.curator - curator-x-discovery - 4.3.0 - - - org.apache.zookeeper - zookeeper - 3.8.0 - - - io.netty - netty-handler - - - io.netty - netty-transport-native-epoll - - - - -``` - -在这份配置中,定义了 dubbo 和 zookeeper(以及对应的连接器 curator)的依赖。 - -![img](/imgs/docs3-v2/java-sdk/quickstart/2023-01-31-16-06-15-image.png) - -添加了上述的配置以后,可以通过 IDEA 的 `Maven - Reload All Maven Projects` 刷新依赖。 - -### 4. 定义服务接口 - -服务接口 Dubbo 中沟通消费端和服务端的桥梁。 - -![img](/imgs/docs3-v2/java-sdk/quickstart/2023-01-31-15-42-43-image.png) - -在 `org.apache.dubbo.samples.api` 下建立 `GreetingsService` 接口,定义如下: - -```java -package org.apache.dubbo.samples.api; - -public interface GreetingsService { - - String sayHi(String name); -} -``` - -在 `GreetingsService` 中,定义了 `sayHi` 这个方法。后续服务端发布的服务,消费端订阅的服务都是围绕着 `GreetingsService` 接口展开的。 - -### 5. 定义服务端的实现 - -定义了服务接口之后,可以在服务端这一侧定义对应的实现,这部分的实现相对于消费端来说是远端的实现,本地没有相关的信息。 - -![img](/imgs/docs3-v2/java-sdk/quickstart/2023-01-31-15-43-34-image.png) - -在 `org.apache.dubbo.samples.provider` 下建立 `GreetingsServiceImpl` 类,定义如下: - -```java -package org.apache.dubbo.samples.provider; - -import org.apache.dubbo.samples.api.GreetingsService; - -public class GreetingsServiceImpl implements GreetingsService { - @Override - public String sayHi(String name) { - return "hi, " + name; - } -} -``` - -在 `GreetingsServiceImpl` 中,实现了 `GreetingsService` 接口,对于 `sayHi` 方法返回 `hi, name`。 - -### 6. 服务端发布服务 - -在实现了服务之后,本小节将通过 Dubbo 的 API 在网络上发布这个服务。 - -![img](/imgs/docs3-v2/java-sdk/quickstart/2023-01-31-15-44-22-image.png) - -在 `org.apache.dubbo.samples.provider` 下建立 `Application` 类,定义如下: - -```java -package org.apache.dubbo.samples.provider; - -import org.apache.dubbo.config.ProtocolConfig; -import org.apache.dubbo.config.RegistryConfig; -import org.apache.dubbo.config.ServiceConfig; -import org.apache.dubbo.config.bootstrap.DubboBootstrap; -import org.apache.dubbo.samples.api.GreetingsService; - -public class Application { - public static void main(String[] args) { - // 定义具体的服务 - ServiceConfig service = new ServiceConfig<>(); - service.setInterface(GreetingsService.class); - service.setRef(new GreetingsServiceImpl()); - - // 启动 Dubbo - DubboBootstrap.getInstance() - .application("first-dubbo-provider") - .registry(new RegistryConfig("zookeeper://127.0.0.1:2181")) - .protocol(new ProtocolConfig("dubbo", -1)) - .service(service) - .start() - .await(); - } -} -``` - -在 `org.apache.dubbo.samples.provider.Application` 中做了两部分的功能:首先是基于 `ServiceConfig` 定义了发布的服务信息,包括接口的信息以及对应的实现类对象;然后是配置 Dubbo 启动器,传入了应用名,注册中心地址,协议的信息以及服务的信息等。 - -注:DubboBootstrap 中的`registry` 、`protocol` 和 `service` 可以多次传入。 - -### 7. 消费端订阅并调用 - -对于消费端,可以通过 Dubbo 的 API 可以进行消费端订阅。 - -![img](/imgs/docs3-v2/java-sdk/quickstart/2023-01-31-15-55-09-image.png) - -在 `org.apache.dubbo.samples.client` 下建立 `Application` 类,定义如下: - -```java -package org.apache.dubbo.samples.client; - -import java.io.IOException; - -import org.apache.dubbo.config.ReferenceConfig; -import org.apache.dubbo.config.RegistryConfig; -import org.apache.dubbo.config.bootstrap.DubboBootstrap; -import org.apache.dubbo.samples.api.GreetingsService; - -public class Application { - public static void main(String[] args) throws IOException { - ReferenceConfig reference = new ReferenceConfig<>(); - reference.setInterface(GreetingsService.class); - - DubboBootstrap.getInstance() - .application("first-dubbo-consumer") - .registry(new RegistryConfig("zookeeper://127.0.0.1:2181")) - .reference(reference); - - GreetingsService service = reference.get(); - String message = service.sayHi("dubbo"); - System.out.println("Receive result ======> " + message); - System.in.read(); - } -} -``` - -在 `org.apache.dubbo.samples.client.Application` 中做了三部分的功能: - -首先是基于 `ReferenceConfig` 定义了订阅的服务信息,包括接口的信息。 - -其次是配置 Dubbo 启动器,传入了应用名,注册中心地址,协议的信息以及服务的信息等。 - -最后是获取到动态代理的对象并进行调用。 - -注:DubboBootstrap 中支持 `service` 和 `reference` 可以同时传入,意味着一个应用可以同时即是消费端、也是服务端。 - -### 8. 启动应用 - -截止第 7 步,代码就已经开发完成了,本小节将启动整个项目并进行验证。 - -![img](/imgs/docs3-v2/java-sdk/quickstart/2023-01-31-15-52-26-image.png) - -首先是启动 `org.apache.dubbo.samples.provider.Application` ,等待一会出现如下图所示的日志(`DubboBootstrap awaiting`)即代表服务提供者启动完毕,标志着该服务提供者可以对外提供服务了。 - -```log -[DUBBO] DubboBootstrap awaiting ..., dubbo version: 3.2.0-beta.4, current host: 169.254.44.42 -``` - -然后是启动`org.apache.dubbo.samples.client.Application` ,等待一会出现如下图所示的日志(`hi, dubbo` )即代表服务消费端启动完毕并调用到服务端成功获取结果。 - -![img](/imgs/docs3-v2/java-sdk/quickstart/2023-01-31-15-54-42-image.png) - -```log -Receive result ======> hi, dubbo -``` - -## 延伸阅读 - -### 1. Dubbo 的配置介绍 - -Dubbo 的主要配置入口有`ReferenceConfig` 、`ServiceConfig` 和 `DubboBootstrap` ,更多的细节可以参考 [API 配置 | Apache Dubbo](/zh-cn/overview/mannual/java-sdk/reference-manual/config/api/) 一文。 - -### 2. 除了 API 方式其他的使用方式 - -Dubbo 除了 API 方式还支持 Spring XML、Annotation、Spring Boot 等配置方式,在下一个教程中将就 Spring Boot 配置方式讲解如何进行快速开发。 - -关于 XML 和 Annotation 的细节可以参考 [XML 配置 | Apache Dubbo](/zh-cn/overview/mannual/java-sdk/reference-manual/config/xml/)、[Annotation 配置 | Apache Dubbo](/zh-cn/overview/mannual/java-sdk/reference-manual/config/annotation/) 疑问。 - -## 更多 - -本教程介绍了如何基于 Dubbo 的纯 API 开发一个微服务应用。下一个教程中,将介绍[如何基于 Spring Boot 开发微服务项目](../spring-boot/)。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/quick-start/brief.md b/content/zh-cn/overview/mannual/java-sdk/quick-start/brief.md deleted file mode 100644 index 32e8507bfbd6..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/quick-start/brief.md +++ /dev/null @@ -1,319 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/quick-start/brief/ - - /zh-cn/docs3-v2/java-sdk/quick-start/brief/ -description: 本文将基于 Dubbo Samples 示例演示如何快速搭建并部署一个微服务应用。 -linkTitle: 快速部署一个微服务应用 -title: 1 - 零基础快速部署一个微服务应用 -type: docs -weight: 1 ---- - - - - - - -## 背景 - -![arch-service-discovery](/imgs/architecture.png) - -Dubbo 作为一款微服务框架,最重要的是向用户提供跨进程的 RPC 远程调用能力。如上图所示,Dubbo 的服务消费者(Consumer)通过一系列的工作将请求发送给服务提供者(Provider)。 - -为了实现这样一个目标,Dubbo 引入了注册中心(Registry)组件,通过注册中心,服务消费者可以感知到服务提供者的连接方式,从而将请求发送给正确的服务提供者。 - -## 目标 - -了解微服务调用的方式以及 Dubbo 的能力 - -## 难度 - -低 - -## 环境要求 - -- 系统:Windows、Linux、MacOS - -- JDK 8 及以上(推荐使用 JDK17) - -- Git - -- Docker (可选) - -## 动手实践 - -本章将通过几个简单的命令,一步一步教你如何部署并运行一个最简单的 Dubbo 用例。 - -### 1. 获取测试工程 - -在开始整个教程之前,我们需要先获取测试工程的代码。Dubbo 的所有测试用例代码都存储在 [apache/dubbo-samples](https://github.com/apache/dubbo-samples) 这个仓库中,以下这个命令可以帮你获取 Samples 仓库的所有代码。 - -```bash -git clone --depth=1 --branch master git@github.com:apache/dubbo-samples.git -``` - -### 2. 认识 Dubbo Samples 项目结构 - -在将 [apache/dubbo-samples](https://github.com/apache/dubbo-samples) 这个仓库 clone 到本地以后,本小节将就仓库的具体组织方式做说明。 - -``` -. -├── codestyle // 开发使用的 style 配置文件 - -├── 1-basic // 基础的入门用例 -├── 2-advanced // 高级用法 -├── 3-extensions // 扩展使用示例 -├── 4-governance // 服务治理用例 -├── 10-task // Dubbo 学习系列示例 - -├── 99-integration // 集成测试使用 -├── test // 集成测试使用 -└── tools // 三方组件快速启动工具 -``` - -如上表所示,[apache/dubbo-samples](https://github.com/apache/dubbo-samples) 主要由三个部分组成:代码风格文件、测试代码、集成测试。 - -1. 代码风格文件是开发 Dubbo 代码的时候可以使用,其中包括了 IntelliJ IDEA 的配置文件。 - -2. 测试代码即本教材所需要的核心内容。目前包括了 5 个部分的内容:面向初学者的 basic 入门用例、面向开发人员的 advanced 高级用法、面向中间件维护者的 extensions Dubbo 周边扩展使用示例、面向生产的 governance 服务治理用例以及 Dubbo 学习系列。本文将基于 basic 入门用例中最简单的 Dubbo API 使用方式进行讲解。 - -3. 集成测试是 Dubbo 的质量保证体系中重要的一环,Dubbo 的每个版本都会对所有的 samples 进行回归验证,保证 Dubbo 的所有变更都不会影响 samples 的使用。 - -### 3. 启动一个简易的注册中心 - -从这一小节开始,将正式通过三个命令部署一个微服务应用。 - -从 [背景](#背景) 一节中可知,运行起 Dubbo 应用的一个大前提是部署一个注册中心,为了让本教程更易于上手,我们提供了一个基于 Apache Zookeeper 注册中心的简易启动器,如果您需要在生产环境部署注册中心,请参考[生产环境初始化](/)一文部署高可用的注册中心。 - -```bash -Windows: -./mvnw.cmd clean compile exec:java -pl tools/embedded-zookeeper - -Linux / MacOS: -./mvnw clean compile exec:java -pl tools/embedded-zookeeper - -注:需要开一个独立的 terminal 运行,命令将会保持一直执行的状态。 - -Docker: -docker run --name some-zookeeper -p 2181:2181 --restart always -d zookeeper -``` - -在执行完上述命令以后,等待一会出现如下图所示的日志即代表注册中心启动完毕,可以继续执行后续任务。 - -![registry](/imgs/docs3-v2/java-sdk/quickstart/2023-01-19-15-55-23-image.png) - -### 4. 启动服务提供者 - -在启动了注册中心之后,下一步是启动一个对外提供服务的服务提供者。在 dubbo-samples 中也提供了对应的示例,可以通过以下命令快速拉起。 - -```bash -Windows: -./mvnw.cmd clean compile exec:java -pl 1-basic/dubbo-samples-api "-Dexec.mainClass=org.apache.dubbo.samples.provider.Application" - -Linux / MacOS: -./mvnw clean compile exec:java -pl 1-basic/dubbo-samples-api -Dexec.mainClass="org.apache.dubbo.samples.provider.Application" - -注:需要开一个独立的 terminal 运行,命令将会保持一直执行的状态。 -``` - -在执行完上述命令以后,等待一会出现如下图所示的日志(`DubboBootstrap awaiting`)即代表服务提供者启动完毕,标志着该服务提供者可以对外提供服务了。 - -![provider](/imgs/docs3-v2/java-sdk/quickstart/2023-01-19-15-56-09-image.png) - -```log -[19/01/23 03:55:49:049 CST] org.apache.dubbo.samples.provider.Application.main() INFO bootstrap.DubboBootstrap: [DUBBO] DubboBootstrap awaiting ..., dubbo version: 3.2.0-beta.3, current host: 169.254.44.42 -``` - -### 5. 启动服务消费者 - -最后一步是启动一个服务消费者来调用服务提供者,也即是 RPC 调用的核心,为服务消费者提供调用服务提供者的桥梁。 - -```bash -Windows: -./mvnw.cmd clean compile exec:java -pl 1-basic/dubbo-samples-api "-Dexec.mainClass=org.apache.dubbo.samples.client.Application" - -Linux / MacOS: -./mvnw clean compile exec:java -pl 1-basic/dubbo-samples-api -Dexec.mainClass="org.apache.dubbo.samples.client.Application" -``` - -在执行完上述命令以后,等待一会出现如下图所示的日志(`hi, dubbo`),打印出的数据就是服务提供者处理之后返回的,标志着一次服务调用的成功。 - -![consumer](/imgs/docs3-v2/java-sdk/quickstart/2023-01-19-16-30-14-image.png) - -```log -Receive result ======> hi, dubbo -``` - -## 延伸阅读 - -### 1. 消费端是怎么找到服务端的? - -在本用例中的步骤 3 启动了一个 Zookeeper 的注册中心,服务提供者会向注册中心中写入自己的地址,供服务消费者获取。 - -Dubbo 会在 Zookeeper 的 `/dubbo/interfaceName` 和 `/services/appName` 下写入服务提供者的连接信息。 - -如下所示是 Zookeeper 上的数据示例: - -``` -[zk: localhost:2181(CONNECTED) 5] ls /dubbo/org.apache.dubbo.samples.api.GreetingsService/providers -[dubbo%3A%2F%2F30.221.146.35%3A20880%2Forg.apache.dubbo.samples.api.GreetingsService%3Fanyhost%3Dtrue%26application%3Dfirst-dubbo-provider%26background%3Dfalse%26deprecated%3Dfalse%26dubbo%3D2.0.2%26dynamic%3Dtrue%26environment%3Dproduct%26generic%3Dfalse%26interface%3Dorg.apache.dubbo.samples.api.GreetingsService%26ipv6%3Dfd00%3A1%3A5%3A5200%3A3218%3A774a%3A4f67%3A2341%26methods%3DsayHi%26pid%3D85639%26release%3D3.1.4%26service-name-mapping%3Dtrue%26side%3Dprovider%26timestamp%3D1674960780647] - -[zk: localhost:2181(CONNECTED) 2] ls /services/first-dubbo-provider -[30.221.146.35:20880] -[zk: localhost:2181(CONNECTED) 3] get /services/first-dubbo-provider/30.221.146.35:20880 -{"name":"first-dubbo-provider","id":"30.221.146.35:20880","address":"30.221.146.35","port":20880,"sslPort":null,"payload":{"@class":"org.apache.dubbo.registry.zookeeper.ZookeeperInstance","id":"30.221.146.35:20880","name":"first-dubbo-provider","metadata":{"dubbo.endpoints":"[{\"port\":20880,\"protocol\":\"dubbo\"}]","dubbo.metadata-service.url-params":"{\"connections\":\"1\",\"version\":\"1.0.0\",\"dubbo\":\"2.0.2\",\"release\":\"3.1.4\",\"side\":\"provider\",\"ipv6\":\"fd00:1:5:5200:3218:774a:4f67:2341\",\"port\":\"20880\",\"protocol\":\"dubbo\"}","dubbo.metadata.revision":"871fbc9cb2730caea9b0d858852d5ede","dubbo.metadata.storage-type":"local","ipv6":"fd00:1:5:5200:3218:774a:4f67:2341","timestamp":"1674960780647"}},"registrationTimeUTC":1674960781893,"serviceType":"DYNAMIC","uriSpec":null} -``` - -更多关于 Dubbo 服务发现模型的细节,可以参考[服务发现](/zh-cn/overview/mannual/java-sdk/concepts-and-architecture/service-discovery/)一文。 - -### 2. 消费端是如何发起请求的? - -在 Dubbo 的调用模型中,起到连接服务消费者和服务提供者的桥梁是接口。 - -服务提供者通过对指定接口进行实现,服务消费者通过 Dubbo 去订阅这个接口。服务消费者调用接口的过程中 Dubbo 会将请求封装成网络请求,然后发送到服务提供者进行实际的调用。 - -在本用例中,定义了一个 `GreetingsService` 的接口,这个接口有一个名为 `sayHi` 的方法。 - -```java -// 1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/api/GreetingsService.java - -package org.apache.dubbo.samples.api; - -public interface GreetingsService { - - String sayHi(String name); - -} -``` - -服务消费者通过 Dubbo 的 API 可以获取这个 `GreetingsService` 接口的代理,然后就可以按照普通的接口调用方式进行调用。**得益于 Dubbo 的动态代理机制,这一切都像本地调用一样。** - -```java -// 1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/client/Application.java - -// 获取订阅到的 Stub -GreetingsService service = reference.get(); -// 像普通的 java 接口一样调用 -String message = service.sayHi("dubbo"); -``` - -### 3. 服务端可以部署多个吗? - -可以,本小节将演示如何启动一个服务端**集群**。 - -1)启动一个注册中心,可以参考动手实践中第 3 小节的[教程](#3-启动一个简易的注册中心) - -2)修改服务提供者返回的数据,让第一个启动的服务提供者返回 `hi, dubbo. I am provider 1.` - -修改 `1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/provider/GreetingsServiceImpl.java` 文件的第 25 行如下所示。 - -```java -// 1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/provider/GreetingsServiceImpl.java - -package org.apache.dubbo.samples.provider; - -import org.apache.dubbo.samples.api.GreetingsService; - -public class GreetingsServiceImpl implements GreetingsService { - @Override - public String sayHi(String name) { - return "hi, " + name + ". I am provider 1."; - } -} -``` - -3)启动第一个服务提供者,可以参考动手实践中第 4 小节的[教程](#4-启动服务提供者) - -4)修改服务提供者返回的数据,让第二个启动的服务提供者返回 `hi, dubbo. I am provider 2.` - -修改 `1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/provider/GreetingsServiceImpl.java` 文件的第 25 行如下所示。 - -```java -// 1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/provider/GreetingsServiceImpl.java - -package org.apache.dubbo.samples.provider; - -import org.apache.dubbo.samples.api.GreetingsService; - -public class GreetingsServiceImpl implements GreetingsService { - @Override - public String sayHi(String name) { - return "hi, " + name + ". I am provider 2."; - } -} -``` - -4)启动第二个服务提供者,可以参考动手实践中第 4 小节的[教程](#4-启动服务提供者) - -5)启动服务消费者,可以参考动手实践中第 5 小节的[教程](#5-启动服务消费者)。多次启动消费者可以看到返回的结果是不一样的。 - -在 dubbo-samples 中也提供了一个会定时发起调用的消费端应用`org.apache.dubbo.samples.client.AlwaysApplication`,可以通过以下命令启动。 - -```bash -Windows: -./mvnw.cmd clean compile exec:java -pl 1-basic/dubbo-samples-api -Dexec.mainClass="org.apache.dubbo.samples.client.AlwaysApplication" - -Linux / MacOS: -./mvnw clean compile exec:java -pl 1-basic/dubbo-samples-api -Dexec.mainClass="org.apache.dubbo.samples.client.AlwaysApplication" -``` - -启动后可以看到类似以下的日志,消费端会随机调用到不同的服务提供者,返回的结果也是远端的服务提供者觉得其结果。 - -``` -Sun Jan 29 11:23:37 CST 2023 Receive result ======> hi, dubbo. I am provider 1. -Sun Jan 29 11:23:38 CST 2023 Receive result ======> hi, dubbo. I am provider 2. -Sun Jan 29 11:23:39 CST 2023 Receive result ======> hi, dubbo. I am provider 2. -Sun Jan 29 11:23:40 CST 2023 Receive result ======> hi, dubbo. I am provider 1. -Sun Jan 29 11:23:41 CST 2023 Receive result ======> hi, dubbo. I am provider 1. -``` - -### 4. 这个用例复杂吗? - -不,Dubbo 只需要简单的配置就可以实现稳定、高效的远程调用。 - -以下是一个服务提供者的简单示例,通过定义若干个配置就可以启动。 - -```java -// 1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/provider/Application.java - -// 定义所有的服务 -ServiceConfig service = new ServiceConfig<>(); -service.setInterface(GreetingsService.class); -service.setRef(new GreetingsServiceImpl()); - -// 启动 Dubbo -DubboBootstrap.getInstance() - .application("first-dubbo-provider") - .registry(new RegistryConfig(ZOOKEEPER_ADDRESS)) - .protocol(new ProtocolConfig("dubbo", -1)) - .service(service) - .start(); -``` - -以下是一个服务消费者的简单示例,通过定义若干个配置启动后就可以获取到对应的代理对象,之后用户完全不需要感知这个对象背后的复杂实现,**一切只需要和本地调用一样就行了**。 - -```java -// 1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/client/Application.java - -// 定义所有的订阅 -ReferenceConfig reference = new ReferenceConfig<>(); -reference.setInterface(GreetingsService.class); - -// 启动 Dubbo -DubboBootstrap.getInstance() - .application("first-dubbo-consumer") - .registry(new RegistryConfig(ZOOKEEPER_ADDRESS)) - .reference(reference) - .start(); - -// 获取订阅到的 Stub -GreetingsService service = reference.get(); -// 像普通的 java 接口一样调用 -String message = service.sayHi("dubbo"); -``` - -## 更多 - -本用例介绍了一个 RPC 远程调用的基础流程,通过启动注册中心、服务提供者、服务消费者三个节点来模拟一个微服务的部署架构。 - -下一个教程中,将就服务提供者和服务消费者分别都做了什么配置进行讲解,[从零告诉你如何搭建一个微服务应用](../api/)。 diff --git a/content/zh-cn/overview/mannual/java-sdk/quick-start/deploy.md b/content/zh-cn/overview/mannual/java-sdk/quick-start/deploy.md new file mode 100644 index 000000000000..2838acfdf28f --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/quick-start/deploy.md @@ -0,0 +1,139 @@ +--- +description: 快速部署Dubbo应用 +linkTitle: 部署Dubbo应用 +title: 快速部署Dubbo应用 +type: docs +toc_hide: true +hide_summary: true +weight: 3 +--- + +在上一篇文章中,我们从头创建了一个 Dubbo 应用并详细介绍了它的代码结构,接下来,我们将学习部署这个 Dubbo 应用。 + +本文将以 Kubernetes 集群作为基础环境来讲解 Dubbo 应用的部署,部署架构如下图所示。 +![Dubbo+Kubernetes+Nacos 部署架构图]() + +{{% alert title="注意" color="info" %}} +在实际使用中,部署环境可能变化多样,包括 Kubernetes Service、服务网格(Service Mesh)、虚拟机等多种部署模式,请参考 [部署文档]() 了解更多详细内容。 +{{% /alert %}} + +## 前置条件 +Dubbo 社区提供了工具和解决方案来简化整个 Kubernetes 环境的打包与部署过程,所以开始前我们需要先安装相关工具。 + +1. 安装 dubboctl(如尚未安装) + ```sh + curl -L https://raw.githubusercontent.com/apache/dubbo-kubernetes/master/release/downloadDubbo.sh | sh - + + cd dubbo-$version + export PATH=$PWD/bin:$PATH + ``` + + +## 部署应用 + +### 初始化微服务集群 + +1. dubboctl 安装完成之后,接下来通过以下命令初始化微服务部署环境 + + ```sh + dubboctl manifest install --profile=demo + ``` + + 作为演示目的,以上命令会一键安装 Zookeeper、Dubbo Control Plane、Prometheus、Grafana、Zipkin、Ingress 等组件,关于 `--profile=demo` 更多解释及配置请参见文档说明。 + +2. 检查环境准备就绪 + + ```sh + kubectl get services -n dubbo-system + ``` + +3. 最后,为目标 kubernetes namespace 开启自动注入模式,以便应用部署后能够自动连接到刚刚安装的 Zookeeper 注册中心等组件。 + + ```shell + kubectl label namespace dubbo-demo dubbo-injection=enabled --overwrite + ``` + +### 部署 Dubbo 应用 + +接下来我们为之前创建的应用打包镜像(请确保本地安装有 Docker 环境并且已经启动 Docker 进程),在应用根目录分别运行以下命令: + +```shell +dubboctl build --dockerfile=./Dockerfile +``` + +`build` 命令会将源码打包为镜像,并推送到远端仓库,取决于网络情况,可能需要一定时间等待命令执行完成。 + +接下来,我们需要生成部署应用的 Kubernetes 资源文件,运行以下命令: +```shell +dubboctl deploy +``` + +`deploy` 命令会使用刚刚 `build` 打包的镜像生成 Kubernetes 资源清单。命令执行成功后,在当前目录看到生成的 `kube.yaml` 文件,其中包括 deployment、service 等 kubernetes 资源定义。 + + +{{% alert title="注意" color="warning" %}} +本地构建可能会花费比较长时间,如您本地构建遇到问题,也可以使用以下命令跳过 `build` 过程。 + +```sh +dubboctl deploy --image=apache/dubbo-demo:quickstart_0.1 +# `--image` 指定使用官方预先准备好的示例镜像 +``` +{{% /alert %}} + +接下来,将应用部署到 Kubernetes 环境。 + +```shell +kubectl apply -f ./kube.yaml +``` + +检查部署状态 +```shell +kubectl get services -n dubbo-demo +``` + +## 访问应用 +部署成功后,可以通过以下方式检查应用状态。 + +{{< tabpane text=true >}} +{{< tab header="请根据情况选择:" disabled=true />}} +{{% tab header="本地 Kubernetes 集群" lang="en" %}} +
+ +1. 如果使用的本地 Kubernetes 集群,请使用以下方式访问应用验证部署状态: + + ```shell + dubboctl dashboard admin + ``` + +2. 以上命令会自动打开 admin 控制台,如果在您的环境下没有打开,请使用浏览器访问以下地址: + + http://localhost:38080/admin + +3. 通过 triple 协议,可以继续测试 Dubbo 服务,执行以下命令进行端口映射: + + ```shell + kubectl port-forward 50051:50051 + ``` + +4. 通过 curl 访问服务: + + ```shell + curl \ + --header "Content-Type: application/json" \ + --data '["Dubbo"]' \ + http://localhost:50051/com.example.demo.dubbo.api.DemoService/sayHello/ + ``` + +{{% /tab %}} + +{{% tab header="阿里云ACK" lang="zh-cn" %}} +
+ +对于云上托管的哦 Kubernetes 集群,可以使用以下方式验证,这里以阿里云 ACK 集群为例: + +ACK ingerss-controller 的访问方式...... + +{{% /tab %}} +{{< /tabpane >}} + + diff --git a/content/zh-cn/overview/mannual/java-sdk/quick-start/idl.md b/content/zh-cn/overview/mannual/java-sdk/quick-start/idl.md deleted file mode 100755 index d64674fd115c..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/quick-start/idl.md +++ /dev/null @@ -1,241 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/quick-start/idl/ - - /zh-cn/docs3-v2/java-sdk/quick-start/idl/ -description: 从零演示如何基于 IDL 方式来定义 Dubbo 服务并使用 Triple 协议 -linkTitle: IDL 定义跨语言服务 -title: 5 - IDL 定义跨语言服务 -type: docs -weight: 11 ---- - - - - - - -使用 IDL 定义服务具有更好的跨语言友好性,对于 Dubbo3 新用户而言,我们推荐使用这种方式。 -然而 Triple 协议并不是和 IDL 强绑定的,也可以使用 Java Interface + Pojo 的方式定义服务并启用 Triple 协议,具体可参见[示例](https://github.com/apache/dubbo-samples/tree/master/3-extensions/protocol/dubbo-samples-triple/src/main/java/org/apache/dubbo/sample/tri/pojo)。 - -更多 Triple 和 IDL 使用方式,请参考[官方示例](https://github.com/apache/dubbo-samples/tree/master/3-extensions/protocol/dubbo-samples-triple) - -### 前置条件 -- [JDK](https://jdk.java.net/) 版本 >= 8 -- 已安装 [Maven](https://maven.apache.org/) - -### 创建工程 -1. 首先创建一个空的 maven 工程 - ``` - $ mvn archetype:generate \ - -DgroupId=org.apache.dubbo \ - -DartifactId=tri-stub-demo \ - -DarchetypeArtifactId=maven-archetype-quickstart \ - -DarchetypeVersion=1.4 \ - -DarchetypeGroupId=org.apache.maven.archetypes \ - -Dversion=1.0-SNAPSHOT - ``` -2. 切换到工程目录 - ``` - $ cd tri-stub-demo - ``` -3. 在 `pom.xml` 中设置 JDK 版本,添加 Dubbo 依赖和插件 - ```xml - - UTF-8 - 1.8 - 1.8 - 3.1.7 - - - - - junit - junit - 4.13 - test - - - org.apache.dubbo - dubbo - ${dubbo.version} - - - org.apache.dubbo - dubbo-dependencies-zookeeper-curator5 - pom - ${dubbo.version} - - - com.google.protobuf - protobuf-java - 3.19.4 - - - - - - - kr.motd.maven - os-maven-plugin - 1.6.1 - - - - - org.xolstice.maven.plugins - protobuf-maven-plugin - 0.6.1 - - com.google.protobuf:protoc:3.19.4:exe:${os.detected.classifier} - - - dubbo - org.apache.dubbo - dubbo-compiler - ${dubbo.version} - org.apache.dubbo.gen.tri.Dubbo3TripleGenerator - - - - - - - compile - - - - - - - ``` -4. 添加接口定义文件`src/main/proto/hello.proto`,Dubbo 使用 [Protobuf](https://developers.google.com/protocol-buffers) 作为 IDL - ```protobuf - syntax = "proto3"; - - option java_multiple_files = true; - option java_package = "org.apache.dubbo.hello"; - option java_outer_classname = "HelloWorldProto"; - option objc_class_prefix = "HLW"; - - package helloworld; - - message HelloRequest { - string name = 1; - } - - message HelloReply { - string message = 1; - } - service Greeter{ - rpc greet(HelloRequest) returns (HelloReply); - } - - ``` -5. 编译 IDL - ``` - $ mvn clean install - ``` - 编译成功后,可以看到`target/generated-sources/protobuf/java` 目录下生成了代码文件 - ``` - $ ls org/apache/dubbo/hello/ - DubboGreeterTriple.java HelloReply.java HelloRequest.java HelloWorldProto.java - Greeter.java HelloReplyOrBuilder.java HelloRequestOrBuilder.java - ``` - -6. 添加服务端接口实现`src/main/java/org/apache/dubbo/GreeterImpl.java` - ```java - package org.apache.dubbo; - - import org.apache.dubbo.hello.DubboGreeterTriple; - import org.apache.dubbo.hello.HelloReply; - import org.apache.dubbo.hello.HelloRequest; - - public class GreeterImpl extends DubboGreeterTriple.GreeterImplBase { - @Override - public HelloReply greet(HelloRequest request) { - return HelloReply.newBuilder() - .setMessage("Hello," + request.getName() + "!") - .build(); - } - } - ``` -7. 添加服务端启动类 `src/main/java/org/apache/dubbo/MyDubboServer.java` - ```java - package org.apache.dubbo; - - import org.apache.dubbo.common.constants.CommonConstants; - import org.apache.dubbo.config.ApplicationConfig; - import org.apache.dubbo.config.ProtocolConfig; - import org.apache.dubbo.config.RegistryConfig; - import org.apache.dubbo.config.ServiceConfig; - import org.apache.dubbo.config.bootstrap.DubboBootstrap; - import org.apache.dubbo.hello.Greeter; - - import java.io.IOException; - - public class MyDubboServer { - - public static void main(String[] args) throws IOException { - ServiceConfig service = new ServiceConfig<>(); - service.setInterface(Greeter.class); - service.setRef(new GreeterImpl()); - - DubboBootstrap bootstrap = DubboBootstrap.getInstance(); - bootstrap.application(new ApplicationConfig("tri-stub-server")) - .registry(new RegistryConfig("zookeeper://127.0.0.1:2181")) - .protocol(new ProtocolConfig(CommonConstants.TRIPLE, 50051)) - .service(service) - .start(); - System.out.println("Dubbo triple stub server started"); - System.in.read(); - } - } - ``` - -8. 添加客户端启动类`src/main/java/org/apache/dubbo/MyDubboClient.java` - ```java - package org.apache.dubbo; - - import org.apache.dubbo.common.constants.CommonConstants; - import org.apache.dubbo.config.ApplicationConfig; - import org.apache.dubbo.config.ReferenceConfig; - import org.apache.dubbo.config.RegistryConfig; - import org.apache.dubbo.config.bootstrap.DubboBootstrap; - import org.apache.dubbo.hello.Greeter; - import org.apache.dubbo.hello.HelloReply; - import org.apache.dubbo.hello.HelloRequest; - - public class MyDubboClient { - public static void main(String[] args) { - DubboBootstrap bootstrap = DubboBootstrap.getInstance(); - ReferenceConfig ref = new ReferenceConfig<>(); - ref.setInterface(Greeter.class); - ref.setProtocol(CommonConstants.TRIPLE); - ref.setProxy(CommonConstants.NATIVE_STUB); - ref.setTimeout(3000); - bootstrap.application(new ApplicationConfig("tri-stub-client")) - .registry(new RegistryConfig("zookeeper://127.0.0.1:2181")) - .reference(ref) - .start(); - - Greeter greeter = ref.get(); - HelloRequest request = HelloRequest.newBuilder().setName("Demo").build(); - HelloReply reply = greeter.greet(request); - System.out.println("Received reply:" + reply); - } - } - ``` -9. 编译代码 - ``` - $ mvn clean install - ``` -10. 启动服务端 - ``` - $ mvn org.codehaus.mojo:exec-maven-plugin:3.0.0:java -Dexec.mainClass="org.apache.dubbo.MyDubboServer" - Dubbo triple stub server started - ``` -11. 打开新的终端,启动客户端 - ``` - $ mvn org.codehaus.mojo:exec-maven-plugin:3.0.0:java -Dexec.mainClass="org.apache.dubbo.MyDubboClient" - Received reply:message: "Hello,Demo!" - ``` diff --git a/content/zh-cn/overview/mannual/java-sdk/quick-start/spring-boot.md b/content/zh-cn/overview/mannual/java-sdk/quick-start/spring-boot.md deleted file mode 100644 index fb81b4509c79..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/quick-start/spring-boot.md +++ /dev/null @@ -1,564 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/quick-start/spring-boot/ - - /zh-cn/docs3-v2/java-sdk/quick-start/spring-boot/ -description: 本文将基于 Dubbo Samples 示例演示如何通过 Dubbo x Spring Boot 快速开发微服务应用。 -linkTitle: 基于 Spring Boot Starter 开发微服务应用 -title: 3 - 基于 Spring Boot Starter 开发微服务应用 -type: docs -weight: 3 ---- - - - - - - -## 目标 - -从零上手开发基于 dubbo-spring-boot-starter 开发微服务,了解 Dubbo x Spring Boot 配置方式。 - -## 难度 - -低 - -## 环境要求 - -- 系统:Windows、Linux、MacOS - -- JDK 8 及以上(推荐使用 JDK17) - -- Git - -- IntelliJ IDEA(可选) - -- Docker (可选) - -## 项目介绍 - -在本任务中,将分为 3 个子模块进行独立开发,模拟生产环境下的部署架构。 - -``` -. // apache/dubbo-samples/1-basic/dubbo-samples-spring-boot -├── dubbo-samples-spring-boot-interface // 共享 API 模块 -├── dubbo-samples-spring-boot-consumer // 消费端模块 -└── dubbo-samples-spring-boot-provider // 服务端模块 -``` - -如上所示,共有 3 个模块,其中 `interface` 模块被 `consumer` 和 `provider` 两个模块共同依赖,存储 RPC 通信使用的 API 接口。 - -``` -. // apache/dubbo-samples/1-basic/dubbo-samples-spring-boot -├── dubbo-samples-spring-boot-interface // 共享 API 模块 -│   ├── pom.xml -│   └── src -│   └── main -│   └── java -│   └── org -│   └── apache -│   └── dubbo -│   └── springboot -│   └── demo -│   └── DemoService.java // API 接口 -├── dubbo-samples-spring-boot-consumer // 消费端模块 -│   ├── pom.xml -│   └── src -│   ├── main -│   │   ├── java -│   │   │   └── org -│   │   │   └── apache -│   │   │   └── dubbo -│   │   │   └── springboot -│   │   │   └── demo -│   │   │   └── consumer -│   │   │   ├── ConsumerApplication.java // 消费端启动类 -│   │   │   └── Task.java // 消费端模拟调用任务 -│   │   └── resources -│   │   └── application.yml // Spring Boot 配置文件 -├── dubbo-samples-spring-boot-provider // 服务端模块 -│   ├── pom.xml -│   └── src -│   └── main -│   ├── java -│   │   └── org -│   │   └── apache -│   │   └── dubbo -│   │   └── springboot -│   │   └── demo -│   │   └── provider -│   │   ├── DemoServiceImpl.java // 服务端实现类 -│   │   └── ProviderApplication.java // 服务端启动类 -│   └── resources -│   └── application.yml // Spring Boot 配置文件 -└── pom.xml -``` - -如上为本教程接下来会使用到的项目的文件结构。 - -## 快速部署(基于 Samples 直接启动) - -本章将通过几个简单的命令,一步一步教你如何部署并运行一个基于 Dubbo x Spring Boot 的用例。 - -注:本章部署的代码细节可以在 [apache/dubbo-samples](https://github.com/apache/dubbo-samples) 这个仓库中 `1-basic/dubbo-samples-spring-boot` 中找到,在下一章中也将展开进行讲解。 - -### 1. 获取测试工程 - -在开始整个教程之前,我们需要先获取测试工程的代码。Dubbo 的所有测试用例代码都存储在 [apache/dubbo-samples](https://github.com/apache/dubbo-samples) 这个仓库中,以下这个命令可以帮你获取 Samples 仓库的所有代码。 - -```bash -git clone --depth=1 --branch master git@github.com:apache/dubbo-samples.git -``` - -### 2. 启动一个简易的注册中心 - -对于一个微服务化的应用来说,注册中心是不可或缺的一个组件。只有通过注册中心,消费端才可以成功发现服务端的地址信息,进而进行调用。 - -为了让本教程更易于上手,我们提供了一个基于 Apache Zookeeper 注册中心的简易启动器,如果您需要在生产环境部署注册中心,请参考[生产环境初始化](/)一文部署高可用的注册中心。 - -```bash -Windows: -./mvnw.cmd clean compile exec:java -pl tools/embedded-zookeeper - -Linux / MacOS: -./mvnw clean compile exec:java -pl tools/embedded-zookeeper - -Docker: -docker run --name some-zookeeper -p 2181:2181 --restart always -d zookeeper -``` - -### 3. 本地打包 API 模块 - -为了成功编译服务端、消费端模块,需要先在本地打包安装 `dubbo-samples-spring-boot-interface` 模块。 - -```bash -./mvnw clean install -pl 1-basic/dubbo-samples-spring-boot -./mvnw clean install -pl 1-basic/dubbo-samples-spring-boot/dubbo-samples-spring-boot-interface -``` - -### 4. 启动服务提供者 - -在启动了注册中心之后,下一步是启动一个对外提供服务的服务提供者。在 dubbo-samples 中也提供了对应的示例,可以通过以下命令快速拉起。 - -```bash -Windows: -./mvnw.cmd clean compile exec:java -pl 1-basic/dubbo-samples-spring-boot/dubbo-samples-spring-boot-provider -Dexec.mainClass="org.apache.dubbo.springboot.demo.provider.ProviderApplication" - -Linux / MacOS: -./mvnw clean compile exec:java -pl 1-basic/dubbo-samples-spring-boot/dubbo-samples-spring-boot-provider -Dexec.mainClass="org.apache.dubbo.springboot.demo.provider.ProviderApplication" - -注:需要开一个独立的 terminal 运行,命令将会保持一直执行的状态。 -``` - -在执行完上述命令以后,等待一会出现如下所示的日志(`Current Spring Boot Application is await`)即代表服务提供者启动完毕,标志着该服务提供者可以对外提供服务了。 - -```log -2023-02-08 17:13:00.357 INFO 80600 --- [lication.main()] o.a.d.c.d.DefaultApplicationDeployer : [DUBBO] Dubbo Application[1.1](dubbo-springboot-demo-provider) is ready., dubbo version: 3.2.0-beta.4, current host: 30.221.128.96 -2023-02-08 17:13:00.369 INFO 80600 --- [lication.main()] o.a.d.s.d.provider.ProviderApplication : Started ProviderApplication in 9.114 seconds (JVM running for 26.522) -2023-02-08 17:13:00.387 INFO 80600 --- [pool-1-thread-1] .b.c.e.AwaitingNonWebApplicationListener : [Dubbo] Current Spring Boot Application is await... -``` - -### 5. 启动服务消费者 - -最后一步是启动一个服务消费者来调用服务提供者,也即是 RPC 调用的核心,为服务消费者提供调用服务提供者的桥梁。 - -```bash -Windows: -./mvnw.cmd clean compile exec:java -pl 1-basic/dubbo-samples-spring-boot/dubbo-samples-spring-boot-consumer -Dexec.mainClass="org.apache.dubbo.springboot.demo.consumer.ConsumerApplication" - -Linux / MacOS: -./mvnw clean compile exec:java -pl 1-basic/dubbo-samples-spring-boot/dubbo-samples-spring-boot-consumer -Dexec.mainClass="org.apache.dubbo.springboot.demo.consumer.ConsumerApplication" -``` - -在执行完上述命令以后,等待一会出现如下所示的日志(`Hello world`),打印出的数据就是服务提供者处理之后返回的,标志着一次服务调用的成功。 - -```log -2023-02-08 17:14:33.045 INFO 80740 --- [lication.main()] o.a.d.s.d.consumer.ConsumerApplication : Started ConsumerApplication in 11.052 seconds (JVM running for 31.62) -Receive result ======> Hello world -2023-02-08 17:14:33.146 INFO 80740 --- [pool-1-thread-1] .b.c.e.AwaitingNonWebApplicationListener : [Dubbo] Current Spring Boot Application is await... -Wed Feb 08 17:14:34 CST 2023 Receive result ======> Hello world -Wed Feb 08 17:14:35 CST 2023 Receive result ======> Hello world -Wed Feb 08 17:14:36 CST 2023 Receive result ======> Hello world -Wed Feb 08 17:14:37 CST 2023 Receive result ======> Hello world -``` - -## 动手实践(从零代码开发版) - -本章将通过手把手的教程一步一步教你如何从零开发一个微服务应用。 - -### 1. 启动注册中心 - -对于一个微服务化的应用来说,注册中心是不可或缺的一个组件。只有通过注册中心,消费端才可以成功发现服务端的地址信息,进而进行调用。 - -为了让本教程更易于上手,我们提供了一个基于 Apache Zookeeper 注册中心的简易启动器,如果您需要在生产环境部署注册中心,请参考[生产环境初始化](/)一文部署高可用的注册中心。 - -```bash -Windows: -git clone --depth=1 --branch master git@github.com:apache/dubbo-samples.git -cd dubbo-samples -./mvnw.cmd clean compile exec:java -pl tools/embedded-zookeeper - -Linux / MacOS: -git clone --depth=1 --branch master git@github.com:apache/dubbo-samples.git -cd dubbo-samples -./mvnw clean compile exec:java -pl tools/embedded-zookeeper - -Docker: -docker run --name some-zookeeper -p 2181:2181 --restart always -d zookeeper -``` - -### 2. 初始化项目 - -从本小节开始,将基于 IntelliJ IDEA 进行工程的搭建以及测试。 - -![img](/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-17-25-27-image.png) - -如上图所示,可以建立一个基础的项目。 - -搭建了基础项目之后,我们还需要创建 `dubbo-spring-boot-demo-interface` 、`dubbo-spring-boot-demo-provider` 和 `dubbo-spring-boot-demo-consumer` 三个子模块。 - -![img](/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-17-27-17-image.png) - -![img](/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-17-26-57-image.png) - -![img](/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-17-27-45-image.png) - -![img](/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-17-28-26-image.png) - -创建了三个子模块之后,需要创建一下几个文件夹: - -1. 在 `dubbo-spring-boot-demo-consumer/src/main/java` 下创建 `org.apache.dubbo.springboot.demo.consumer` package - -2. 在 `dubbo-spring-boot-demo-interface/src/main/java` 下创建 `org.apache.dubbo.springboot.demo` package - -3. 在 `dubbo-spring-boot-demo-provider/src/main/java` 下创建 `org.apache.dubbo.springboot.demo.provider` package - -![img](/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-17-32-50-image.png) - -最终的文件夹参考如上图所示。 - -### 3. 添加 Maven 依赖 - -在初始化完项目以后,我们需要先添加 Dubbo 相关的 maven 依赖。 - -对于多模块项目,首先需要在父项目的 `pom.xml` 里面配置依赖信息。 - -![img](/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-17-53-18-image.png) - -编辑 `./pom.xml` 这个文件,添加下列配置。 - -```xml - - 3.2.0-beta.4 - 2.7.8 - 17 - 17 - UTF-8 - - - - - - - org.springframework.boot - spring-boot-dependencies - ${spring-boot.version} - pom - import - - - - - org.apache.dubbo - dubbo-bom - ${dubbo.version} - pom - import - - - - org.apache.dubbo - dubbo-dependencies-zookeeper-curator5 - ${dubbo.version} - pom - - - - - - - - - - org.springframework.boot - spring-boot-maven-plugin - ${spring-boot.version} - - - - -``` - -然后在 `dubbo-spring-boot-consumer` 和 `dubbo-spring-boot-provider` 两个模块 `pom.xml` 中进行具体依赖的配置。 - -![img](/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-17-52-53-image.png) - -编辑 `./dubbo-spring-boot-consumer/pom.xml` 和 `./dubbo-spring-boot-provider/pom.xml` 这两文件,都添加下列配置。 - -```xml - - - org.apache.dubbo - dubbo-samples-spring-boot-interface - ${project.parent.version} - - - - - org.apache.dubbo - dubbo-spring-boot-starter - - - org.apache.dubbo - dubbo-dependencies-zookeeper-curator5 - pom - - - slf4j-reload4j - org.slf4j - - - - - - - org.springframework.boot - spring-boot-starter - - - -``` - -在这份配置中,定义了 dubbo 和 zookeeper(以及对应的连接器 curator)的依赖。 - -添加了上述的配置以后,可以通过 IDEA 的 `Maven - Reload All Maven Projects` 刷新依赖。 - -### 4. 定义服务接口 - -服务接口 Dubbo 中沟通消费端和服务端的桥梁。 - -![img](/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-17-57-29-image.png) - -在 `dubbo-spring-boot-demo-interface` 模块的 `org.apache.dubbo.samples.api` 下建立 `DemoService` 接口,定义如下: - -```java -package org.apache.dubbo.springboot.demo; - -public interface DemoService { - - String sayHello(String name); -} -``` - -在 `DemoService` 中,定义了 `sayHello` 这个方法。后续服务端发布的服务,消费端订阅的服务都是围绕着 `DemoService` 接口展开的。 - -### 5. 定义服务端的实现 - -定义了服务接口之后,可以在服务端这一侧定义对应的实现,这部分的实现相对于消费端来说是远端的实现,本地没有相关的信息。 - -![img](/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-17-59-46-image.png) - -在`dubbo-spring-boot-demo-provider` 模块的 `org.apache.dubbo.samples.provider` 下建立 `DemoServiceImpl` 类,定义如下: - -```java -package org.apache.dubbo.springboot.demo.provider; - -import org.apache.dubbo.config.annotation.DubboService; -import org.apache.dubbo.springboot.demo.DemoService; - -@DubboService -public class DemoServiceImpl implements DemoService { - - @Override - public String sayHello(String name) { - return "Hello " + name; - } -} -``` - -在 `DemoServiceImpl` 中,实现了 `DemoService` 接口,对于 `sayHello` 方法返回 `Hello name`。 - -注:在`DemoServiceImpl` 类中添加了 `@DubboService` 注解,通过这个配置可以基于 Spring Boot 去发布 Dubbo 服务。 - -### 6. 配置服务端 Yaml 配置文件 - -从本步骤开始至第 7 步,将会通过 Spring Boot 的方式配置 Dubbo 的一些基础信息。 - -首先,我们先创建服务端的配置文件。 - -![img](/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-18-00-24-image.png) - -在 `dubbo-spring-boot-demo-provider` 模块的 `resources` 资源文件夹下建立 `application.yml` 文件,定义如下: - -```yaml -dubbo: - application: - name: dubbo-springboot-demo-provider - protocol: - name: dubbo - port: -1 - registry: - address: zookeeper://${zookeeper.address:127.0.0.1}:2181 -``` - -在这个配置文件中,定义了 Dubbo 的应用名、Dubbo 协议信息、Dubbo 使用的注册中心地址。 - -### 7. 配置消费端 Yaml 配置文件 - -同样的,我们需要创建消费端的配置文件。 - -![img](/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-18-01-03-image.png) - -在 `dubbo-spring-boot-demo-consumer` 模块的 `resources` 资源文件夹下建立 `application.yml` 文件,定义如下: - -```yaml -dubbo: - application: - name: dubbo-springboot-demo-consumer - protocol: - name: dubbo - port: -1 - registry: - address: zookeeper://${zookeeper.address:127.0.0.1}:2181 -``` - -在这个配置文件中,定义了 Dubbo 的应用名、Dubbo 协议信息、Dubbo 使用的注册中心地址。 - -### 8. 基于 Spring 配置服务端启动类 - -除了配置 Yaml 配置文件之外,我们还需要创建基于 Spring Boot 的启动类。 - -首先,我们先创建服务端的启动类。 - -![img](/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-18-01-38-image.png) - -在 `dubbo-spring-boot-demo-provider` 模块的 `org.apache.dubbo.springboot.demo.provider` 下建立 `Application` 类,定义如下: - -```java -package org.apache.dubbo.springboot.demo.provider; - -import org.apache.dubbo.config.spring.context.annotation.EnableDubbo; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -@SpringBootApplication -@EnableDubbo -public class ProviderApplication { - public static void main(String[] args) { - SpringApplication.run(ProviderApplication.class, args); - } -} -``` - -在这个启动类中,配置了一个 `ProviderApplication` 去读取我们前面第 6 步中定义的 `application.yml` 配置文件并启动应用。 - -### 9. 基于 Spring 配置消费端启动类 - -同样的,我们需要创建消费端的启动类。 - -![img](/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-18-02-11-image.png) - -在 `dubbo-spring-boot-demo-consumer` 模块的 `org.apache.dubbo.springboot.demo.consumer` 下建立 `Application` 类,定义如下: - -```java -package org.apache.dubbo.springboot.demo.consumer; - -import org.apache.dubbo.config.spring.context.annotation.EnableDubbo; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -@SpringBootApplication -@EnableDubbo -public class ConsumerApplication { - - public static void main(String[] args) { - SpringApplication.run(ConsumerApplication.class, args); - } -} -``` - -在这个启动类中,配置了一个 `ConsumerApplication` 去读取我们前面第 7 步中定义的 `application.yml` 配置文件并启动应用。 - -### 10. 配置消费端请求任务 - -除了配置消费端的启动类,我们在 Spring Boot 模式下还可以基于 `CommandLineRunner`去创建 - -![img](/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-18-02-33-image.png) - -在 `dubbo-spring-boot-demo-consumer` 模块的 `org.apache.dubbo.springboot.demo.consumer` 下建立 `Task` 类,定义如下: - -```java -package org.apache.dubbo.springboot.demo.consumer; - -import java.util.Date; - -import org.apache.dubbo.config.annotation.DubboReference; -import org.apache.dubbo.springboot.demo.DemoService; -import org.springframework.boot.CommandLineRunner; -import org.springframework.stereotype.Component; - -@Component -public class Task implements CommandLineRunner { - @DubboReference - private DemoService demoService; - - @Override - public void run(String... args) throws Exception { - String result = demoService.sayHello("world"); - System.out.println("Receive result ======> " + result); - - new Thread(()-> { - while (true) { - try { - Thread.sleep(1000); - System.out.println(new Date() + " Receive result ======> " + demoService.sayHello("world")); - } catch (InterruptedException e) { - e.printStackTrace(); - Thread.currentThread().interrupt(); - } - } - }).start(); - } -} -``` - -在 `Task` 类中,通过`@DubboReference` 从 Dubbo 获取了一个 RPC 订阅,这个 `demoService` 可以像本地调用一样直接调用。在 `run`方法中创建了一个线程进行调用。 - -### 11. 启动应用 - -截止第 10 步,代码就已经开发完成了,本小节将启动整个项目并进行验证。 - -![img](/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-18-03-59-image.png) - -首先是启动 `org.apache.dubbo.samples.provider.Application` ,等待一会出现如下图所示的日志(`Current Spring Boot Application is await`)即代表服务提供者启动完毕,标志着该服务提供者可以对外提供服务了。 - -```log -[Dubbo] Current Spring Boot Application is await... -``` - -然后是启动`org.apache.dubbo.samples.client.Application` ,等待一会出现如下图所示的日志(`Hello world` )即代表服务消费端启动完毕并调用到服务端成功获取结果。 - -![img](/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-18-05-02-image.png) - -```log -Receive result ======> Hello world -``` - -## 延伸阅读 - -### 1. Dubbo 的 Spring 配置介绍 - -Dubbo 的主要配置入口有 yaml 的配置内容、`@DubboReference` 和`@DubboService` 等,更多的细节可以参考 [Annotation 配置 | Apache Dubbo](/zh-cn/overview/mannual/java-sdk/reference-manual/config/annotation/) 一文。 - -## 更多 - -本教程介绍了如何基于 Dubbo x Spring Boot 开发一个微服务应用。在下一节中,将介绍[另外一种 Dubbo 的配置方式 —— Dubbo x Spring XML](../spring-xml/)。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/quick-start/spring-xml.md b/content/zh-cn/overview/mannual/java-sdk/quick-start/spring-xml.md deleted file mode 100644 index ab7c1320570c..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/quick-start/spring-xml.md +++ /dev/null @@ -1,403 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/quick-start/spring-xml/ - - /zh-cn/docs3-v2/java-sdk/quick-start/spring-xml/ - - /zh/overview/quickstart/java/spring-xml/ - - /zh-cn/overview/quickstart/java/spring-xml/ -description: 本文将基于 Dubbo Samples 示例演示如何通过 Dubbo x Spring XML 快速开发微服务应用。 -linkTitle: 基于 Spring XML 开发微服务应用 -title: 4 - 基于 Spring XML 开发微服务应用 -type: docs -weight: 4 ---- - - - - - - -## 目标 - -从零上手开发基于 Dubbo x Spring XML 的微服务开发,了解 Dubbo x Spring XML 配置方式。 - -## 难度 - -低 - -## 环境要求 - -- 系统:Windows、Linux、MacOS - -- JDK 8 及以上(推荐使用 JDK17) - -- Git - -- IntelliJ IDEA(可选) - -- Docker (可选) - -## 快速部署(基于 Samples 直接启动) - -本章将通过几个简单的命令,一步一步教你如何部署并运行一个基于 Dubbo x Spring XML 的用例。 - -注:本章部署的代码细节可以在 [apache/dubbo-samples](https://github.com/apache/dubbo-samples) 这个仓库中 `1-basic/dubbo-samples-spring-xml` 中找到,在下一章中也将展开进行讲解。 - -### 1. 获取测试工程 - -在开始整个教程之前,我们需要先获取测试工程的代码。Dubbo 的所有测试用例代码都存储在 [apache/dubbo-samples](https://github.com/apache/dubbo-samples) 这个仓库中,以下这个命令可以帮你获取 Samples 仓库的所有代码。 - -```bash -git clone --depth=1 --branch master git@github.com:apache/dubbo-samples.git -``` - -### 2. 启动一个简易的注册中心 - -对于一个微服务化的应用来说,注册中心是不可或缺的一个组件。只有通过注册中心,消费端才可以成功发现服务端的地址信息,进而进行调用。 - -为了让本教程更易于上手,我们提供了一个基于 Apache Zookeeper 注册中心的简易启动器,如果您需要在生产环境部署注册中心,请参考[生产环境初始化](/)一文部署高可用的注册中心。 - -```bash -Windows: -./mvnw.cmd clean compile exec:java -pl tools/embedded-zookeeper - -Linux / MacOS: -./mvnw clean compile exec:java -pl tools/embedded-zookeeper - -Docker: -docker run --name some-zookeeper -p 2181:2181 --restart always -d zookeeper -``` - -### 3. 启动服务提供者 - -在启动了注册中心之后,下一步是启动一个对外提供服务的服务提供者。在 dubbo-samples 中也提供了对应的示例,可以通过以下命令快速拉起。 - -```bash -Windows: -./mvnw.cmd clean compile exec:java -pl 1-basic/dubbo-samples-spring-xml -Dexec.mainClass="org.apache.dubbo.samples.provider.Application" - -Linux / MacOS: -./mvnw clean compile exec:java -pl 1-basic/dubbo-samples-spring-xml -Dexec.mainClass="org.apache.dubbo.samples.provider.Application" - -注:需要开一个独立的 terminal 运行,命令将会保持一直执行的状态。 -``` - -在执行完上述命令以后,等待一会出现如下所示的日志(`Dubbo Application[1.1](demo-provider) is ready.`)即代表服务提供者启动完毕,标志着该服务提供者可以对外提供服务了。 - -```log -[08/02/23 03:26:52:052 CST] org.apache.dubbo.samples.provider.Application.main() INFO metadata.ConfigurableMetadataServiceExporter: [DUBBO] The MetadataService exports urls : [dubbo://30.221.128.96:20880/org.apache.dubbo.metadata.MetadataService?anyhost=true&application=demo-provider&background=false&bind.ip=30.221.128.96&bind.port=20880&connections=1&corethreads=2&delay=0&deprecated=false&dubbo=2.0.2&dynamic=true&executes=100&generic=false&getAndListenInstanceMetadata.1.callback=true&getAndListenInstanceMetadata.return=true&getAndListenInstanceMetadata.sent=true&group=demo-provider&interface=org.apache.dubbo.metadata.MetadataService&ipv6=fd00:1:5:5200:4d53:9f5:a545:804d&methods=exportInstanceMetadata,getAndListenInstanceMetadata,getExportedServiceURLs,getExportedURLs,getExportedURLs,getExportedURLs,getExportedURLs,getExportedURLs,getInstanceMetadataChangedListenerMap,getMetadataInfo,getMetadataInfos,getMetadataURL,getServiceDefinition,getServiceDefinition,getSubscribedURLs,isMetadataService,serviceName,toSortedStrings,toSortedStrings,version&pid=70803®ister=false&release=3.1.6&revision=3.1.6&side=provider&threadpool=cached&threads=100×tamp=1675841212727&version=1.0.0], dubbo version: 3.1.6, current host: 30.221.128.96 -[08/02/23 03:26:52:052 CST] org.apache.dubbo.samples.provider.Application.main() INFO metadata.ServiceInstanceMetadataUtils: [DUBBO] Start registering instance address to registry., dubbo version: 3.1.6, current host: 30.221.128.96 -[08/02/23 03:26:52:052 CST] org.apache.dubbo.samples.provider.Application.main() INFO metadata.MetadataInfo: [DUBBO] metadata revision changed: null -> 602d44cc6d653b9cd42ab23c3948b5ab, app: demo-provider, services: 1, dubbo version: 3.1.6, current host: 30.221.128.96 -[08/02/23 03:26:52:052 CST] org.apache.dubbo.samples.provider.Application.main() INFO deploy.DefaultApplicationDeployer: [DUBBO] Dubbo Application[1.1](demo-provider) is ready., dubbo version: 3.1.6, current host: 30.221.128.96 -``` - -### 4. 启动服务消费者 - -最后一步是启动一个服务消费者来调用服务提供者,也即是 RPC 调用的核心,为服务消费者提供调用服务提供者的桥梁。 - -```bash -Windows: -./mvnw.cmd clean compile exec:java -pl 1-basic/dubbo-samples-spring-xml -Dexec.mainClass="org.apache.dubbo.samples.client.Application" - -Linux / MacOS: -./mvnw clean compile exec:java -pl 1-basic/dubbo-samples-spring-xml -Dexec.mainClass="org.apache.dubbo.samples.client.Application" -``` - -在执行完上述命令以后,等待一会出现如下所示的日志(`hi, dubbo`),打印出的数据就是服务提供者处理之后返回的,标志着一次服务调用的成功。 - -```log -[08/02/23 03:28:23:023 CST] org.apache.dubbo.samples.client.Application.main() INFO deploy.DefaultApplicationDeployer: [DUBBO] Dubbo Application[1.1](demo-consumer) is ready., dubbo version: 3.1.6, current host: 30.221.128.96 -Receive result ======> hi, dubbo -``` - -## 动手实践(从零代码开发版) - -本章将通过手把手的教程一步一步教你如何从零开发一个微服务应用。 - -### 1. 启动注册中心 - -对于一个微服务化的应用来说,注册中心是不可或缺的一个组件。只有通过注册中心,消费端才可以成功发现服务端的地址信息,进而进行调用。 - -为了让本教程更易于上手,我们提供了一个基于 Apache Zookeeper 注册中心的简易启动器,如果您需要在生产环境部署注册中心,请参考[生产环境初始化](/)一文部署高可用的注册中心。 - -```bash -Windows: -git clone --depth=1 --branch master git@github.com:apache/dubbo-samples.git -cd dubbo-samples -./mvnw.cmd clean compile exec:java -pl tools/embedded-zookeeper - -Linux / MacOS: -git clone --depth=1 --branch master git@github.com:apache/dubbo-samples.git -cd dubbo-samples -./mvnw clean compile exec:java -pl tools/embedded-zookeeper - -Docker: -docker run --name some-zookeeper -p 2181:2181 --restart always -d zookeeper -``` - -### 2. 初始化项目 - -从本小节开始,将基于 IntelliJ IDEA 进行工程的搭建以及测试。 - -![img](/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-15-32-16-image.png) - -如上图所示,可以建立一个基础的项目。 - -![img](/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-15-33-20-image.png) - -在初始化完项目之后,需要在 `src/main/java` 目录下创建 `org.apache.dubbo.samples.api` 、`org.apache.dubbo.samples.client` 和 `org.apache.dubbo.samples.provider` 三个 package。 - -后续我们将在 `api` 下创建对应的接口,在 `client` 下创建对应客户端订阅服务的功能,在 `provider` 下创建对应服务端的实现以及发布服务的功能。 - -上述三个 package 分别对应了应用共同依赖的 api、消费端应用的模块、服务端应用的模块。在实际部署中需要拆成三个工程,消费端和服务的共同依赖 api 模块。从简单出发,本教程将在同一个工程中进行开发,区分多个启动类。 - -### 3. 添加 Maven 依赖 - -在初始化完项目以后,我们需要先添加 Dubbo 相关的 maven 依赖。 - -![img](/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-15-36-57-image.png) - -编辑 `pom.xml` 这个文件,添加下列配置。 - -```xml - - - org.apache.dubbo - dubbo - 3.1.6 - - - - org.springframework - spring-context - 5.3.25 - - - - org.apache.curator - curator-x-discovery - 5.2.0 - - - org.apache.zookeeper - zookeeper - 3.8.0 - - -``` - -在这份配置中,定义了 dubbo 和 zookeeper(以及对应的连接器 curator)的依赖。 - -![img](/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-15-36-31-image.png) - -添加了上述的配置以后,可以通过 IDEA 的 `Maven - Reload All Maven Projects` 刷新依赖。 - -### 4. 定义服务接口 - -服务接口 Dubbo 中沟通消费端和服务端的桥梁。 - -![img](/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-15-37-31-image.png) - -在 `org.apache.dubbo.samples.api` 下建立 `GreetingsService` 接口,定义如下: - -```java -package org.apache.dubbo.samples.api; - -public interface GreetingsService { - - String sayHi(String name); -} -``` - -在 `GreetingsService` 中,定义了 `sayHi` 这个方法。后续服务端发布的服务,消费端订阅的服务都是围绕着 `GreetingsService` 接口展开的。 - -### 5. 定义服务端的实现 - -定义了服务接口之后,可以在服务端这一侧定义对应的实现,这部分的实现相对于消费端来说是远端的实现,本地没有相关的信息。 - -![img](/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-15-38-04-image.png) - -在 `org.apache.dubbo.samples.provider` 下建立 `GreetingsServiceImpl` 类,定义如下: - -```java -package org.apache.dubbo.samples.provider; - -import org.apache.dubbo.samples.api.GreetingsService; - -public class GreetingsServiceImpl implements GreetingsService { - @Override - public String sayHi(String name) { - return "hi, " + name; - } -} -``` - -在 `GreetingsServiceImpl` 中,实现了 `GreetingsService` 接口,对于 `sayHi` 方法返回 `hi, name`。 - -### 6. 配置服务端 XML 配置文件 - -从本步骤开始至第 7 步,将会通过 Spring XML 的方式配置 Dubbo 服务的信息。 - -首先,我们先创建服务端的配置文件。 - -![img](/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-15-40-07-image.png) - -在 `resources` 资源文件夹下建立 `dubbo-demo-provider.xml` 文件,定义如下: - -```xml - - - - - - - - - - - - - - - - -``` - -在这个配置文件中,定义了 Dubbo 的应用名、Dubbo 使用的注册中心地址、发布服务的 spring bean 以及通过 Dubbo 去发布这个 bean。 - -### 7. 配置消费端 XML 配置文件 - -同样的,我们需要创建消费端的配置文件。 - -![img](/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-15-40-59-image.png) - -在 `resources` 资源文件夹下建立 `dubbo-demo-consumer.xml` 文件,定义如下: - -```xml - - - - - - - - - - - - - - - -``` - -在这个配置文件中,定义了 Dubbo 的应用名、Dubbo 使用的注册中心地址、订阅的服务信息。 - -### 8. 基于 Spring 配置服务端启动类 - -除了配置 XML 配置文件之外,我们还需要创建基于 Spring Context 的启动类。 - -首先,我们先创建服务端的启动类。 - -![img](/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-15-46-49-image.png) - -在 `org.apache.dubbo.samples.provider` 下建立 `Application` 类,定义如下: - -```java -package org.apache.dubbo.samples.provider; - -import java.util.concurrent.CountDownLatch; - -import org.springframework.context.support.ClassPathXmlApplicationContext; - -public class Application { - - public static void main(String[] args) throws InterruptedException { - ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("dubbo-demo-provider.xml"); - context.start(); - - // 挂起主线程,防止退出 - new CountDownLatch(1).await(); - } -} -``` - -在这个启动类中,配置了一个 `ClassPathXmlApplicationContext` 去读取我们前面第 6 步中定义的 `dubbo-demo-provider.xml` 配置文件。 - -### 9. 基于 Spring 配置消费端启动类 - -同样的,我们需要创建消费端的启动类。 - -![img](/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-15-48-26-image.png) - -在 `org.apache.dubbo.samples.client` 下建立 `Application` 类,定义如下: - -```java -package org.apache.dubbo.samples.client; - -import java.io.IOException; - -import org.apache.dubbo.samples.api.GreetingsService; -import org.springframework.context.support.ClassPathXmlApplicationContext; - -public class Application { - public static void main(String[] args) throws IOException { - ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("dubbo-demo-consumer.xml"); - context.start(); - GreetingsService greetingsService = (GreetingsService) context.getBean("greetingsService"); - - String message = greetingsService.sayHi("dubbo"); - System.out.println("Receive result ======> " + message); - System.in.read(); - System.exit(0); - } - -} -``` - -在这个启动类中,主要执行了三个功能: - -1. 配置了一个 `ClassPathXmlApplicationContext` 去读取我们前面第 7 步中定义的 `dubbo-demo-consumer.xml` 配置文件 - -2. 从 Spring Context 中获取名字为 `greetingsService` 的由 Dubbo 创建的 bean - -3. 通过这个 bean 对远端发起调用 - -### 10. 启动应用 - -截止第 9 步,代码就已经开发完成了,本小节将启动整个项目并进行验证。 - -![img](/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-16-01-29-image.png) - -首先是启动 `org.apache.dubbo.samples.provider.Application` ,等待一会出现如下图所示的日志(`Dubbo Application[1.1](demo-provider) is ready`)即代表服务提供者启动完毕,标志着该服务提供者可以对外提供服务了。 - -```log -[DUBBO] Dubbo Application[1.1](demo-provider) is ready., dubbo version: 3.1.6, current host: 30.221.128.96 -``` - -然后是启动`org.apache.dubbo.samples.client.Application` ,等待一会出现如下图所示的日志(`hi, dubbo` )即代表服务消费端启动完毕并调用到服务端成功获取结果。 - -![img](/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-16-02-50-image.png) - -```log -Receive result ======> hi, dubbo -``` - -## 延伸阅读 - -### 1. Dubbo 的 XML 配置介绍 - -Dubbo 的主要配置入口有`dubbo:application` 、`dubbo:registry` 、 `dubbo:reference` 和 `dubbo:service` 等,更多的细节可以参考 [XML 配置 | Apache Dubbo](/zh-cn/overview/mannual/java-sdk/reference-manual/config/xml/) 一文。 - -## 更多 - -本教程介绍了如何基于 Dubbo x Spring XML 开发一个微服务应用。至此,Dubbo 基于 API、Spring Boot、Spring XML 三种主要的启动方式都已经介绍完毕。 - -在下一节中,将介绍[基于 Protobuf IDL 配置的微服务开发方式](../idl/)。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/quick-start/starter.md b/content/zh-cn/overview/mannual/java-sdk/quick-start/starter.md new file mode 100644 index 000000000000..214c15a55c31 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/quick-start/starter.md @@ -0,0 +1,178 @@ +--- +aliases: + - /zh/docs3-v2/java-sdk/reference-manual/config/overview/ + - /zh-cn/docs3-v2/java-sdk/reference-manual/config/overview/ + - /zh-cn/overview/mannual/java-sdk/quick-start/spring-boot/ +description: 创建基于Spring Boot的Dubbo应用。 +linkTitle: 创建基于Spring Boot的Dubbo应用 +title: 创建基于Spring Boot的微服务应用 +type: docs +weight: 2 +--- + +以下文档将引导您从头创建一个基于 Spring Boot 的 Dubbo 应用,并为应用配置 Triple 通信协议、服务发现等微服务基础能力。 + +## 快速创建应用 +通过访问 start.dubbo.apache.org 在线服务创建 Dubbo 微服务应用。如下图所示依次添加组件,您可以在几十秒之内快速创建一个 Dubbo 应用。下载生成的示例应用并解压源码即可。 + +项目结构截图 + +{{% alert title="直接使用官方准备好的示例" color="info" %}} +您还可以直接下载官方预先准备好的示例项目: + +```shell +$ git clone -b main --depth 1 https://github.com/apache/dubbo-samples +$ cd dubbo-samples/11-quickstart +```` +{{% /alert %}} + +## 本地启动应用 +接下来,让我们尝试在本地启动应用。运行以下命令启动应用: + +```shell +./mvnw +``` + +{{% alert title="注意" color="warning" %}} +由于配置文件中启用了注册中心,为了能够成功启动应用,您需要首先在本地启动 NacosZookeeper 注册中心 server。 +{{% /alert %}} + + +在应用启动成功后,本地进程使用 Triple 协议在指定端口发布了服务,可直接使用 cURL 测试服务是否已经正常运行: + +```shell +curl \ + --header "Content-Type: application/json" \ + --data '["Dubbo"]' \ + http://localhost:50051/com.example.demo.dubbo.api.DemoService/sayHello/ +``` + +除了使用命令行之外,我们还可以在 IDE 中启动项目,调整示例或进行本地 debug。 + +## 源码解析 +将以上准备好的示例项目导入最喜欢的 IDE 开发工具(以 IntelliJ IDEA 为例),项目结构如下: + +项目结构截图 + +### Maven 依赖 +打开 pom.xml,可以看到示例项目中 Dubbo 相关核心依赖如下: + +```xml + + + + org.apache.dubbo + dubbo-bom + 3.3.0 + pom + import + + + + + + + org.apache.dubbo + dubbo-spring-boot-starter + + + org.apache.dubbo + dubbo-zookeeper-spring-boot-starter + + +``` + +其中,`dubbo-spring-boot-starter`、`dubbo-zookeeper-spring-boot-starter` 分别为我们引入了 Dubbo 内核框架与 Zookeeper 客户端相关的依赖组件,更多内容可以查看 [Dubbo 支持的 Spring Boot Starter 清单]() 。 + +### 服务定义 + +以下是基于 Java Interface 的标准 Dubbo 服务定义。 + +```java +public interface DemoService { + String sayHello(String name); +} +``` + +在 `DemoService` 中,定义了 `sayHello` 这个方法。后续服务端发布的服务,消费端订阅的服务都是围绕着 `DemoService` 接口展开的。 + +### 服务实现 + +定义了服务接口之后,可以在服务端这一侧定义对应的业务逻辑实现。 + +```java +@DubboService +public class DemoServiceImpl implements DemoService { + @Override + public String sayHello(String name) { + return "Hello " + name; + } +} +``` + +在`DemoServiceImpl` 类中添加了 `@DubboService` 注解,通过这个配置可以基于 Spring Boot 去发布 Dubbo 服务。 + +### 发起服务调用 +示例应用中有一个 consumer 包,用于模拟发起对 provider 服务的远程调用。 + +```java +@Component +public class Consumer implements CommandLineRunner { + @DubboReference + private DemoService demoService; + + @Override + public void run(String... args) throws Exception { + String result = demoService.sayHello("world"); + System.out.println("Receive result ======> " + result); + } +} +``` + +在 `Task` 类中,通过`@DubboReference` 从 Dubbo 获取了一个 RPC 订阅,这个 `demoService` 可以像本地调用一样直接调用: `demoService.sayHello("world")`。 + +{{% alert title="提示" color="primary" %}} +通常远程调用是跨进程的,示例项目为了方便开发,直接内置了一个 `@DubboReference` 调用。如果您想学习如何开发一个独立的 Consumer(客户端)进程,以便发起对 Dubbo 服务的远程调用,我们有一个 包含独立 consumer、provider 模块的示例项目 可供参考。 +{{% /alert %}} + +### 应用入口与配置文件 + +由于我们创建的是一个 Spring Boot 应用,Dubbo 相关配置信息都存放在 `application.yml` 配置文件中。基于以下配置,Dubbo 进程将在 50051 端口监听 triple 协议请求,同时,实例的 ip:port 信息将会被注册到 Zookeeper server。 + +```yaml +# application.yml +dubbo: + application: + name: dubbo-demo + protocol: + name: tri + port: 50051 + registry: + address: zookeeper://${zookeeper.address:127.0.0.1}:2181 +``` + +以下是整个应用的启动入口,`@EnableDubbo` 注解用来加载和启动 Dubbo 相关组件。 + +```java +@SpringBootApplication +@EnableDubbo +public class DemoApplication { + public static void main(String[] args) { + SpringApplication.run(DemoApplication.class, args); + } +} +``` + +## 发布服务定义到远端仓库 + +应用开发完成后,我们需要将服务定义发布到外部公开的或组织内部的 maven 仓库,以便调用这些服务的应用能够加载并使用这些服务。 + +如之前我们看到的,示例项目包含 api、service 两个模块,切换项目到 api 目录,以下命令即可完成发布动作: + +```shell +mvn clean deploy +``` + +## 更多内容 +- 接下来,可以 [快速部署 Dubbo 应用到微服务集群]() +- Dubbo 内置服务发现、负载均衡、流量管控规则等能力,学习 [如何配置更多服务治理能力]() diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/_index.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/_index.md index 3c7d717219d4..8d05c7706e1e 100755 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/_index.md +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/_index.md @@ -2,9 +2,10 @@ aliases: - /zh/docs3-v2/java-sdk/reference-manual/ - /zh-cn/docs3-v2/java-sdk/reference-manual/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/ description: 参考手册 linkTitle: 参考手册 title: 参考手册 type: docs -weight: 4 +weight: 5 --- diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/architecture/_index.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/architecture/_index.md index 9c27e5b673d2..920b0022d463 100755 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/architecture/_index.md +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/architecture/_index.md @@ -7,5 +7,5 @@ description: 概念和架构 linkTitle: 源码架构 title: 源码架构 type: docs -weight: 2 +weight: 100 --- diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/dubbo-spi.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/architecture/dubbo-spi.md similarity index 78% rename from content/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/dubbo-spi.md rename to content/zh-cn/overview/mannual/java-sdk/reference-manual/architecture/dubbo-spi.md index ae9014a0b7cf..0d0487980895 100644 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/dubbo-spi.md +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/architecture/dubbo-spi.md @@ -9,32 +9,63 @@ type: docs weight: 0 --- +## 1. Dubbo SPI 扩展简介 +Dubbo 中的扩展机制与 JDK 标准的 SPI 扩展点 原理类似。Dubbo 对其做了一定的改造与加强: +* JDK 标准的 SPI 会一次性实例化扩展点所有实现,如果有扩展实现初始化很耗时,但如果没用上也加载,会很浪费资源。 +* 如果扩展点加载失败,JDK SPI 没给出详细信息,不方便定位问题,Dubbo SPI 在失败时记录真正的失败原因,并打印出来 +* 增加 [IOC](#23-ioc-机制)、[AOP](#24-aop-机制) 能力 +* 增加排序能力 +* 增加条件激活能力 +* 提供了一系列更灵活的 API,如[获取所有 SPI 扩展实现](./#21-按名称获取指定扩展类)、[根据名称查询某个扩展实现](./#211-获取所有拓展类)、根据类型查询扩展实现、查询匹配条件的扩展实现等。 +### 1.1 SPI定义 +Dubbo 中的 SPI 插件是标准的 Java Interface 定义,并且必须包含 `@org.apache.dubbo.common.extension.SPI` 注解: -## 1. Dubbo SPI 扩展简介 +```java +@SPI(value = "dubbo", scope = ExtensionScope.FRAMEWORK) +public interface Protocol { + // ... +} +``` -SPI 全称为 Service Provider Interface,是一种服务发现机制。SPI 的本质是将接口实现类的全限定名配置在文件中,并由服务加载器读取配置文件,加载实现类。这样可以在运行时,动态为接口替换实现类。正因此特性,我们可以很容易的通过 SPI 机制为我们的程序提供拓展功能。SPI 机制在第三方框架中也有所应用,比如 Dubbo 就是通过 SPI 机制加载所有的组件。不过,Dubbo 并未使用 Java 原生的 SPI 机制,而是对其进行了增强,使其能够更好的满足需求。在 Dubbo 中,SPI 是一个非常重要的模块。基于 SPI,我们可以很容易的对 Dubbo 进行拓展。 -Dubbo 中,SPI 主要有两种用法,一种是加载固定的扩展类,另一种是加载自适应扩展类。这两种方式会在下面详细的介绍。 -需要特别注意的是: 在 Dubbo 中,基于 SPI 扩展加载的类是单例的。 +`@SPI` 注解的定义如下: -### 1.1 加载固定的扩展类 +```java +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE}) +public @interface SPI { + /** + * default extension name + */ + String value() default ""; + + /** + * scope of SPI, default value is application scope. + */ + ExtensionScope scope() default ExtensionScope.APPLICATION; +} +``` + +### 1.2 SPI加载流程 -如果让你来设计加载固定扩展类,你会怎么做了? -一种常见思路是读取特定目录下的配置文件,然后解析出全类名,通过反射机制来实例化这个类,然后将这个类放在集合中存起来,如果有需要的时候,直接从集合中取。Dubbo 中的实现也是这么一个思路。 -不过在 Dubbo 中,实现的更加完善,它实现了 IOC 和 AOP 的功能。IOC 就是说如果这个扩展类依赖其他属性,Dubbo 会自动的将这个属性进行注入。这个功能如何实现了?一个常见思路是获取这个扩展类的 setter - 方法,调用 setter 方法进行属性注入。AOP 指的是什么了?这个说的是 Dubbo 能够为扩展类注入其包装类。比如 DubboProtocol 是 Protocol 的扩展类,ProtocolListenerWrapper 是 DubboProtocol 的包装类。 +Dubbo 加载扩展的整个流程如下: -### 1.2 加载自适应扩展类 +![//imgs/v3/concepts/extension-load.png](/imgs/v3/concepts/extension-load.png) + +主要步骤为 4 个: +* 读取并解析配置文件 +* 缓存所有扩展实现 +* 基于用户执行的扩展名,实例化对应的扩展实现 +* 进行扩展实例属性的 IOC 注入以及实例化扩展的包装类,实现 AOP 特性 -先说明下自适应扩展类的使用场景。比如我们有需求,在调用某一个方法时,基于参数选择调用到不同的实现类。和工厂方法有些类似,基于不同的参数,构造出不同的实例对象。 -在 Dubbo 中实现的思路和这个差不多,不过 Dubbo 的实现更加灵活,它的实现和策略模式有些类似。每一种扩展类相当于一种策略,基于 URL 消息总线,将参数传递给 ExtensionLoader,通过 ExtensionLoader 基于参数加载对应的扩展类,实现运行时动态调用到目标实例上。 ## 2. Dubbo SPI 源码分析 -### 2.1 加载固定的扩展类 +### 2.1 按名称获取指定扩展类 Dubbo 中,SPI 加载固定扩展类的入口是 ExtensionLoader 的 getExtension 方法,下面我们对拓展类对象的获取过程进行详细的分析。 @@ -135,7 +166,7 @@ createExtension 方法的逻辑稍复杂一下,包含了如下的步骤: 以上步骤中,第一个步骤是加载拓展类的关键,第三和第四个步骤是 Dubbo IOC 与 AOP 的具体实现。在接下来的章节中,将会重点分析 getExtensionClasses 方法的逻辑,以及简单介绍 Dubbo IOC 的具体实现。 -#### 2.1.1 获取所有的拓展类 +#### 2.1.1 获取所有拓展类 我们在通过名称获取拓展类之前,首先需要根据配置文件解析出拓展项名称到拓展类的映射关系表(Map\<名称, 拓展类\>),之后再根据拓展项名称从映射关系表中取出相应的拓展类即可。相关过程的代码分析如下: @@ -313,80 +344,14 @@ private void loadClass(Map> extensionClasses, java.net.URL reso 如上,loadClass 方法操作了不同的缓存,比如 cachedAdaptiveClass、cachedWrapperClasses 和 cachedNames 等等。除此之外,该方法没有其他什么逻辑了。 -到此,关于缓存类加载的过程就分析完了。整个过程没什么特别复杂的地方,大家按部就班的分析即可,不懂的地方可以调试一下。接下来,我们来聊聊 Dubbo IOC 方面的内容。 - -#### 2.1.2 Dubbo IOC - -Dubbo IOC 是通过 setter 方法注入依赖。Dubbo 首先会通过反射获取到实例的所有方法,然后再遍历方法列表,检测方法名是否具有 setter 方法特征。若有,则通过 ObjectFactory 获取依赖对象,最后通过反射调用 setter 方法将依赖设置到目标对象中。整个过程对应的代码如下: - -```java -private T injectExtension(T instance) { - - if (objectFactory == null) { - return instance; - } - - try { - // 遍历目标类的所有方法 - for (Method method : instance.getClass().getMethods()) { - // 检测方法是否以 set 开头,且方法仅有一个参数,且方法访问级别为 public - if (!isSetter(method)) { - continue; - } - /** - * 检测是否有 DisableInject 注解修饰. - */ - if (method.getAnnotation(DisableInject.class) != null) { - continue; - } - - /** - * 检测是否实现了ScopeModelAware、ExtensionAccessorAware类,如果实现则不注入 - */ - if (method.getDeclaringClass() == ScopeModelAware.class) { - continue; - } - if (instance instanceof ScopeModelAware || instance instanceof ExtensionAccessorAware) { - if (ignoredInjectMethodsDesc.contains(ReflectUtils.getDesc(method))) { - continue; - } - } - - // 基本类型不注入 - Class pt = method.getParameterTypes()[0]; - if (ReflectUtils.isPrimitives(pt)) { - continue; - } - - try { - // 获取属性名,比如 setName 方法对应属性名 name - String property = getSetterProperty(method); - // 从 ObjectFactory 中获取依赖对象 - Object object = objectFactory.getExtension(pt, property); - if (object != null) { - // 注入 - method.invoke(instance, object); - } - } catch (Exception e) { - logger.error("Failed to inject via method " + method.getName() - + " of interface " + type.getName() + ": " + e.getMessage(), e); - } - - } - } catch (Exception e) { - logger.error(e.getMessage(), e); - } - return instance; -} -``` - -在上面代码中,objectFactory 变量的类型为 AdaptiveExtensionFactory,AdaptiveExtensionFactory 内部维护了一个 ExtensionFactory 列表,用于存储其他类型的 ExtensionFactory。Dubbo 目前提供了两种 ExtensionFactory,分别是 SpiExtensionFactory 和 SpringExtensionFactory。前者用于创建自适应的拓展,后者是用于从 Spring 的 IOC 容器中获取所需的拓展。这两个类的类的代码不是很复杂,这里就不一一分析了。 - -Dubbo IOC 目前仅支持 setter 方式注入,总的来说,逻辑比较简单易懂。 +到此,关于缓存类加载的过程就分析完了。整个过程没什么特别复杂的地方,大家按部就班的分析即可,不懂的地方可以调试一下。 ### 2.2 加载自适应扩展类 +先说明下自适应扩展类的使用场景。比如我们有需求,在调用某一个方法时,基于参数选择调用到不同的实现类,这和工厂方法有些类似,基于不同的参数,构造出不同的实例对象。在 Dubbo 中实现的思路和这个差不多,不过 Dubbo 的实现更加灵活,它的实现和策略模式有些类似。每一种扩展类相当于一种策略,基于 URL 消息总线,将参数传递给 ExtensionLoader,通过 ExtensionLoader 基于参数加载对应的扩展类,实现运行时动态调用到目标实例上。 + 自适应扩展类的含义是说,基于参数,在运行时动态选择到具体的目标类,然后执行。 + 在 Dubbo 中,很多拓展都是通过 SPI 机制进行加载的,比如 Protocol、Cluster、LoadBalance 等。有时,有些拓展并不想在框架启动阶段被加载,而是希望在拓展方法被调用时,根据运行时参数进行加载。这听起来有些矛盾。拓展未被加载,那么拓展方法就无法被调用(静态方法除外)。拓展方法未被调用,拓展就无法被加载。对于这个矛盾的问题,Dubbo 通过自适应拓展机制很好的解决了。自适应拓展机制的实现逻辑比较复杂,首先 Dubbo 会为拓展接口生成具有代理功能的代码。然后通过 javassist 或 jdk 编译这段代码,得到 Class 类。最后再通过反射创建代理类,整个过程比较复杂。 加载自适应扩展类的入口是 ExtensionLoader 的 getAdaptiveExtension 方法。 @@ -614,6 +579,241 @@ public class HasAdaptiveExt$Adaptive implements org.apache.dubbo.common.extensio ``` +### 2.3 IOC 机制 + +Dubbo IOC 是通过 setter 方法注入依赖。Dubbo 首先会通过反射获取到实例的所有方法,然后再遍历方法列表,检测方法名是否具有 setter 方法特征。若有,则通过 ObjectFactory 获取依赖对象,最后通过反射调用 setter 方法将依赖设置到目标对象中。整个过程对应的代码如下: + +```java +private T injectExtension(T instance) { + + if (objectFactory == null) { + return instance; + } + + try { + // 遍历目标类的所有方法 + for (Method method : instance.getClass().getMethods()) { + // 检测方法是否以 set 开头,且方法仅有一个参数,且方法访问级别为 public + if (!isSetter(method)) { + continue; + } + /** + * 检测是否有 DisableInject 注解修饰. + */ + if (method.getAnnotation(DisableInject.class) != null) { + continue; + } + + /** + * 检测是否实现了ScopeModelAware、ExtensionAccessorAware类,如果实现则不注入 + */ + if (method.getDeclaringClass() == ScopeModelAware.class) { + continue; + } + if (instance instanceof ScopeModelAware || instance instanceof ExtensionAccessorAware) { + if (ignoredInjectMethodsDesc.contains(ReflectUtils.getDesc(method))) { + continue; + } + } + + // 基本类型不注入 + Class pt = method.getParameterTypes()[0]; + if (ReflectUtils.isPrimitives(pt)) { + continue; + } + + try { + // 获取属性名,比如 setName 方法对应属性名 name + String property = getSetterProperty(method); + // 从 ObjectFactory 中获取依赖对象 + Object object = objectFactory.getExtension(pt, property); + if (object != null) { + // 注入 + method.invoke(instance, object); + } + } catch (Exception e) { + logger.error("Failed to inject via method " + method.getName() + + " of interface " + type.getName() + ": " + e.getMessage(), e); + } + + } + } catch (Exception e) { + logger.error(e.getMessage(), e); + } + return instance; +} +``` + +在上面代码中,objectFactory 变量的类型为 AdaptiveExtensionFactory,AdaptiveExtensionFactory 内部维护了一个 ExtensionFactory 列表,用于存储其他类型的 ExtensionFactory。Dubbo 目前提供了两种 ExtensionFactory,分别是 SpiExtensionFactory 和 SpringExtensionFactory。前者用于创建自适应的拓展,后者是用于从 Spring 的 IOC 容器中获取所需的拓展。这两个类的类的代码不是很复杂,这里就不一一分析了。 + +Dubbo IOC 目前仅支持 setter 方式注入,总的来说,逻辑比较简单易懂。 + +### 2.4 AOP 机制 + +Dubbo AOP 机制采用 wrapper 设计模式实现,要成为一个 AOP wrapper 类,必须同时满足以下几个条件: +1. wrapper 类必须实现 SPI 接口,如以下示例中的 `class QosProtocolWrapper implements Protocol` +2. 构造器 constructor 必须包含一个相同的 SPI 参数,如以下示例中 `QosProtocolWrapper(Protocol protocol)` +3. wrapper 类必须和普通的 SPI 实现一样写入配置文件,如以下示例 `resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Protocol` + +```java +public class QosProtocolWrapper implements Protocol, ScopeModelAware { + private final Protocol protocol; + public QosProtocolWrapper(Protocol protocol) { + if (protocol == null) { + throw new IllegalArgumentException("protocol == null"); + } + this.protocol = protocol; + } +} +``` + +写入配置文件 `resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Protocol`: + +```properties +qos=org.apache.dubbo.qos.protocol.QosProtocolWrapper +``` + +在通过 `getExtension(name)` 尝试获取并加载 SPI 扩展实例时,Dubbo 框架会判断所有满足以上 3 个条件的 wrapper 类实现,并将 wrapper 类按顺序包在实例外面,从而达到 AOP 拦截的效果。 + +以下是 wrapper 判断与加载的实现逻辑,你还可以使用 @Wrapper 注解来控制 wrapper 类的激活条件: + +```java +private T createExtension(String name, boolean wrap) { + Class clazz = getExtensionClasses().get(name); + T instance = (T) extensionInstances.get(clazz); + // ... + if (wrap) { // 如果调用方告知需要 AOP,即 wrap=true + List> wrapperClassesList = new ArrayList<>(); + if (cachedWrapperClasses != null) { + wrapperClassesList.addAll(cachedWrapperClasses); + wrapperClassesList.sort(WrapperComparator.COMPARATOR); + Collections.reverse(wrapperClassesList); + } + + if (CollectionUtils.isNotEmpty(wrapperClassesList)) { + for (Class wrapperClass : wrapperClassesList) { + // 通过 @Wrapper 注解判断当前 wrapper 类是否要生效 + Wrapper wrapper = wrapperClass.getAnnotation(Wrapper.class); + boolean match = (wrapper == null) + || ((ArrayUtils.isEmpty(wrapper.matches()) + || ArrayUtils.contains(wrapper.matches(), name)) + && !ArrayUtils.contains(wrapper.mismatches(), name)); + if (match) { + instance = injectExtension( + (T) wrapperClass.getConstructor(type).newInstance(instance)); + instance = postProcessAfterInitialization(instance, name); + } + } + } + } +} +``` + +### 2.5 Activate激活条件 + +可以使用 `@org.apache.dubbo.common.extension.Activate` 来控制 SPI 扩展实现在什么场景下加载生效。相比于任何场景下都生效,能精确的控制扩展实现的生效条件会让实现变得更灵活。 + +以下是一些使用场景示例: + +```java +// 不加 @Activate 注解,getActivateExtension() 时不会加载,其他 getExtension() 方法仍可正常加载 +public class MetricsProviderFilter implements Filter{} +``` + +```java +// 不加任何参数,表示在 getActivateExtension() 时无条件自动返回 +@Activate +public class MetricsProviderFilter implements Filter{} +``` + +```java +// group 支持 consumer、provider 两个固定值,getActivateExtension() 调用加载扩展点时自动过滤 +// provider 表示在提供者端会被加载;consumer 表示在消费者端会被加载 +@Activate(group="provider") +public class MetricsProviderFilter implements Filter{} +``` + +```java +// URL 参数中有 cache 这个 key 时,调用 getActivateExtension() 才会加载 +@Activate(value="cache") +public class MetricsProviderFilter implements Filter{} +``` + +```java +// URL 参数中有 cache 这个 key 并且值为 test 时,调用 getActivateExtension() 才会加载 +@Activate(value="cache:test") +public class MetricsProviderFilter implements Filter{} +``` + +以下是 `@Activate` 注解的具体定义: + +```java +/** + * Activate. This annotation is useful for automatically activate certain extensions with the given criteria, + * for examples: @Activate can be used to load certain Filter extension when there are + * multiple implementations. + *
    + *
  1. {@link Activate#group()} specifies group criteria. Framework SPI defines the valid group values. + *
  2. {@link Activate#value()} specifies parameter key in {@link URL} criteria. + *
+ * SPI provider can call {@link ExtensionLoader#getActivateExtension(URL, String, String)} to find out all activated + * extensions with the given criteria. + * + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE, ElementType.METHOD}) +public @interface Activate { + /** + * Activate the current extension when one of the groups matches. The group passed into + * {@link ExtensionLoader#getActivateExtension(URL, String, String)} will be used for matching. + * + * @return group names to match + * @see ExtensionLoader#getActivateExtension(URL, String, String) + */ + String[] group() default {}; + + /** + * Activate the current extension when the specified keys appear in the URL's parameters. + *

+ * For example, given @Activate("cache, validation"), the current extension will be return only when + * there's either cache or validation key appeared in the URL's parameters. + *

+ * + * @return URL parameter keys + * @see ExtensionLoader#getActivateExtension(URL, String) + * @see ExtensionLoader#getActivateExtension(URL, String, String) + */ + String[] value() default {}; + + /** + * Absolute ordering info, optional + * + * Ascending order, smaller values will be in the front o the list. + * + * @return absolute ordering info + */ + int order() default 0; + + /** + * Activate loadClass when the current extension when the specified className all match + * @return className names to all match + */ + String[] onClass() default {}; +} +``` + +### 2.6 扩展点排序 + +排序同样使用 `@Activate` 注解设置,以下是使用示例,`order` 值越小加载优先级越高。 + +```java +@Activate(order=100) +public class FilterImpl1 implements Filter{} + +@Activate(order=200) +public class FilterImpl2 implements Filter{} +``` ## 3. Dubbo SPI 扩展示例 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/architecture/multi-instance/_index.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/architecture/multi-instance/_index.md new file mode 100755 index 000000000000..8f62be7b075b --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/architecture/multi-instance/_index.md @@ -0,0 +1,7 @@ +--- +description: "Dubbo 多实例、多应用设计原理、实现与使用方法。" +linkTitle: 多实例部署 +title: 多实例部署 +type: docs +weight: 100 +--- diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/architecture/multi-instance/develop.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/architecture/multi-instance/develop.md new file mode 100644 index 000000000000..347e5cc3013e Binary files /dev/null and b/content/zh-cn/overview/mannual/java-sdk/reference-manual/architecture/multi-instance/develop.md differ diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/architecture/multi-instance/model.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/architecture/multi-instance/model.md new file mode 100644 index 000000000000..3b5bc831856e --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/architecture/multi-instance/model.md @@ -0,0 +1,178 @@ +--- +description: "Dubbo 多实例相关领域模型与概念" +linkTitle: 模型与概念 +title: 多实例相关的模型与概念定义 +type: docs +weight: 3 +--- + +## Dubbo 架构 + +JVM —— 虚拟机层 +目的:Dubbo 框架之间完全隔离(端口不能复用) + +Dubbo Framework —— 框架层 +目的:将需要全局缓存的进行复用(端口、序列化等) + +Application —— 应用层 +目的:隔离应用之间的信息,包括注册中心、配置中心、元数据中心 + +Services —— 模块层 +目的:提供热加载能力,可以按 ClassLoader、Spring Context 进行隔离上下文 + +## Dubbo 概念对齐 + +1. DubboBoorstrap + 1. 需要拆分 export/refer services、ServiceInstance、Metadata/Config 等 Client +2. ConfigManager + 1. 需要拆分应用级配置信息、模块级配置信息 +3. ApplicationModel + 1. 实际存储应用层信息,持有到 ConfigManager 应用级配置信息的引用 +4. ConsumerModel + 1. 实际存储接口信息,由 ModuleModel 持有引用 +5. ProviderModel + 1. 实际存储接口信息,由 ModuleModel 持有引用 +6. ExtensionLoader + 1. 需要根据不同层级 load 出不同的实例对象 +7. Registry + 1. 应用级别共享,需要确保多实例订阅正常(考虑单元化场景) +8. Router / Filter + 1. 模块级别共享 +9. Protocol / Remoting + 1. 框架级别共享,复用 IO,多应用间贡献 +10. Metadata + 1. 应用级别共享,考虑应用级服务发现 +11. QoS + 1. 框架级别共享,与 IO 有关 +12. Serialization + 1. 框架级别共享,与 IO 有关 +13. ConfigCenter + 1. 应用级别贡献 +14. ModuleModel(新) + 1. 实际存储模块层信息,持有接口级信息 +15. FrameworkModel(新) + 1. 实际存储框架层信息 + +## 配置存储梳理 + +### FrameworkModel +Qos、Protocol、Remoting、Serialization、ExtensionLoader + +### ApplicationModel +ConfigManager(应用级)、DubboBootstrap(类 Fluent API)、Registry、Metadata、ServiceInstance、ConfigCenter、ExtensionLoader + +### ModuleModel +ConsumerModel、ProviderModel、Router、Filter、ExtensionLoader + + +![](https://intranetproxy.alipay.com/skylark/lark/0/2021/jpeg/15256464/1628824598406-95556f0d-7817-4010-97a7-0f8e84a175cb.jpeg) +## Dubbo 流程梳理 + +### Model 创建 + +DefaultModel - FrameworkModel、ApplicationModel、ModuleModel + +1. 默认 Model 创建时机 +2. 用户自定义的 Model 的创建方式 + +### 消费端初始化 + +1. 消费端通过 ReferenceConfig 作为入口进行初始化配置相关信息,当前配置里面需要添加 ClassLoader 属性,ReferenceConfig 生成 ConsumerModel 注入到 ModuleModel +2. 组装的 URL 需要包含当前 ConsumerModel、ModuleModel、ApplicationModel、FrameworkModel(需要梳理全链路内 URL 转换逻辑,保证在中间不会被丢弃) +3. 组装链路上 Registry 为 ApplicationModel 域内的(订阅需要考虑订阅之间互相独立、多注册中心场景) ;Filter、Cluster、LoadBalance 为 ModuleModel 域内的 +4. Directory 需要持有包括详细信息的 ConsumerURL,序列化层需要传入配置信息 +5. ModuleModel 内三元组唯一,总是创建出同一个 proxy;ModuleModel 间允许重复三元组,proxy、invoker 均相互独立 + +### 服务端初始化 + +1. 服务端通过 ServiceConfig 作为入口进行初始化配置相关信息,当前配置里面需要添加 ClassLoader 属性,ServiceConfig 生成 ProviderModel 注入到 ModuleModel +2. 组装的 URL 需要包含当前 ProviderModel、ModuleModel、ApplicationModel、FrameworkModel(需要梳理全链路内 URL 转换逻辑,保证在中间不会被丢弃) +3. 组装链路上 Registry 为 ApplicationModel 域内的(订阅需要考虑服务之间互相独立、多注册中心场景) ;Filter 为 ModuleModel 域内的 +4. Protocol 层持有的三元组保证唯一,可以直接找到 ProviderModel(FrameworkModel 域内) + +### 地址推送流程 + +1. 注册中心监听需要确保三元组重复的订阅都能独立收到通知、相同三元组到注册中心的订阅链接可以进行复用 +2. 注册中心工作在 ApplicationModel 域,通过持有监听列表连接 ModuleModel 层,地址的处理为 ModuleModel 域内操作,如果服用地址通知需要保证通知内容不会被某个订阅所修改 +3. 每份地址通知根据不同 ModuleModel 独立创建 Invoker,Invoker 直接持有 ConsumerModel +4. Invoker 的底层 Protocol 层连接复用 TCP 连接 + +### 消费端调用链路 + +1. 消费端创建 invocation 时需要携带当前 ConsumerModel、ModuleModel、ApplicationModel、FrameworkModel (通过 consumerURL 携带),需要保证调用全链路 consumerURL 不丢失 + +### 服务端调用链路 + +1. 服务端收到请求后根据三元组定位 ProviderModel 及 invoker,进行反序列化时需要考虑 ClassLoader 切换 + +### 其他流程 + +1. 销毁流程 +2. QoS 聚合方式 + +## 代码改动 + +1. ExtensionLoader 依赖注入 +```java +ModuleModel.getExtensionFactory().getAdaptiveExtension(Protocol.class) +ApplicationModel.getExtensionFactory().getAdaptiveExtension(Protocol.class) +FrameworkModel.getExtensionFactory().getAdaptiveExtension(Protocol.class) + + +@SPI(scope = FRAMEWORK) +public interface Protocol { +} +``` + +- SPI 依赖注入 +2. DubboBootstrap -> 功能拆分(ModuleModel 维护生命周期) +```java +// 创建新应用实例,共享FrameworkModel +DubboBootstrap.newInstance(FrameworkModel) // SharedFrameworkModel -> NewApplicationModel + .addModule() // New ModuleModel + .addReference(ReferenceConfig) // 将服务配置挂到模块下 + .addReference(ReferenceConfig) + .addService(ServiceConfig) + .endModule() + .addModule() + .addReference(ReferenceConfig) + .addService(ServiceConfig) + .endModule() + .addRegistry() + .addConfigCenter() + .start() + +// 兼容旧的Bootstrap API,使用默认应用实例 +DubboBootstrap.getInstance() // DefaultFrameworkModel -> DefaultApplicationModel + .addReference(ReferenceConfig) // DefaultApplicationModel -> DefaultModuleModel + .addService(ServiceConfig) // DefaultApplicationModel -> DefaultModuleModel + .setRegistry() // DefaultApplicationModel + .start() + +// 新建应用实例 +DubboBootstrap.newInstance() // DefaultFrameworkModel -> NewApplicationModel + .addReference(ReferenceConfig) // NewApplicationModel -> DefaultModuleModel + .addService(ServiceConfig) // NewApplicationModel -> DefaultModuleModel + .setRegistry() // NewApplicationModel + .start() + +``` + +3. RefenceConfig、ServiceConfig + 1. ModuleModel 动态设置 + 2. 需要把 ExtensionLoader 初始化的地方下放到 setModuleModel + 3. consumerUrl 携带 ModuleModel +4. ModuleModel、ApplicationModel、FrameworkModel + 1. ModuleModel -> ConsumerModels、ProviderModels + 2. ApplicationModel -> ConfigManager(应用级的属性信息)、ModuleModels +5. ConsumerModel、ProviderModel +6. 注册中心需要支持多订阅 +7. Spring + + +1. ModuleModel、ApplicationModel、FrameworkModel(ExtensionLoader) +2. RefenceConfig、ServiceConfig(ConsumerModel、ProviderModel) +3. ExtensionLoader (Filter 改动) + + + diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/architecture/multi-instance/multi-instance.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/architecture/multi-instance/multi-instance.md new file mode 100644 index 000000000000..b11036ba60d3 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/architecture/multi-instance/multi-instance.md @@ -0,0 +1,113 @@ +--- +description: "Dubbo 多实例、多应用设计原理、实现与使用方法。" +linkTitle: 多实例设计理念 +title: 多实例部署的设计理念 +type: docs +weight: 1 +--- + +## 背景 + +Java 提供的静态变量(static field)能力可以将持有对象引用的行为绑定到类上面来,这给开发者提供了巨大的便利。注入单例模式、工厂模式等设计模式的实现方案都依赖了静态变量的功能。通过使用静态变量,开发者可以在任何时间、任何地点简单地获取到所需要的对象信息。 +```java +public class Test { + public static Object obj; +} +Test.obj = xxx; +``` +在一直以来的 Dubbo 框架开发中,静态变量受到了广泛地应用,诸如使用一个全局共享的 ConfigManager 来存储全局配置信息、ServiceRepository 来存储服务信息,不论从中心化管理配置或者是参数获取的便利性的角度来说,这种设计都是最佳的。在 Dubbo 2.7 以前的所有版本,Dubbo 所需要的运行时配置信息都通过全局静态变量获取,通过 RPC 服务三元组(interface + version + group)的方式进行唯一定位。 + +但是随着 Dubbo 用户基数的不断扩大以及在阿里集团内由 Dubbo 作为内核的 HSF3 框架都对原来的这种设计模式提出了挑战。 + +对于开源用户,社区收到的诉求主要包括以下几点: + +1. 在同一个应用内能够创建多个三元组一样的订阅。这个行为在 Dubbo 2.7 中虽然没有做强限制,但是由于 Dubbo 很多参数是取自全局的,而这个获取的索引使用的就是三元组。如果用户创建了两个三元组一样的订阅,他们的参数会被相互覆盖,地址推送等功能也会收到很大的影响。 +2. Java 提供了自定义 ClassLoader 的机制可以自定义指定类的加载器来源,但是对于 Dubbo 来说并没有去支持多 ClassLoader 的场景,在动态代理生成和序列化场景下都不支持 ClassLoader 切换的行为。 +3. Dubbo 众多的测试用例都共享了同一份配置信息,导致在进行单元测试的时候极为容易造成环境污染的问题。 + +对于阿里集团内大规模落地来说,我们遇到的问题主要有: + +1. 阿里集团内有众多的中间件框架,这些框架提供了各种各样的类加载方式,同时业务方期望在同一应用内的配置等信息是相互隔离的。 +2. 一些业务方的定制逻辑需要支持动态热部署的模式,具体体现在动态对某个虚拟环境进行销毁,这需要 Dubbo 内的生命周期管理更加完善。 +3. 集团内有多个对 Spring 容器进行定制化开发的框架,需要 Dubbo 能够支持多个 Spring Context 独立管理生命周期的场景。 + +基于众多的这些原因,在八月初的时候我们决定对 Dubbo 的生命周期进行重构,经过一个月的紧张开发,目前社区版本已经完整支持了多实例化的功能,Dubbo 的生命周期也变得更加清晰。 + +## 设计 + +整个 Dubbo 多实例的设计我们按照了三层模型来配置,分别是 Framework 框架层、Application 应用层、Module 模块层。 +![image.png](https://cdn.nlark.com/yuque/0/2021/png/209479/1633766738924-498b5ac4-d96b-48f4-a55f-8cc946800bee.png#clientId=uc9c7eb9b-dec6-4&from=paste&height=446&id=ub35f4a80&originHeight=892&originWidth=2366&originalType=binary&ratio=1&size=483065&status=done&style=none&taskId=u01b03e88-733f-422b-94ea-cf45220737c&width=1183) +基于三层机制,我们可以将 Dubbo 按照一定规则进行隔离: + +1. Framework 与 Framework 之间完全隔离,相当于是使用了两个完全不同的 Dubbo 实例 +2. Application 与 Application 之间按照应用名进行隔离,但是相互有些地共享 Protocol、Serialization 层,目标是达到在同一个 dubbo 端口(20880)上可以承载多个应用,而每个应用独立上报地址信息。 +3. Module 与 Module 之间可以由用户自定义进行进行隔离,可以是热部署周期的一个状态、也可以是 Spring Context 的一个 Context。通过 Module,用户可以对 Dubbo 的生命周期粒度进行最小的管理。 + +为了实现 Dubbo 多实例化,Dubbo 框架内做的最多的变化是修改掉大部分的从静态变量中获取的参数的逻辑,最明显的逻辑是 Dubbo 内部用于参数传递的 URL 对象带上了 ScopeModel 状态,这个 ScopeModel 对应的就是上面提到的三层模型的具体数据承载对象。 + +## 使用方式 + +多实例重构版本之后的 Dubbo 对于大多数用户的使用来说是无感知的,改造后的 DubboBootstrap 已经变成一个独立的启动器,用户可以通过 DubboBootstrap 定制多实例的使用。 + +下面是使用多实例的一个简单的例子。 + +```java + ServiceConfig service = new ServiceConfig<>(); + service.setInterface(DemoService.class); + service.setRef(new DemoServiceImpl()); + + ReferenceConfig reference1 = new ReferenceConfig<>(); + reference1.setInterface(DemoService.class); + + ReferenceConfig reference2 = new ReferenceConfig<>(); + reference2.setInterface(DemoService.class); + + // 创建一个启动器(自动创建新 ApplicationModel) + DubboBootstrap bootstrap1 = DubboBootstrap.newInstance(); + // 指定应用名 + bootstrap1.application(new ApplicationConfig("dubbo-demo-app-1")) + .registry(new RegistryConfig("nacos://localhost:8848")) + // 创建一个模块 + .newModule() + // 在模块内发布服务 + .service(service) + .endModule() + // 创建一个模块 + .newModule() + // 在模块内订阅服务 + .reference(reference1) + .endModule() + .start(); + + // 创建一个启动器(自动创建新 ApplicationModel) + DubboBootstrap bootstrap2 = DubboBootstrap.newInstance(); + // 指定应用名 + bootstrap2.application(new ApplicationConfig("dubbo-demo-app-2")) + .registry(new RegistryConfig("nacos://localhost:8848")) + // 创建一个模块 + .newModule() + // 在模块内订阅服务 + .reference(reference2) + .endModule() + .start(); + + // stub1 与 stub2 是两个独立的订阅,互相隔离 + + // 订阅的 stub + DemoService stub1 = reference1.get(); + System.out.println(stub1.sayHello("Hello World!")); + + // 订阅的 stub + DemoService stub2 = reference2.get(); + System.out.println(stub2.sayHello("Hello World!")); + + bootstrap1.stop(); + bootstrap2.stop(); +``` + +这个例子对外发布了一个 DemoService 的服务,由 dubbo-demo-app-1 这个应用提供。同时我们创建了两个订阅,分别是在 dubbo-demo-app-1 应用和 dubbo-demo-app-2 应用中,然后我们去对两个订阅进行调用,得到预期的结果。 + +这里需要注意的是虽然两个订阅的服务信息是完全一致的,在多实例化改造后,这两个订阅对于消费端来说是完全隔离的,也就是在最新版本的 Dubbo 中是支持三元组一样的情况下通过变更参数来创建多个订阅的行为的了。 + + + diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/architecture/multi-instance/workflow.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/architecture/multi-instance/workflow.md new file mode 100644 index 000000000000..73725af963b1 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/architecture/multi-instance/workflow.md @@ -0,0 +1,25 @@ +--- +description: "Dubbo 多实例启动流程与模块依赖关系。" +linkTitle: 启动流程与模块依赖关系 +title: 多实例启动流程与模块依赖关系 +type: docs +weight: 3 +--- + +1、应用启动流程 +初始化应用配置,启动内部模块,启动其它模块。 +应用启动方式包括:DubboBootstrap.start(), ApplicationModel.getDeployer().start() +![Dubbo start process.svg](https://cdn.nlark.com/yuque/0/2021/svg/2391732/1634895625292-99fdac6f-3371-4147-9ad5-9428296cb083.svg#clientId=u82d0d5c2-bff3-4&from=drop&id=u8db161d3&originHeight=2594&originWidth=1050&originalType=binary&ratio=1&size=64242&status=done&style=none&taskId=u8976fa81-5bc5-469a-ab4a-b4cda12cd6d) +2、模块启动流程 +上图中从ModuleDeployer.start() 开始,自动初始化应用配置,启动内部模块,然后启动当前模块。 +模块启动方式包括: +1) Spring context 加载dubbo xml配置或者注解 +2) 手工启动模块:ModuleModel.getDeployer().start() + +3、服务接口API方式启动 +ServiceConfig.export() 或者 ReferenceConfig.get() 先自动启动module,然后执行export/refer服务接口 + + + + + diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/architecture/multi-protocol.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/architecture/multi-protocol.md new file mode 100644 index 000000000000..06f9050534e9 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/architecture/multi-protocol.md @@ -0,0 +1,132 @@ +--- +description: "Dubbo 单端口多协议实现原理&源码解析。" +linkTitle: 单端口多协议 +title: 单端口多协议实现原理解析 +type: docs +weight: 1 +--- + +通过对protocol进行配置,dubbo3可以支持端口的协议复用。 +比如使用Triple协议启动端口复用后,可以在相同的端口上为服务增加 +Dubbo协议支持,以及Qos协议支持。这些协议的识别都是由一个统一的端口复用 +服务器进行处理的,可以用于服务的协议迁移,并且可以节约端口以及相关的资源,减少运维的复杂性。 + +![pu-server-image1](/imgs/blog/pu-server/pu-server-flow.png) + +- 在服务的创建阶段,通过从Config层获取到服务导出的协议配置从而创建不同的Protocol对象进行导出。在导出的过程 +中,如果不是第一次创建端口复用的Server,那么Exchanger会将Protcol层传递的数据保存到Server,用于后续处理该协议类型的消息。 + +- 当客户端的消息传递过来后,首先会通过Server传递给ProtocolDetector,如果完成了识别,那么就会标记该客户端为对应的协议。并通过WireProtocol配置对应的处理逻辑,最后交给ChannelOperator完成底层的IO框架和对应的Dubbo框架的处理逻辑的绑定。 + +- 以上的协议识别完成之后,Channel已经确定了如何处理远程的客户端消息,通过对应的ServerPipeline进行处理即可(在处理的过程中也会根据配置信息决定消息的处理线程)。 + +## 使用场景 +- 最常用的是用于服务发现。这允许应用程序通过网络发现服务,然后使用同一端口与它们通信,有助于降低网络通信的复杂性,并使其更易于管理。 + +- 可以用于负载平衡。这允许应用程序在多个远程服务或服务集群之间平衡负载,有助于提高服务的可扩展性、可靠性和可用性。 + +- 可以用于服务监控。这允许应用程序监视远程服务的运行状况,并在服务出现故障或变得不可用时发出警报,有助于确保服务的可用性并减少停机时间。 + +> 参考用例 +[https://github.com/apache/dubbo-samples/tree/master/dubbo-samples-port-unification](https://github.com/apache/dubbo-samples/tree/master/3-extensions/protocol/dubbo-samples-port-unification) + +## 使用方式 +在同一主机上部署多个服务或需要通过负载均衡器访问多个服务。 + +> 关于Dubbo支持的配置方式 [配置说明](/zh-cn/overview/mannual/java-sdk/reference-manual/config/) + +### 服务多协议导出 + +ext-protocol参数支持配置多个不同的协议,协议之间通过","进行分隔。 + +#### xml 配置 + +```xml + + + + + + +``` + +#### API 配置 + +```java +ProtocolConfig config = new ProtocolConfig(CommonConstants.TRIPLE, -1); + +config.setExtProtocol(CommonConstants.DUBBO+","); +``` + +#### yaml 配置 + +``` yaml +dubbo: + application: + name: dubbo-springboot-demo-provider + protocol: + name: tri + port: -1 + ext-protocol: dubbo, +``` + +#### properties 配置 +```properties +dubbo.protocol.name=tri +dubbo.protocol.ext-protocol=dubbo, +dubbo.protocol.port=20880 +``` + +### Qos接入 + +#### Qos模块导入 + +```xml + + org.apache.dubbo + dubbo-qos + +``` + +完成Qos模块的导入之后,相关的配置项可参考[Qos操作手册](/zh-cn/overview/mannual/java-sdk/reference-manual/qos/overview/)进行配置。 + +默认情况下,基于端口复用的Qos服务在模块导入后是启动的。 + + + +### Qos使用 + +将Qos协议接入到端口复用的场景下,需要在建立连接之后,客户端先向服务端发送消息,对比将Qos协议通过单个端口提供服务,端口复用版的Qos协议在处理telnet连接的情况下需要用户执行一些操作,完成协议识别(二选一)。 + +1. 直接调用命令 + + 直接调用telnet支持的命令也可以完成识别,在用户不熟悉的情况下可以调用help指令完成识别 + + ![pu-server-image2](/imgs/blog/pu-server/qos-telnet-directcall.png) + +2. 发送telnet命令识别 + + 通过telnet命令建立连接之后,执行以下几个步骤: + + 1. 使用 crtl + "]" 进入到telnet交互界面(telnet默认的escape character) + 2. 调用 "send ayt" 向服务端发送特殊识别字段(为telnet协议的一个特殊字段) + 3. 回车完成消息发送并进入到dubbo的交互界面 + + ![pu-server-imgs3](/imgs/blog/pu-server/qos-telnet-sendayt.png) + + +### 服务引用 + +以[dubbo-samples-port-unification](https://github.com/apache/dubbo-samples/tree/master/3-extensions/protocol/dubbo-samples-port-unification)中的例子作为基础, 引用不同协议的服务和非端口复用情况下的配置是一致的,下面通过Consumer端的InvokerListener输出调用过程中的URL信息。 + +```java +ReferenceConfig reference = new ReferenceConfig<>(); +reference.setInterface(GreetingService.class); +reference.setListener("consumer"); +reference.setProtocol(this.protocol); +// reference.setProtocol(CommonConstants.DUBBO); +// reference.setProtocol(CommonConstants.TRIPLE); +``` + +![pu-server-imgs4](/imgs/blog/pu-server/reference-service.png) + diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/config-center/_index.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/config-center/_index.md index f6acc2c9d221..2fa6d5b61c8e 100644 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/config-center/_index.md +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/config-center/_index.md @@ -7,7 +7,7 @@ description: Dubbo 配置中心的基本使用和工作原理 linkTitle: 配置中心 title: 配置中心 type: docs -weight: 4 +weight: 6 --- diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/config-center/introduction.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/config-center/introduction.md new file mode 100644 index 000000000000..cd3edada6a13 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/config-center/introduction.md @@ -0,0 +1,29 @@ +--- +aliases: + - /zh/docs3-v2/java-sdk/reference-manual/config-center/ + - /zh-cn/docs3-v2/java-sdk/reference-manual/config-center/ + - /zh-cn/overview/what/ecosystem/config-center/ +description: Dubbo 配置中心的基本使用和工作原理 +linkTitle: 配置中心概述 +title: 配置中心 +type: docs +weight: 1 +--- + + +配置中心 (config-center) 在 Dubbo 中可承担两类职责: + +1. [外部化配置](/zh-cn/overview/mannual/java-sdk/reference-manual/config/principle/#33-外部化配置):启动配置的集中式存储 (简单理解为 dubbo.properties 的外部化存储)。 +2. 流量治理规则存储 + +请参考具体扩展实现了解如何启用配置中心。 + +值得注意的是 Dubbo 动态配置中心定义了两个不同层次的隔离选项,分别是 namespace 和 group。 +* namespace - 配置命名空间,默认值 `dubbo`。命名空间通常用于多租户隔离,即对不同用户、不同环境或完全不关联的一系列配置进行逻辑隔离,区别于物理隔离的点是不同的命名空间使用的还是同一物理集群。 +* group - 配置分组,默认值 `dubbo`。`group` 通常用于归类一组相同类型/目的的配置项,是对 `namespace` 下配置项的进一步隔离。 + +参考 [配置说明 - 配置项手册](/zh-cn/overview/mannual/java-sdk/reference-manual/config/properties/#dubboconfig-center) 了解 namespace 和 group 之外 config-center 开放的更多配置项。 + +{{% alert title="使用注册中心作为默认配置中心" color="info" %}} +在使用 Zookeeper、Nacos 作为注册中心且没有显式配置配置中心的情况下,Dubbo 框架会默认将此 Zookeeper、Nacos 用作配置中心,用作服务治理用途。 +{{% /alert %}} diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/config-center/nacos.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/config-center/nacos.md index 4f37e60ca5b2..3bf51acfc078 100644 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/config-center/nacos.md +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/config-center/nacos.md @@ -11,16 +11,17 @@ weight: 3 --- ## 1 前置条件 -* 了解 [Dubbo 基本开发步骤](../../../quick-start/spring-boot/) -* 安装并启动 [Nacos](https://nacos.io/zh-cn/docs/quick-start.html) -> 当Dubbo使用`3.0.0`及以上版本时,需要使用Nacos `2.0.0`及以上版本。 +* 了解 [Dubbo 基本开发步骤](/zh-cn/overview/mannual/java-sdk/quick-start/starter/) +* 安装并启动 [Nacos](/zh-cn/overview/reference/integrations/nacos/) + +> 当Dubbo使用`3.0.0`及以上版本时,需要使用Nacos `2.0.0`及以上版本。请参考 [nacos 注册中心](/zh-cn/overview/mannual/java-sdk/reference-manual/registry/nacos/#12-nacos-版本) 了解 nacos 版本适配情况。 ## 2 使用说明 ### 2.1 增加 Maven 依赖 如果项目已经启用 Nacos 作为注册中心,则无需增加任何额外配置。 -如果未启用 Nacos 注册中心,则请参考 [为注册中心增加 Nacos 依赖](../../registry/nacos/#21-增加依赖)。 +如果未启用 Nacos 注册中心,则请参考 [为注册中心增加 Nacos 依赖](/zh-cn/overview/mannual/java-sdk/reference-manual/registry/nacos/#11-增加依赖)。 ### 2.2 启用 Nacos 配置中心 ```xml diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/config-center/others.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/config-center/others.md new file mode 100644 index 000000000000..29fe7cc6ed6c --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/config-center/others.md @@ -0,0 +1,54 @@ +--- +description: "更多配置中心扩展实现,包括 etcd、consul 等" +linkTitle: 扩展实现 +title: 更多配置中心扩展实现 +type: docs +weight: 4 +--- + +Dubbo 框架还默认提供了 etcd、consul 等配置中心适配实现。 + +## Etcd + +Etcd 配置中心由社区生态库维护,具体可参见 [](https://github.com/apache/dubbo-spi-extensions/tree/master/dubbo-configcenter-extensions/dubbo-configcenter-etcd)。 + +增加依赖: + +```xml + + org.apache.dubbo.extensions + dubbo-configcenter-etcd + 3.3.0 + +``` + +调整配置: + +```yaml +dubbo + config-center + address: etcd://127.0.0.1:1111 +``` + + +## Consul + +Consul 配置中心由社区生态库维护,具体可参见 [](https://github.com/apache/dubbo-spi-extensions/tree/master/dubbo-configcenter-extensions/dubbo-configcenter-consul)。 + +增加依赖: + +```xml + + org.apache.dubbo.extensions + dubbo-configcenter-consul + 3.3.0 + +``` + +调整配置: + +```yaml +dubbo + config-center + address: consul://127.0.0.1:1111 +``` \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/config-center/zookeeper.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/config-center/zookeeper.md index 0920310bb667..a315d774cd12 100644 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/config-center/zookeeper.md +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/config-center/zookeeper.md @@ -12,8 +12,8 @@ weight: 2 ## 1 前置条件 -* 了解 [Dubbo 基本开发步骤](../../../quick-start/spring-boot/) -* 安装并启动 [Zookeeper](https://zookeeper.apache.org/) +* 了解 [Dubbo 基本开发步骤](/zh-cn/overview/mannual/java-sdk/quick-start/starter/) +* 安装并启动 [Zookeeper](/zh-cn/overview/reference/integrations/zookeeper/) ## 2 使用说明 在此查看[完整示例代码](https://github.com/apache/dubbo-samples/tree/master/3-extensions/configcenter/dubbo-samples-configcenter-annotation) @@ -21,7 +21,7 @@ weight: 2 ### 2.1 增加 Maven 依赖 如果项目已经启用 Zookeeper 作为注册中心,则无需增加任何额外配置。 -如果未使用 Zookeeper 注册中心,则请参考 [为注册中心增加 Zookeeper 相关依赖](../../registry/zookeeper/#21-增加-maven-依赖)。 +如果未使用 Zookeeper 注册中心,则请参考 [为注册中心增加 Zookeeper 相关依赖](/zh-cn/overview/mannual/java-sdk/reference-manual/registry/zookeeper/#11-增加-maven-依赖)。 ### 2.2 启用 Zookeeper 配置中心 ```xml @@ -49,10 +49,10 @@ ConfigCenterConfig configCenter = new ConfigCenterConfig(); configCenter.setAddress("zookeeper://127.0.0.1:2181"); ``` -`address` 格式请参考 [zookeeper 注册中心 - 启用配置](../../registry/zookeeper/#22-配置并启用-zookeeper) +`address` 格式请参考 [zookeeper 注册中心 - 启用配置](../../registry/zookeeper/#13-配置并启用-zookeeper) ## 3 高级配置 -如要开启认证鉴权,请参考 [zookeeper 注册中心 - 启用认证鉴权](../../registry/zookeeper/#31-认证与鉴权) +如要开启认证鉴权,请参考 [zookeeper 注册中心 - 启用认证鉴权](../../registry/zookeeper/#21-认证与鉴权) ### 3.1 定制外部化配置 key **1. 启用外部化配置,并指定 key** @@ -89,7 +89,7 @@ dubbo 对配置中心而言,`group` 与 `namespace` 应该是全公司(集群)统一的,应该避免不同应用使用不同的值,外部化配置和治理规则也应该存放在对应的 group 与 namespace。 ## 4 流量治理规则 -所有流量治理规则默认都存储在 `/dubbo/config` 节点下,具体节点结构图如下。流量治理规则的增删改建议通过 dubbo-admin 完成,更多内容可查看 Dubbo 支持的具体流量治理能力 +所有流量治理规则默认都存储在 `/dubbo/config` 节点下,具体节点结构图如下。流量治理规则的增删改建议通过 dubbo-control-plane(dubbo-admin) 完成,更多内容可查看 Dubbo 支持的具体流量治理能力 ![zk-configcenter-governance](/imgs/user/zk-configcenter-governance.jpg) diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/config/_index.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/config/_index.md index 073bf14b1923..dd5549e51b71 100644 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/config/_index.md +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/config/_index.md @@ -2,6 +2,7 @@ aliases: - /zh/docs3-v2/java-sdk/reference-manual/config/ - /zh-cn/docs3-v2/java-sdk/reference-manual/config/ + - /zh-cn/overview/mannual/java-sdk/reference-manual/config/overview/ description: Dubbo 配置指南 linkTitle: 配置说明 title: 配置手册 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/config/annotation.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/config/annotation.md deleted file mode 100644 index 445a9144b3eb..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/config/annotation.md +++ /dev/null @@ -1,219 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/reference-manual/config/annotation/ - - /zh-cn/docs3-v2/java-sdk/reference-manual/config/annotation/ -description: 以 Annotation、Spring Boot 开发 Dubbo 应用 -linkTitle: Annotation 配置 -title: Annotation 配置 -type: docs -weight: 3 ---- - - - - - - -本文以 Spring Boot + Annotation 模式描述 Dubbo 应用开发,在此查看无 Spring Boot 的 Spring 注解开发模式 - -> [完整示例](https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-annotation) - -在 Dubbo Spring Boot 开发中,你只需要增加几个注解,并配置 `application.properties` 或 `application.yml` 文件即可完成 Dubbo 服务定义: -* 注解有 `@DubboService`、`@DubboReference` 与 `EnableDubbo`。其中 `@DubboService` 与 `@DubboReference` 用于标记 Dubbo 服务,`EnableDubbo` 启动 Dubbo 相关配置并指定 Spring Boot 扫描包路径。 -* 配置文件 `application.properties` 或 `application.yml` - -> [dubbo-samples](https://github.com/apache/dubbo-samples/tree/master/1-basic/dubbo-samples-spring-boot) - -## 增加 Maven 依赖 - -使用 Dubbo Spring Boot Starter 首先引入以下 Maven 依赖 -```xml - - - - - org.springframework.boot - spring-boot-dependencies - ${spring-boot.version} - pom - import - - - - org.apache.dubbo - dubbo-bom - ${dubbo.version} - pom - import - - - - - org.apache.dubbo - dubbo-dependencies-zookeeper - ${dubbo.version} - pom - - - -``` - -然后在相应的模块的 pom 中增加 -```xml - - - - org.apache.dubbo - dubbo - - - org.apache.dubbo - dubbo-dependencies-zookeeper - pom - - - - - org.apache.dubbo - dubbo-spring-boot-starter - - - - - org.springframework.boot - spring-boot-starter - - - org.springframework.boot - spring-boot-autoconfigure - - -``` -> 区分上面的 **与** - -## application.yml 或 application.properties - -除 service、reference 之外的组件都可以在 application.yml 文件中设置,如果要扩展 service 或 reference 的注解配置,则需要增加 `dubbo.properties` 配置文件或使用其他非注解如 Java Config 方式,具体请看下文 [扩展注解的配置](#扩展注解配置)。 - -service、reference 组件也可以通过 `id` 与 application 中的全局组件做关联,以下面配置为例: - -```yaml -dubbo: - application: - name: dubbo-springboot-demo-provider - protocol: - name: dubbo - port: -1 - registry: - id: zk-registry - address: zookeeper://127.0.0.1:2181 - config-center: - address: zookeeper://127.0.0.1:2181 - metadata-report: - address: zookeeper://127.0.0.1:2181 -``` - -通过注解将 service 关联到上文定义的特定注册中心 -```java -@DubboService(registry="zk-registry") -public class DemoServiceImpl implements DemoService {} -``` - -通过 Java Config 配置进行关联也是同样道理 -```java -@Configuration -public class ProviderConfiguration { - @Bean - public ServiceConfig demoService() { - ServiceConfig service = new ServiceConfig(); - service.setRegistry("zk-registry"); - return service; - } -} -``` -## 注解 -### @DubboService 注解 - -> `@Service` 注解从 3.0 版本开始就已经废弃,改用 `@DubboService`,以区别于 Spring 的 `@Service` 注解 - -定义好 Dubbo 服务接口后,提供服务接口的实现逻辑,并用 `@DubboService` 注解标记,就可以实现 Dubbo 的服务暴露 - -```java -@DubboService -public class DemoServiceImpl implements DemoService {} -``` - -如果要设置服务参数,`@DubboService` 也提供了常用参数的设置方式。如果有更复杂的参数设置需求,则可以考虑使用其他设置方式 -```java -@DubboService(version = "1.0.0", group = "dev", timeout = 5000) -public class DemoServiceImpl implements DemoService {} -``` - -### @DubboReference 注解 - -> `@Reference` 注解从 3.0 版本开始就已经废弃,改用 `@DubboReference`,以区别于 Spring 的 `@Reference` 注解 - -```java -@Component -public class DemoClient { - @DubboReference - private DemoService demoService; -} -``` - -`@DubboReference` 注解将自动注入为 Dubbo 服务代理实例,使用 demoService 即可发起远程服务调用 - -### @EnableDubbo 注解 -`@EnableDubbo` 注解必须配置,否则将无法加载 Dubbo 注解定义的服务,`@EnableDubbo` 可以定义在主类上 - -```java -@SpringBootApplication -@EnableDubbo -public class ProviderApplication { - public static void main(String[] args) throws Exception { - SpringApplication.run(ProviderApplication.class, args); - } -} -``` - -Spring Boot 注解默认只会扫描 main 类所在的 package,如果服务定义在其它 package 中,需要增加配置 `EnableDubbo(scanBasePackages = {"org.apache.dubbo.springboot.demo.provider"})` - -### 扩展注解配置 -虽然可以通过 `@DubboService` 和 `DubboReference` 调整配置参数(如下代码片段所示),但总体来说注解提供的配置项还是非常有限。在这种情况下,如果有更复杂的参数设置需求,可以使用 `Java Config` 或 `dubbo.properties` 两种方式。 - -```java -@DubboService(version = "1.0.0", group = "dev", timeout = 5000) -@DubboReference(version = "1.0.0", group = "dev", timeout = 5000) -``` - -### 使用 Java Config 代替注解 - -注意,Java Config 是 `DubboService` 或 `DubboReference` 的替代方式,对于有复杂配置需求的服务建议使用这种方式。 - -```java -@Configuration -public class ProviderConfiguration { - @Bean - public ServiceConfig demoService() { - ServiceConfig service = new ServiceConfig(); - service.setInterface(DemoService.class); - service.setRef(new DemoServiceImpl()); - service.setGroup("dev"); - service.setVersion("1.0.0"); - Map parameters = new HashMap<>(); - service.setParameters(parameters); - return service; - } -} -``` - -### 通过 dubbo.properties 补充配置 -对于使用 `DubboService` 或 `DubboReference` 的场景,可以使用 dubbo.properties 作为配置补充,[具体格式](../principle/#1-配置格式)这里有更详细解释。 - -```properties -dubbo.service.org.apache.dubbo.springboot.demo.DemoService.timeout=5000 -dubbo.service.org.apache.dubbo.springboot.demo.DemoService.parameters=[{myKey:myValue},{anotherKey:anotherValue}] -dubbo.reference.org.apache.dubbo.springboot.demo.DemoService.timeout=6000 -``` - -> properties 格式配置目前结构性不太强,比如体现在 key 字段冗余较多,后续会考虑提供对于 yaml 格式的支持。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/config/api.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/config/api.md deleted file mode 100644 index 903fa626cde6..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/config/api.md +++ /dev/null @@ -1,315 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/reference-manual/config/api/ - - /zh-cn/docs3-v2/java-sdk/reference-manual/config/api/ -description: 以 API 的方式来配置你的 Dubbo 应用 -linkTitle: ' API 配置' -title: API 配置 -type: docs -weight: 2 ---- - - - - - - -通过 API 编码方式组装配置、启动 Dubbo、发布及订阅服务。此方式可以支持动态创建 ReferenceConfig/ServiceConfig,结合泛化调用可以满足 API Gateway 或测试平台的需要。 - -> 参考 [API示例](https://github.com/apache/dubbo-samples/tree/master/1-basic/dubbo-samples-api) - -## 服务提供者 - -通过 ServiceConfig 暴露服务接口,发布服务接口到注册中心。 - -> 注意:为了更好支持 Dubbo3 应用级服务发现,推荐使用新的 [DubboBootstrap API](#bootstrap-api)。 - -```java -import org.apache.dubbo.config.ApplicationConfig; -import org.apache.dubbo.config.RegistryConfig; -import org.apache.dubbo.config.ProviderConfig; -import org.apache.dubbo.config.ServiceConfig; -import com.xxx.DemoService; -import com.xxx.DemoServiceImpl; - -public class DemoProvider { - public static void main(String[] args) { - // 服务实现 - DemoService demoService = new DemoServiceImpl(); - - // 当前应用配置 - ApplicationConfig application = new ApplicationConfig(); - application.setName("demo-provider"); - - // 连接注册中心配置 - RegistryConfig registry = new RegistryConfig(); - registry.setAddress("zookeeper://10.20.130.230:2181"); - - // 服务提供者协议配置 - ProtocolConfig protocol = new ProtocolConfig(); - protocol.setName("dubbo"); - protocol.setPort(12345); - protocol.setThreads(200); - - // 注意:ServiceConfig为重对象,内部封装了与注册中心的连接,以及开启服务端口 - // 服务提供者暴露服务配置 - ServiceConfig service = new ServiceConfig(); // 此实例很重,封装了与注册中心的连接,请自行缓存,否则可能造成内存和连接泄漏 - service.setApplication(application); - service.setRegistry(registry); // 多个注册中心可以用setRegistries() - service.setProtocol(protocol); // 多个协议可以用setProtocols() - service.setInterface(DemoService.class); - service.setRef(demoService); - service.setVersion("1.0.0"); - - // 暴露及注册服务 - service.export(); - - // 挂起等待(防止进程退出) - System.in.read(); - } -} -``` - -## 服务消费者 - -通过 ReferenceConfig 引用远程服务,从注册中心订阅服务接口。 - -> 注意:为了更好支持 Dubbo3 应用级服务发现,推荐使用新的 [DubboBootstrap API](#bootstrap-api)。 - -```java -import org.apache.dubbo.config.ApplicationConfig; -import org.apache.dubbo.config.RegistryConfig; -import org.apache.dubbo.config.ConsumerConfig; -import org.apache.dubbo.config.ReferenceConfig; -import com.xxx.DemoService; - -public class DemoConsumer { - public static void main(String[] args) { - // 当前应用配置 - ApplicationConfig application = new ApplicationConfig(); - application.setName("demo-consumer"); - - // 连接注册中心配置 - RegistryConfig registry = new RegistryConfig(); - registry.setAddress("zookeeper://10.20.130.230:2181"); - - // 注意:ReferenceConfig为重对象,内部封装了与注册中心的连接,以及与服务提供方的连接 - // 引用远程服务 - ReferenceConfig reference = new ReferenceConfig(); // 此实例很重,封装了与注册中心的连接以及与提供者的连接,请自行缓存,否则可能造成内存和连接泄漏 - reference.setApplication(application); - reference.setRegistry(registry); // 多个注册中心可以用setRegistries() - reference.setInterface(DemoService.class); - reference.setVersion("1.0.0"); - - // 和本地bean一样使用demoService - // 注意:此代理对象内部封装了所有通讯细节,对象较重,请缓存复用 - DemoService demoService = reference.get(); - demoService.sayHello("Dubbo"); - } -} -``` - -## Bootstrap API - -通过 DubboBootstrap API 可以减少重复配置,更好控制启动过程,支持批量发布/订阅服务接口,还可以更好支持 Dubbo3 的应用级服务发现。 - -```java -import org.apache.dubbo.config.bootstrap.DubboBootstrap; -import org.apache.dubbo.config.ApplicationConfig; -import org.apache.dubbo.config.RegistryConfig; -import org.apache.dubbo.config.ProviderConfig; -import org.apache.dubbo.config.ServiceConfig; -import com.xxx.DemoService; -import com.xxx.DemoServiceImpl; - -public class DemoProvider { - public static void main(String[] args) { - - ConfigCenterConfig configCenter = new ConfigCenterConfig(); - configCenter.setAddress("zookeeper://127.0.0.1:2181"); - - // 服务提供者协议配置 - ProtocolConfig protocol = new ProtocolConfig(); - protocol.setName("dubbo"); - protocol.setPort(12345); - protocol.setThreads(200); - - // 注意:ServiceConfig为重对象,内部封装了与注册中心的连接,以及开启服务端口 - // 服务提供者暴露服务配置 - ServiceConfig demoServiceConfig = new ServiceConfig<>(); - demoServiceConfig.setInterface(DemoService.class); - demoServiceConfig.setRef(new DemoServiceImpl()); - demoServiceConfig.setVersion("1.0.0"); - - // 第二个服务配置 - ServiceConfig fooServiceConfig = new ServiceConfig<>(); - fooServiceConfig.setInterface(FooService.class); - fooServiceConfig.setRef(new FooServiceImpl()); - fooServiceConfig.setVersion("1.0.0"); - - ... - - // 通过DubboBootstrap简化配置组装,控制启动过程 - DubboBootstrap.getInstance() - .application("demo-provider") // 应用配置 - .registry(new RegistryConfig("zookeeper://127.0.0.1:2181")) // 注册中心配置 - .protocol(protocol) // 全局默认协议配置 - .service(demoServiceConfig) // 添加ServiceConfig - .service(fooServiceConfig) - .start() // 启动Dubbo - .await(); // 挂起等待(防止进程退出) - } -} -``` - -```java -import org.apache.dubbo.config.bootstrap.DubboBootstrap; -import org.apache.dubbo.config.ApplicationConfig; -import org.apache.dubbo.config.RegistryConfig; -import org.apache.dubbo.config.ProviderConfig; -import org.apache.dubbo.config.ServiceConfig; -import com.xxx.DemoService; -import com.xxx.DemoServiceImpl; - -public class DemoConsumer { - public static void main(String[] args) { - - // 引用远程服务 - ReferenceConfig demoServiceReference = new ReferenceConfig(); - demoServiceReference.setInterface(DemoService.class); - demoServiceReference.setVersion("1.0.0"); - - ReferenceConfig fooServiceReference = new ReferenceConfig(); - fooServiceReference.setInterface(FooService.class); - fooServiceReference.setVersion("1.0.0"); - - // 通过DubboBootstrap简化配置组装,控制启动过程 - DubboBootstrap bootstrap = DubboBootstrap.getInstance(); - bootstrap.application("demo-consumer") // 应用配置 - .registry(new RegistryConfig("zookeeper://127.0.0.1:2181")) // 注册中心配置 - .reference(demoServiceReference) // 添加ReferenceConfig - .reference(fooServiceReference) - .start(); // 启动Dubbo - - ... - - // 和本地bean一样使用demoService - // 通过Interface获取远程服务接口代理,不需要依赖ReferenceConfig对象 - DemoService demoService = DubboBootstrap.getInstance().getCache().get(DemoService.class); - demoService.sayHello("Dubbo"); - - FooService fooService = DubboBootstrap.getInstance().getCache().get(FooService.class); - fooService.greeting("Dubbo"); - } - -} - -``` - -## 其它配置 - -API 提供了最灵活丰富的配置能力,以下是一些可配置组件示例。 - -### 基本配置 - -可以在 DubboBootstrap 中设置全局基本配置,包括应用配置、协议配置、注册中心、配置中心、元数据中心、模块、监控、SSL、provider 配置、consumer 配置等。 - -```java -// 注册中心 -RegistryConfig registry = new RegistryConfig(); -registry.setAddress("zookeeper://192.168.10.1:2181"); -... - -// 服务提供者协议配置 -ProtocolConfig protocol = new ProtocolConfig(); -protocol.setName("dubbo"); -protocol.setPort(12345); -protocol.setThreads(200); -... - -// 配置中心 -ConfigCenterConfig configCenter = new ConfigCenterConfig(); -configCenter.setAddress("zookeeper://192.168.10.2:2181"); -... - -// 元数据中心 -MetadataReportConfig metadataReport = new MetadataReportConfig(); -metadataReport.setAddress("zookeeper://192.168.10.3:2181"); -... - -// Metrics -MetricsConfig metrics = new MetricsConfig(); -metrics.setProtocol("dubbo"); -... - -// SSL -SslConfig ssl = new SslConfig(); -ssl.setServerKeyCertChainPath("/path/ssl/server-key-cert-chain"); -ssl.setServerPrivateKeyPath("/path/ssl/server-private-key"); -... - -// Provider配置(ServiceConfig默认配置) -ProviderConfig provider = new ProviderConfig(); -provider.setGroup("demo"); -provider.setVersion("1.0.0"); -... - -// Consumer配置(ReferenceConfig默认配置) -ConsumerConfig consumer = new ConsumerConfig(); -consumer.setGroup("demo"); -consumer.setVersion("1.0.0"); -consumer.setTimeout(2000); -... - -DubboBootstrap.getInstance() - .application("demo-app") - .registry(registry) - .protocol(protocol) - .configCenter(configCenter) - .metadataReport(metadataReport) - .module(new ModuleConfig("module")) - .metrics(metrics) - .ssl(ssl) - .provider(provider) - .consumer(consumer) - ... - .start(); - -``` - -### 方法级设置 - -```java -... - -// 方法级配置 -List methods = new ArrayList(); -MethodConfig method = new MethodConfig(); -method.setName("sayHello"); -method.setTimeout(10000); -method.setRetries(0); -methods.add(method); - -// 引用远程服务 -ReferenceConfig reference = new ReferenceConfig(); // 此实例很重,封装了与注册中心的连接以及与提供者的连接,请自行缓存,否则可能造成内存和连接泄漏 -... -reference.setMethods(methods); // 设置方法级配置 - -... -``` - -### 点对点直连 - -```java - -... - -// 此实例很重,封装了与注册中心的连接以及与提供者的连接,请自行缓存,否则可能造成内存和连接泄漏 -ReferenceConfig reference = new ReferenceConfig(); -// 如果点对点直连,可以用reference.setUrl()指定目标地址,设置url后将绕过注册中心, -// 其中,协议对应provider.setProtocol()的值,端口对应provider.setPort()的值, -// 路径对应service.setPath()的值,如果未设置path,缺省path为接口名 -reference.setUrl("dubbo://10.20.130.230:20880/com.xxx.DemoService"); - -... -``` \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/config/api/_index.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/config/api/_index.md new file mode 100644 index 000000000000..d6ab16f56a08 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/config/api/_index.md @@ -0,0 +1,10 @@ +--- +aliases: + - /zh/docs3-v2/java-sdk/reference-manual/config/ + - /zh-cn/docs3-v2/java-sdk/reference-manual/config/ +description: Dubbo 配置指南 +linkTitle: 原生API +title: 配置手册 +type: docs +weight: 1 +--- diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/config/api/api.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/config/api/api.md new file mode 100644 index 000000000000..1f14a143ebc5 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/config/api/api.md @@ -0,0 +1,389 @@ +--- +aliases: + - /zh/docs3-v2/java-sdk/reference-manual/config/api/ + - /zh-cn/docs3-v2/java-sdk/reference-manual/config/api/ +description: 以 API 的方式来配置你的 Dubbo 应用 +linkTitle: API 配置 +title: API 配置 +type: docs +weight: 2 +--- + +作为一款 RPC 框架,Dubbo 定义了一套完善的 API 接口,我们可以基于原生 API 开发 Dubbo 应用,关于如何使用原生API开发轻量RPC、微服务应用等的具体示例可查看 [使用教程 - API开发模式](/zh-cn/overview/mannual/java-sdk/tasks/develop/api/) 中的示例。它的适用场景包括以下两类: +* **轻量 RPC Server & Client**,通常用于一些应用内、基础组件、中间件等内的简单远程调用场景 +* **微服务应用**,不依赖 Spring、Spring Boot 的情况下,直接用 API 开发微服务;同时,直接使用 API 对于一些网关或测试平台集成场景也可能比较有用。 + +目前的入口 API 主要有 `Bootstrap`、`ServiceConfig`、`ReferenceConfig` 等,分别用于不同场景下的 Dubbo 应用开发。 + +## Bootstrap API + +DubboBootstrap 实例代表一个 Dubbo 应用,是整个 Dubbo 应用的启动入口。在 DubboBootstrap 基础上,我们可以设置 protocol、service、registry、metrics 等来注册服务、连接注册中心等,这和我们在 Spring Boot 中调整 application.yml 或者 application.properties 文件是对等的作用。 + +官方推荐使用 DubboBootstrap.start() 作为应用的集中启动入口,但为了方便在进程启动后,在运行态单独发布一些服务,Dubbo 也允许直接调用 ServiceConfig.export() 或 ReferenceConfig.refer() 方法发布服务,这时 Service/Reference 会注册到默认的 DubboBootstrap 实例中,效果同调用 DubboBootstrap.service(...).start() 类似。 + +```java +import org.apache.dubbo.config.bootstrap.DubboBootstrap; +import org.apache.dubbo.config.ApplicationConfig; +import org.apache.dubbo.config.RegistryConfig; +import org.apache.dubbo.config.ProviderConfig; +import org.apache.dubbo.config.ServiceConfig; +import com.xxx.DemoService; +import com.xxx.DemoServiceImpl; + +public class DemoProvider { + public static void main(String[] args) { + + ConfigCenterConfig configCenter = new ConfigCenterConfig(); + configCenter.setAddress("zookeeper://127.0.0.1:2181"); + + // 服务提供者协议配置 + ProtocolConfig protocol = new ProtocolConfig(); + protocol.setName("dubbo"); + protocol.setPort(12345); + protocol.setThreads(200); + + // 注意:ServiceConfig为重对象,内部封装了与注册中心的连接,以及开启服务端口 + // 服务提供者暴露服务配置 + ServiceConfig demoServiceConfig = new ServiceConfig<>(); + demoServiceConfig.setInterface(DemoService.class); + demoServiceConfig.setRef(new DemoServiceImpl()); + demoServiceConfig.setVersion("1.0.0"); + + // 第二个服务配置 + ServiceConfig fooServiceConfig = new ServiceConfig<>(); + fooServiceConfig.setInterface(FooService.class); + fooServiceConfig.setRef(new FooServiceImpl()); + fooServiceConfig.setVersion("1.0.0"); + + ... + + // 通过DubboBootstrap简化配置组装,控制启动过程 + DubboBootstrap.getInstance() + .application("demo-provider") // 应用配置 + .registry(new RegistryConfig("zookeeper://127.0.0.1:2181")) // 注册中心配置 + .protocol(protocol) // 全局默认协议配置 + .service(demoServiceConfig) // 添加ServiceConfig + .service(fooServiceConfig) + .start() // 启动Dubbo + .await(); // 挂起等待(防止进程退出) + } +} +``` + +```java +import org.apache.dubbo.config.bootstrap.DubboBootstrap; +import org.apache.dubbo.config.ApplicationConfig; +import org.apache.dubbo.config.RegistryConfig; +import org.apache.dubbo.config.ProviderConfig; +import org.apache.dubbo.config.ServiceConfig; +import com.xxx.DemoService; +import com.xxx.DemoServiceImpl; + +public class DemoConsumer { + public static void main(String[] args) { + + // 引用远程服务 + ReferenceConfig demoServiceReference = new ReferenceConfig(); + demoServiceReference.setInterface(DemoService.class); + demoServiceReference.setVersion("1.0.0"); + + ReferenceConfig fooServiceReference = new ReferenceConfig(); + fooServiceReference.setInterface(FooService.class); + fooServiceReference.setVersion("1.0.0"); + + // 通过DubboBootstrap简化配置组装,控制启动过程 + DubboBootstrap bootstrap = DubboBootstrap.getInstance(); + bootstrap.application("demo-consumer") // 应用配置 + .registry(new RegistryConfig("zookeeper://127.0.0.1:2181")) // 注册中心配置 + .reference(demoServiceReference) // 添加ReferenceConfig + .reference(fooServiceReference) + .start(); // 启动Dubbo + + ... + + // 和本地bean一样使用demoService + // 通过Interface获取远程服务接口代理,不需要依赖ReferenceConfig对象 + DemoService demoService = DubboBootstrap.getInstance().getCache().get(DemoService.class); + demoService.sayHello("Dubbo"); + + FooService fooService = fooServiceReference.get(); + fooService.greeting("Dubbo"); + } + +} +``` + +### 基本配置 + +可以在 DubboBootstrap 中设置全局基本配置,包括应用配置、协议配置、注册中心、配置中心、元数据中心、模块、监控、SSL、provider 配置、consumer 配置等。 + +```java +// 注册中心 +RegistryConfig registry = new RegistryConfig(); +registry.setAddress("zookeeper://192.168.10.1:2181"); +... + +// 服务提供者协议配置 +ProtocolConfig protocol = new ProtocolConfig(); +protocol.setName("dubbo"); +protocol.setPort(12345); +protocol.setThreads(200); +... + +// 配置中心 +ConfigCenterConfig configCenter = new ConfigCenterConfig(); +configCenter.setAddress("zookeeper://192.168.10.2:2181"); +... + +// 元数据中心 +MetadataReportConfig metadataReport = new MetadataReportConfig(); +metadataReport.setAddress("zookeeper://192.168.10.3:2181"); +... + +// Metrics +MetricsConfig metrics = new MetricsConfig(); +metrics.setProtocol("dubbo"); +... + +// SSL +SslConfig ssl = new SslConfig(); +ssl.setServerKeyCertChainPath("/path/ssl/server-key-cert-chain"); +ssl.setServerPrivateKeyPath("/path/ssl/server-private-key"); +... + +// Provider配置(ServiceConfig默认配置) +ProviderConfig provider = new ProviderConfig(); +provider.setGroup("demo"); +provider.setVersion("1.0.0"); +... + +// Consumer配置(ReferenceConfig默认配置) +ConsumerConfig consumer = new ConsumerConfig(); +consumer.setGroup("demo"); +consumer.setVersion("1.0.0"); +consumer.setTimeout(2000); +... + +DubboBootstrap.getInstance() + .application("demo-app") + .registry(registry) + .protocol(protocol) + .configCenter(configCenter) + .metadataReport(metadataReport) + .module(new ModuleConfig("module")) + .metrics(metrics) + .ssl(ssl) + .provider(provider) + .consumer(consumer) + ... + .start(); + +``` + +### 方法级设置 + +```java +... + +// 方法级配置 +List methods = new ArrayList(); +MethodConfig method = new MethodConfig(); +method.setName("sayHello"); +method.setTimeout(10000); +method.setRetries(0); +methods.add(method); + +// 引用远程服务 +ReferenceConfig reference = new ReferenceConfig(); // 此实例很重,封装了与注册中心的连接以及与提供者的连接,请自行缓存,否则可能造成内存和连接泄漏 +... +reference.setMethods(methods); // 设置方法级配置 + +... +``` + +### 点对点直连 + +```java + +... + +// 此实例很重,封装了与注册中心的连接以及与提供者的连接,请自行缓存,否则可能造成内存和连接泄漏 +ReferenceConfig reference = new ReferenceConfig(); +// 如果点对点直连,可以用reference.setUrl()指定目标地址,设置url后将绕过注册中心, +// 其中,协议对应provider.setProtocol()的值,端口对应provider.setPort()的值, +// 路径对应service.setPath()的值,如果未设置path,缺省path为接口名 +reference.setUrl("dubbo://10.20.130.230:20880/com.xxx.DemoService"); + +... +``` + +## ServiceConfig + +通过 ServiceConfig 可以直接发布服务,将服务接口注册到内存列表和注册中心。这对于一些需要动态发布服务的场景可能非常有用。 + +> 注意:对于普通的应用开发场景,我们更推荐使用 [DubboBootstrap API](#bootstrap-api)。 + +```java +import org.apache.dubbo.config.ApplicationConfig; +import org.apache.dubbo.config.RegistryConfig; +import org.apache.dubbo.config.ProviderConfig; +import org.apache.dubbo.config.ServiceConfig; +import com.xxx.DemoService; +import com.xxx.DemoServiceImpl; + +public class DemoProvider { + public static void main(String[] args) { + // 服务实现 + DemoService demoService = new DemoServiceImpl(); + + // 当前应用配置 + ApplicationConfig application = new ApplicationConfig(); + application.setName("demo-provider"); + + // 连接注册中心配置 + RegistryConfig registry = new RegistryConfig(); + registry.setAddress("zookeeper://10.20.130.230:2181"); + + // 服务提供者协议配置 + ProtocolConfig protocol = new ProtocolConfig(); + protocol.setName("dubbo"); + protocol.setPort(12345); + protocol.setThreads(200); + + // 注意:ServiceConfig为重对象,内部封装了与注册中心的连接,以及开启服务端口 + // 服务提供者暴露服务配置 + ServiceConfig service = new ServiceConfig(); // 此实例很重,封装了与注册中心的连接,请自行缓存,否则可能造成内存和连接泄漏 + service.setApplication(application); + service.setRegistry(registry); // 多个注册中心可以用setRegistries() + service.setProtocol(protocol); // 多个协议可以用setProtocols() + service.setInterface(DemoService.class); + service.setRef(demoService); + service.setVersion("1.0.0"); + + // 暴露及注册服务 + service.export(); + + // 挂起等待(防止进程退出) + System.in.read(); + } +} +``` + +## ReferenceConfig + +通过 ReferenceConfig 引用远程服务,从注册中心订阅服务接口。这对于一些需要动态发布服务的场景是可能会非常有用。 + +> 注意:对于普通应用开发,我们推荐使用 [DubboBootstrap API](#bootstrap-api)。 + +```java +import org.apache.dubbo.config.ApplicationConfig; +import org.apache.dubbo.config.RegistryConfig; +import org.apache.dubbo.config.ConsumerConfig; +import org.apache.dubbo.config.ReferenceConfig; +import com.xxx.DemoService; + +public class DemoConsumer { + public static void main(String[] args) { + // 当前应用配置 + ApplicationConfig application = new ApplicationConfig(); + application.setName("demo-consumer"); + + // 连接注册中心配置 + RegistryConfig registry = new RegistryConfig(); + registry.setAddress("zookeeper://10.20.130.230:2181"); + + // 注意:ReferenceConfig为重对象,内部封装了与注册中心的连接,以及与服务提供方的连接 + // 引用远程服务 + ReferenceConfig reference = new ReferenceConfig(); // 此实例很重,封装了与注册中心的连接以及与提供者的连接,请自行缓存,否则可能造成内存和连接泄漏 + reference.setApplication(application); + reference.setRegistry(registry); // 多个注册中心可以用setRegistries() + reference.setInterface(DemoService.class); + reference.setVersion("1.0.0"); + + // 和本地bean一样使用demoService + // 注意:此代理对象内部封装了所有通讯细节,对象较重,请缓存复用 + DemoService demoService = reference.get(); + demoService.sayHello("Dubbo"); + } +} +``` + +## 多实例部署 + +多实例部署的背景起源于 Dubbo 在阿里集团内的大规模应用部署场景,阿里集团遇到的问题主要有: +1. 阿里集团内有众多的中间件框架,这些框架提供了各种各样的类加载方式,不同的业务方期望在同一应用内的配置等信息是相互隔离的。 +2. 一些业务方的定制逻辑需要支持动态热部署模式,具体体现在动态对某个虚拟环境进行销毁,这需要 Dubbo 内的生命周期管理更加完善。 +3. 阿里集团内有多个对 Spring 容器进行定制化开发的框架,需要 Dubbo 能够支持多个 Spring Context 独立管理生命周期的场景。 + +![多实例架构图](/imgs/v3/manual/java/multi-instance/arch.png) + + +整个 Dubbo 多实例的设计我们按照了三层模型来配置,分别是 Framework 框架层、Application 应用层、Module 模块层。 + +基于三层机制,我们可以将 Dubbo 按照一定规则进行隔离: +1. Framework 与 Framework 之间完全隔离,相当于是使用了两个完全不同的 Dubbo 实例 +2. Application 与 Application 之间按照应用名进行隔离,但是相互有些地共享 Protocol、Serialization 层,目标是达到在同一个 dubbo 端口(20880)上可以承载多个应用,而每个应用独立上报地址信息。 +3. Module 与 Module 之间可以由用户自定义进行进行隔离,可以是热部署周期的一个状态、也可以是 Spring Context 的一个 Context。通过 Module,用户可以对 Dubbo 的生命周期粒度进行最小的管理。 + +为了实现 Dubbo 多实例化,Dubbo 框架内做的最多的变化是修改掉大部分的从静态变量中获取的参数的逻辑,最明显的逻辑是 Dubbo 内部用于参数传递的 URL 对象带上了 ScopeModel 状态,这个 ScopeModel 对应的就是上面提到的三层模型的具体数据承载对象。 +关于多示例的更多实现原理、设计细节等,请参考 [源码架构 - 多实例设计与实现](/zh-cn/overview/mannual/java-sdk/reference-manual/architecture/multi-instance/)。 + + +```java +ServiceConfig service = new ServiceConfig<>(); +service.setInterface(DemoService.class); +service.setRef(new DemoServiceImpl()); + +ReferenceConfig reference1 = new ReferenceConfig<>(); +reference1.setInterface(DemoService.class); + +ReferenceConfig reference2 = new ReferenceConfig<>(); +reference2.setInterface(DemoService.class); + +// 创建一个启动器(自动创建新 ApplicationModel) +DubboBootstrap bootstrap1 = DubboBootstrap.newInstance(); +// 指定应用名 +bootstrap1.application(new ApplicationConfig("dubbo-demo-app-1")) + .registry(new RegistryConfig("nacos://localhost:8848")) + // 创建一个模块 + .newModule() + // 在模块内发布服务 + .service(service) + .endModule() + // 创建一个模块 + .newModule() + // 在模块内订阅服务 + .reference(reference1) + .endModule() + .start(); + +// 创建一个启动器(自动创建新 ApplicationModel) +DubboBootstrap bootstrap2 = DubboBootstrap.newInstance(); +// 指定应用名 +bootstrap2.application(new ApplicationConfig("dubbo-demo-app-2")) + .registry(new RegistryConfig("nacos://localhost:8848")) + // 创建一个模块 + .newModule() + // 在模块内订阅服务 + .reference(reference2) + .endModule() + .start(); + +// stub1 与 stub2 是两个独立的订阅,互相隔离 + +// 订阅的 stub +DemoService stub1 = reference1.get(); +System.out.println(stub1.sayHello("Hello World!")); + +// 订阅的 stub +DemoService stub2 = reference2.get(); +System.out.println(stub2.sayHello("Hello World!")); + +bootstrap1.stop(); +bootstrap2.stop(); +``` + +这个例子对外发布了一个 DemoService 的服务,由 dubbo-demo-app-1 这个应用提供。同时我们创建了两个订阅,分别是在 dubbo-demo-app-1 应用和 dubbo-demo-app-2 应用中,然后我们去对两个订阅进行调用,得到预期的结果。 + +这里需要注意的是虽然两个订阅的服务信息是完全一致的,在多实例化改造后,这两个订阅对于消费端来说是完全隔离的,也就是在最新版本的 Dubbo 中是支持三元组一样的情况下通过变更参数来创建多个订阅的行为的了。 + diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/config/maven-plugin.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/config/maven-plugin.md new file mode 100644 index 000000000000..fb8caed662dc --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/config/maven-plugin.md @@ -0,0 +1,179 @@ +--- +description: Dubbo Maven Plugin 的配置方式 +linkTitle: Maven Plugin 配置 +title: Dubbo Maven Plugin 的配置方式 +type: docs +weight: 3 +--- + +本文主要讲解 Dubbo Maven Plugin 的配置方式。 + +当前 Dubbo Maven Plugin 支持以下功能: +- Dubbo Maven Plugin For Protobuf:生成 Dubbo 服务接口的 Stub 代码 +- Dubbo Maven Plugin For Native Image:基于 AOT 机制,生成 Native Image 必要的 Metadata 信息 + +## Dubbo Maven Plugin For Protobuf + +### 如何使用 Dubbo Maven Plugin 生成 Protobuf Stub 代码 + +#### 1. 编写 .proto 文件 + +greeter.proto + +```protobuf +syntax = "proto3"; + +option java_multiple_files = true; +option java_package = "org.apache.dubbo.demo"; +option java_outer_classname = "DemoServiceProto"; +option objc_class_prefix = "DEMOSRV"; + +package demoservice; + +// The demo service definition. +service DemoService { + rpc SayHello (HelloRequest) returns (HelloReply) {} +} + +// The request message containing the user's name. +message HelloRequest { + string name = 1; +} + +// The response message containing the greetings +message HelloReply { + string message = 1; +} + +``` + +#### 2. 引入 dubbo-maven-plugin 依赖 + +```xml + + + org.apache.dubbo + dubbo-maven-plugin + ${dubbo.version} + + + + compile + + + + +``` + +#### 3. 生成文件示例 + +```java +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.dubbo.demo; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.atomic.AtomicBoolean; + +public final class DemoServiceDubbo { + private static final AtomicBoolean registered = new AtomicBoolean(); + + private static Class init() { + Class clazz = null; + try { + clazz = Class.forName(DemoServiceDubbo.class.getName()); + if (registered.compareAndSet(false, true)) { + org.apache.dubbo.common.serialize.protobuf.support.ProtobufUtils.marshaller( + org.apache.dubbo.demo.HelloReply.getDefaultInstance()); + org.apache.dubbo.common.serialize.protobuf.support.ProtobufUtils.marshaller( + org.apache.dubbo.demo.HelloRequest.getDefaultInstance()); + } + } catch (ClassNotFoundException e) { +// ignore + } + return clazz; + } + + private DemoServiceDubbo() { + } + + public static final String SERVICE_NAME = "org.apache.dubbo.demo.DemoService"; + + /** + * Code generated for Dubbo + */ + public interface IDemoService extends org.apache.dubbo.rpc.model.DubboStub { + + static Class clazz = init(); + + org.apache.dubbo.demo.HelloReply sayHello(org.apache.dubbo.demo.HelloRequest request); + + CompletableFuture sayHelloAsync(org.apache.dubbo.demo.HelloRequest request); + + + } + +} + +``` + +### 配置列表 + +Dubbo Maven Plugin For Protobuf 支持以下配置: + +| 配置参数 | 必填 | 解释 | 默认值 | 示例 | +|----------------------|-------|--------------------------------------------------------|------------------------------------------------------------|---------------------------------------------------------------------------| +| dubboVersion | true | Dubbo 版本号,用于查找 dubbo-compiler 组件 | ${dubbo.version} | 3.3.0 | +| dubboGenerateType | true | 生成的文件类型 | tri | tri 或 tri-reactor | +| protocExecutable | false | 可执行的 protoc 路径,如不配置将自动从 Maven 仓库下载 | | protoc | +| protocArtifact | false | protoc 在 Maven 仓库中定位,用于下载 protoc 文件,如不配置将自动识别操作系统类型并下载 | | com.google.protobuf:protoc:${protoc.version}:exe:${os.detected.classifier} | +| protoSourceDir | true | proto 文件目录 | ${basedir}/src/main/proto | ./proto | +| outputDir | true | 生成文件的目标目录 | ${project.build.directory}/generated-sources/protobuf/java | ${basedir}/src/main/java | +| protocPluginDirectory | false | 临时存储 protoc 的目录 | ${project.build.directory}/protoc-plugins | ./target/protoc-plugins | + +## Dubbo Maven Plugin For Native Image + +### 示例 + +```xml + + org.apache.dubbo + dubbo-maven-plugin + ${dubbo.version} + + com.example.nativedemo.NativeDemoApplication + + + + process-sources + + dubbo-process-aot + + + + +``` + + +### 配置列表 + +Dubbo Maven Plugin For Native Image 支持以下配置: + +| 配置参数 | 必填 | 解释 | 默认值 | 示例 | +|----------------------|-------|------|------------------------------------------------------------|---------------------------------------------------------------------------| +| mainClass | true | 启动类名 | | com.example.nativedemo.NativeDemoApplication | diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/config/overview.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/config/overview.md deleted file mode 100644 index a974f21c759a..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/config/overview.md +++ /dev/null @@ -1,174 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/reference-manual/config/overview/ - - /zh-cn/docs3-v2/java-sdk/reference-manual/config/overview/ -description: 对 Dubbo 配置总体设计与工作原理进行了总体概述,包括配置组件、配置来源、配置方式及配置加载流程等。 -linkTitle: 配置概述 -title: 配置概述 -type: docs -weight: 1 ---- - - - - - - -* [使用 Spring Boot 快速开发 Dubbo 应用](../../../quick-start/spring-boot/) - -* [配置项参考手册](../properties) - -* [配置加载及覆盖的工作原理](../principle) - -组件名称 | 描述 | 范围 | 是否必须配置 ------- | ------ | ------ | ------ -application | 指定应用名等应用级别相关信息 | 一个应用内只允许出现一个 | 必选 -service | 声明普通接口或实现类为 Dubbo 服务 | 一个应用内可以有 0 到多个 service | service/reference 至少一种 -reference | 声明普通接口为 Dubbo 服务 | 一个应用内可以有 0 到多个 reference | service/reference 至少一种 -protocol | 要暴露的 RPC 协议及相关配置如端口号等 | 一个应用可配置多个,一个 protocol 可作用于一组 service&reference | 可选,默认 dubbo -registry | 注册中心类型、地址及相关配置 | 一个应用内可配置多个,一个 registry 可作用于一组 service&reference| 必选 -config-center | 配置中心类型、地址及相关配置 | 一个应用内可配置多个,所有服务共享 | 可选 -metadata-report | 元数据中心类型、地址及相关配置 | 一个应用内可配置多个,所有服务共享 | 可选 -consumer | reference 间共享的默认配置 | 一个应用内可配置多个,一个 consumer 可作用于一组 reference | 可选 -provider | service 间共享的默认配置 | 一个应用内可配置多个,一个 provider 可作用于一组 service | 可选 -monitor | 监控系统类型及地址 | 一个应用内只允许配置一个 | 可选 -metrics | 数据采集模块相关配置 | 一个应用内只允许配置一个 | 可选 -ssl | ssl/tls 安全链接相关的证书等配置 | 一个应用内只允许配置一个 | 可选 -method | 指定方法级的配置 | service 和 reference 的子配置 | 可选 -argument | 某个方法的参数配置 | method的子配置 | 可选 - -## 实现原理 - -为了更好地管理各种配置,Dubbo 抽象了一套结构化的配置组件,各组件总体以用途划分,分别控制不同作用域的行为。 - -![dubbo-config](/imgs/user/dubbo-config.jpg) - - - - -> 从实现原理层面,最终 Dubbo 所有的配置项都会被组装到 URL 中,以 URL 为载体在后续的启动、RPC 调用过程中传递,进而控制框架行为。如想了解更多,请参照 Dubbo 源码解析系列文档或 [Blog](/zh-cn/blog/2019/10/17/dubbo-中的-url-统一模型/#rpc调用)。 - -> 各组件支持的具体配置项及含义请参考 [配置项手册](../properties) - -### service 与 reference -`service` 与 `reference` 是 Dubbo 最基础的两个配置项,它们用来将某个指定的接口或实现类注册为 Dubbo 服务,并通过配置项控制服务的行为。 -* `service` 用于服务提供者端,通过 `service` 配置的接口和实现类将被定义为标准的 Dubbo 服务,从而实现对外提供 RPC 请求服务。 -* `reference` 用于服务消费者端,通过 `reference` 配置的接口将被定义为标准的 Dubbo 服务,生成的 proxy 可发起对远端的 RPC 请求。 - -> 一个应用中可以配置任意多个 `service` 与 `reference`。 - -### consumer 与 provider -* 当应用内有多个 `reference` 配置时,`consumer` 指定了这些 `reference` 共享的默认值,如共享的超时时间等以简化繁琐的配置,如某个 `reference` 中单独设置了配置项值则该 `reference` 中的配置优先级更高。 -* 当应用内有多个 `service` 配置时,`provider` 指定了这些 `service` 共享的默认值,如某个 `service` 中单独设置了配置项值则该 `service` 中的配置优先级更高。 - -> consumer 组件还可以对 reference 进行虚拟分组,不通分组下的 reference 可有不同的 consumer 默认值设定;如在 XML 格式配置中, 标签可通过嵌套在 标签之中实现分组。provider 与 service 之间也可以实现相同的效果。 - -## 配置方式 - -### 属性配置 -根据属性Key-value生成配置组件,类似SpringBoot的ConfigurationProperties,具体请参考[属性配置](../properties)。 - -属性配置的另外一个重要的功能特性是[属性覆盖](../principle/#32-属性覆盖),使用外部属性的值覆盖已创建的配置组件属性。 - -如果要将属性配置放到外部的配置中心,请参考[外部化配置](../principle/#33-外部化配置)。 - -除了外围驱动方式上的差异,Dubbo 的配置读取总体上遵循了以下几个原则: - -1. Dubbo 支持了多层级的配置,并按预定优先级自动实现配置间的覆盖,最终所有配置汇总到数据总线URL后驱动后续的服务暴露、引用等流程。 -2. 配置格式以 Properties 为主,在配置内容上遵循约定的 `path-based` 的[命名规范](../principle/#1-配置格式) - -### API 配置 -> 以Java编码的方式组织配置,包括Raw API和Bootstrap API,具体请参考[API配置](../api)。 - -```java -public static void main(String[] args) throws IOException { - ServiceConfig service = new ServiceConfig<>(); - service.setApplication(new ApplicationConfig("first-dubbo-provider")); - service.setRegistry(new RegistryConfig("multicast://224.5.6.7:1234")); - service.setInterface(GreetingsService.class); - service.setRef(new GreetingsServiceImpl()); - service.export(); - System.out.println("first-dubbo-provider is running."); - System.in.read(); -} -``` - -### XML 配置 -> 以XML方式配置各种组件,支持与Spring无缝集成,具体请参考[XML配置](../xml)。 - -```xml - - - - - - - - - - - -``` - -### Annotation 配置 -> 以注解方式暴露服务和引用服务接口,支持与Spring无缝集成,具体请参考[Annotation配置](../annotation)。 - -```java - // AnnotationService服务实现 - - @DubboService - public class AnnotationServiceImpl implements AnnotationService { - @Override - public String sayHello(String name) { - System.out.println("async provider received: " + name); - return "annotation: hello, " + name; - } - } -``` - -```properties -## dubbo.properties - -dubbo.application.name=annotation-provider -dubbo.registry.address=zookeeper://127.0.0.1:2181 -dubbo.protocol.name=dubbo -dubbo.protocol.port=20880 -``` - -### Spring Boot 配置 -> 使用 Spring Boot 减少非必要配置,结合 Annotation 与 application.properties/application.yml 开发 Dubbo 应用,具体请参考[Annotation 配置](../annotation)。 - -```properties -## application.properties - -# Spring boot application -spring.application.name=dubbo-externalized-configuration-provider-sample - -# Base packages to scan Dubbo Component: @com.alibaba.dubbo.config.annotation.Service -dubbo.scan.base-packages=com.alibaba.boot.dubbo.demo.provider.service - -# Dubbo Application -## The default value of dubbo.application.name is ${spring.application.name} -## dubbo.application.name=${spring.application.name} - -# Dubbo Protocol -dubbo.protocol.name=dubbo -dubbo.protocol.port=12345 - -## Dubbo Registry -dubbo.registry.address=N/A - -## DemoService version -demo.service.version=1.0.0 -``` - -## 配置规范与来源 - -Dubbo 遵循一种 [path-based 的配置规范](../principle/),每一个配置组件都可以通过这种方式进行表达。而在配置的来源上,总共支持 6 种配置来源,即 Dubbo 会分别尝试从以下几个位置尝试加载配置数据: - -- JVM System Properties,JVM -D 参数 -- System environment,JVM进程的环境变量 -- Externalized Configuration,[外部化配置](../principle/#33-外部化配置),从配置中心读取 -- Application Configuration,应用的属性配置,从Spring应用的Environment中提取"dubbo"打头的属性集 -- API / XML /注解等编程接口采集的配置可以被理解成配置来源的一种,是直接面向用户编程的配置采集方式 -- 从classpath读取配置文件 dubbo.properties \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/config/principle.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/config/principle.md index 84713c20f170..cb1c396c7777 100644 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/config/principle.md +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/config/principle.md @@ -3,12 +3,208 @@ aliases: - /zh/docs3-v2/java-sdk/reference-manual/config/principle/ - /zh-cn/docs3-v2/java-sdk/reference-manual/config/principle/ description: Dubbo 配置方式和工作原理的深度解读,包括配置格式、设计思路、来源、加载流程等。 -linkTitle: 配置工作原理 +linkTitle: 配置加载流程 title: 配置工作原理 type: docs weight: 5 --- +本文主要讲解 Dubbo 配置相关的 API 与工作原理,学习 Dubbo 的多种配置源、每种配置源的具体配置方式、不同配置源之间的优先级与覆盖关系。 + +## 实现原理 + +为了更好地管理各种配置,Dubbo 抽象了一套结构化的配置组件,各组件总体以用途划分,分别控制不同作用域的行为。 + +![dubbo-config](/imgs/user/dubbo-config.jpg) + + +组件名称 | 描述 | 范围 | 是否必须配置 +------ | ------ | ------ | ------ +application | 指定应用名等应用级别相关信息 | 一个应用内只允许出现一个 | 必选 +service | 声明普通接口或实现类为 Dubbo 服务 | 一个应用内可以有 0 到多个 service | service/reference 至少一种 +reference | 声明普通接口为 Dubbo 服务 | 一个应用内可以有 0 到多个 reference | service/reference 至少一种 +protocol | 要暴露的 RPC 协议及相关配置如端口号等 | 一个应用可配置多个,一个 protocol 可作用于一组 service&reference | 可选,默认 dubbo +registry | 注册中心类型、地址及相关配置 | 一个应用内可配置多个,一个 registry 可作用于一组 service&reference| 必选 +config-center | 配置中心类型、地址及相关配置 | 一个应用内可配置多个,所有服务共享 | 可选 +metadata-report | 元数据中心类型、地址及相关配置 | 一个应用内可配置多个,所有服务共享 | 可选 +consumer | reference 间共享的默认配置 | 一个应用内可配置多个,一个 consumer 可作用于一组 reference | 可选 +provider | service 间共享的默认配置 | 一个应用内可配置多个,一个 provider 可作用于一组 service | 可选 +monitor | 监控系统类型及地址 | 一个应用内只允许配置一个 | 可选 +metrics | 数据采集模块相关配置 | 一个应用内只允许配置一个 | 可选 +ssl | ssl/tls 安全链接相关的证书等配置 | 一个应用内只允许配置一个 | 可选 +method | 指定方法级的配置 | service 和 reference 的子配置 | 可选 +argument | 某个方法的参数配置 | method的子配置 | 可选 + + +> 从实现原理层面,最终 Dubbo 所有的配置项都会被组装到 URL 中,以 URL 为载体在后续的启动、RPC 调用过程中传递,进而控制框架行为。如想了解更多,请参照 Dubbo 源码解析系列文档或 [Blog](/zh-cn/blog/2019/10/17/dubbo-中的-url-统一模型/#rpc调用)。 + +> 各组件支持的具体配置项及含义请参考 [配置项手册](../properties) + + +{{% alert title="注意" color="info" %}} +**背景** + +在每个dubbo应用中某些种类的配置类实例只能出现一次(比如`ApplicationConfig`、`MonitorConfig`、`MetricsConfig`、`SslConfig`、`ModuleConfig`),有些能出现多次(比如`RegistryConfig`、`ProtocolConfig`等)。 + +如果应用程序意外的扫描到了多个唯一配置类实例(比如用户在一个dubbo应用中错误了配置了两个`ApplicationConfig`),应该以哪种策略来处理这种情况呢?是直接抛异常?是保留前者忽略后者?是忽略前者保留后者?还是允许某一种形式的并存(比如后者的属性覆盖到前者上)? + +目前dubbo中的唯一配置类类型和以及某唯一配置类型找到多个实例允许的配置模式/策略如下。 + +**唯一配置类类型** + +`ApplicationConfig`、`MonitorConfig`、`MetricsConfig`、`SslConfig`、`ModuleConfig`。 + +前四个属于应用级别的,最后一个属于模块级别的。 + +**配置模式** + +- `strict`:严格模式。直接抛异常。 +- `override`:覆盖模式。忽略前者保留后者。 +- `ignore`:忽略模式。忽略后者保留前者。 +- `override_all`:属性覆盖模式。不管前者的属性值是否为空,都将后者的属性覆盖/设置到前者上。 +- `override_if_absent`:若不存在则属性覆盖模式。只有前者对应属性值为空,才将后者的属性覆盖/设置到前者上。 + +注:后两种还影响配置实例的属性覆盖。因为dubbo有多种配置方式,即存在多个配置源,配置源也有优先级。比如通过xml方式配置了一个`ServiceConfig`且指定属性`version=1.0.0`,同时我们又在外部配置(配置中心)中配置了`dubbo.service.{interface}.version=2.0.0`,在没有引入`config-mode`配置项之前,按照原有的配置源优先级,最终实例的`version=2.0.0`。但是引入了`config-mode`配置项之后,配置优先级规则也不再那么严格,即如果指定`config-mode为override_all`则为`version=2.0.0`,如果`config-mode为override_if_absent`则为`version=1.0.0`,`config-mode`为其他值则遵循原有配置优先级进行属性设值/覆盖。 + +**配置方式** + +配置的key为`dubbo.config.mode`,配置的值为如上描述的几种,默认的策略值为`strict`。下面展示了配置示例 + +```properties +# JVM -D +-Ddubbo.config.mode=strict + +# 环境变量 +DUBBO_CONFIG_MODE=strict + +# 外部配置(配置中心)、Spring应用的Environment、dubbo.properties +dubbo.config.mode=strict +``` +{{% /alert %}} + +### service 与 reference +`service` 与 `reference` 是 Dubbo 最基础的两个配置项,它们用来将某个指定的接口或实现类注册为 Dubbo 服务,并通过配置项控制服务的行为。 +* `service` 用于服务提供者端,通过 `service` 配置的接口和实现类将被定义为标准的 Dubbo 服务,从而实现对外提供 RPC 请求服务。 +* `reference` 用于服务消费者端,通过 `reference` 配置的接口将被定义为标准的 Dubbo 服务,生成的 proxy 可发起对远端的 RPC 请求。 + +> 一个应用中可以配置任意多个 `service` 与 `reference`。 + +### consumer 与 provider +* 当应用内有多个 `reference` 配置时,`consumer` 指定了这些 `reference` 共享的默认值,如共享的超时时间等以简化繁琐的配置,如某个 `reference` 中单独设置了配置项值则该 `reference` 中的配置优先级更高。 +* 当应用内有多个 `service` 配置时,`provider` 指定了这些 `service` 共享的默认值,如某个 `service` 中单独设置了配置项值则该 `service` 中的配置优先级更高。 + +> consumer 组件还可以对 reference 进行虚拟分组,不通分组下的 reference 可有不同的 consumer 默认值设定;如在 XML 格式配置中, 标签可通过嵌套在 标签之中实现分组。provider 与 service 之间也可以实现相同的效果。 + +## 配置方式 + +### 属性配置 +根据属性Key-value生成配置组件,类似SpringBoot的ConfigurationProperties,具体请参考[属性配置](../properties)。 + +属性配置的另外一个重要的功能特性是[属性覆盖](../principle/#32-属性覆盖),使用外部属性的值覆盖已创建的配置组件属性。 + +如果要将属性配置放到外部的配置中心,请参考[外部化配置](../principle/#33-外部化配置)。 + +除了外围驱动方式上的差异,Dubbo 的配置读取总体上遵循了以下几个原则: + +1. Dubbo 支持了多层级的配置,并按预定优先级自动实现配置间的覆盖,最终所有配置汇总到数据总线URL后驱动后续的服务暴露、引用等流程。 +2. 配置格式以 Properties 为主,在配置内容上遵循约定的 `path-based` 的[命名规范](../principle/#1-配置格式) + +### API 配置 +> 以Java编码的方式组织配置,包括Raw API和Bootstrap API,具体请参考[API配置](../api)。 + +```java +public static void main(String[] args) throws IOException { + ServiceConfig service = new ServiceConfig<>(); + service.setApplication(new ApplicationConfig("first-dubbo-provider")); + service.setRegistry(new RegistryConfig("multicast://224.5.6.7:1234")); + service.setInterface(GreetingsService.class); + service.setRef(new GreetingsServiceImpl()); + service.export(); + System.out.println("first-dubbo-provider is running."); + System.in.read(); +} +``` + +### XML 配置 +> 以XML方式配置各种组件,支持与Spring无缝集成,具体请参考[XML配置](../xml)。 + +```xml + + + + + + + + + + + +``` + +### Annotation 配置 +> 以注解方式暴露服务和引用服务接口,支持与Spring无缝集成,具体请参考[Annotation配置](../annotation)。 + +```java + // AnnotationService服务实现 + + @DubboService + public class AnnotationServiceImpl implements AnnotationService { + @Override + public String sayHello(String name) { + System.out.println("async provider received: " + name); + return "annotation: hello, " + name; + } + } +``` + +```properties +## dubbo.properties + +dubbo.application.name=annotation-provider +dubbo.registry.address=zookeeper://127.0.0.1:2181 +dubbo.protocol.name=dubbo +dubbo.protocol.port=20880 +``` + +### Spring Boot 配置 +> 使用 Spring Boot 减少非必要配置,结合 Annotation 与 application.properties/application.yml 开发 Dubbo 应用,具体请参考[Annotation 配置](../annotation)。 + +```properties +## application.properties + +# Spring boot application +spring.application.name=dubbo-externalized-configuration-provider-sample + +# Base packages to scan Dubbo Component: @com.alibaba.dubbo.config.annotation.Service +dubbo.scan.base-packages=com.alibaba.boot.dubbo.demo.provider.service + +# Dubbo Application +## The default value of dubbo.application.name is ${spring.application.name} +## dubbo.application.name=${spring.application.name} + +# Dubbo Protocol +dubbo.protocol.name=dubbo +dubbo.protocol.port=12345 + +## Dubbo Registry +dubbo.registry.address=N/A + +## DemoService version +demo.service.version=1.0.0 +``` + +## 配置规范与来源 + +Dubbo 遵循一种 [path-based 的配置规范](../principle/),每一个配置组件都可以通过这种方式进行表达。而在配置的来源上,总共支持 6 种配置来源,即 Dubbo 会分别尝试从以下几个位置尝试加载配置数据: + +- JVM System Properties,JVM -D 参数 +- System environment,JVM进程的环境变量 +- Externalized Configuration,[外部化配置](../principle/#33-外部化配置),从配置中心读取 +- Application Configuration,应用的属性配置,从Spring应用的Environment中提取"dubbo"打头的属性集 +- API / XML /注解等编程接口采集的配置可以被理解成配置来源的一种,是直接面向用户编程的配置采集方式 +- 从classpath读取配置文件 dubbo.properties + diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/config/properties.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/config/properties.md index 576d02caf9cc..0dbbdf5f9c8d 100644 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/config/properties.md +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/config/properties.md @@ -2,6 +2,15 @@ aliases: - /zh/docs3-v2/java-sdk/reference-manual/config/properties/ - /zh-cn/docs3-v2/java-sdk/reference-manual/config/properties/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/dump/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/lazy-connect/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/simplify-registry-data/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/stickiness/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/delay-publish/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/preflight-check/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/registry-only/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/service-downgrade/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/subscribe-only/ description: 包含 Dubbo 支持的所有配置组件及每个配置组件支持的所有配置项 linkTitle: 配置项手册 title: 配置项参考手册 @@ -10,493 +19,709 @@ weight: 6 --- +## JVM(-D) 参数 + + +| JVM 参数 | 示例值 | 说明 | +| --- | --- | --- | +| dubbo.{config-name}.{property} | -Ddubbo.application.name="dubbo-demo"

-Ddubbo.registry.address="nacos://host:port"

-Ddubbo.protocol.port="20880"

...... | Dubbo支持 [所有的配置项](aaa) 以JVM参数格式指定。其中`config` 是指如 application、registry、protocol 等配置项,而`property`则是指每个配置项中的具体属性。 | +| dubbo.resolve.file | -Ddubbo.resolve.file=/home/ken/.../dubbo-resolve.properties | 在文件中指定每个接口的直连地址url,如:org.apache.dubbo.demo.DemoService=tri://127.0.0.1:50051/org.apache.dubbo.demo.DemoService?xxx=xxx | +| org.graalvm.nativeimage.imagecode || [https://github.com/oracle/graal/blob/master/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/ImageInfo.java](https://github.com/oracle/graal/blob/master/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/ImageInfo.java) | +| dubbo.properties.file | -Ddubbo.properties.file=foo.properties | 指定 properties 配置文件地址,可以是绝对路径或者classpath相对路径。默认值为 dubbo.properties | +| dubbo.jstack-dump.max-line | -Ddubbo.jstack-dump.max-line=20 | Dubbo 支持自动打印调用堆栈,这个参数可以控制堆栈行数,如示例中只会打印前20行堆栈 | +| dubbo.json-framework.prefer| -Ddubbo.json-framework.prefer=gson | 设置框架中 json 序列化的具体实现,目前可选实现有 `fastjson2`、`fastjson`、`gson`、`jackson`。默认情况,框架会自动查找可用实现,以上按顺序优先级依次降低 | +| dubbo.network.interface.ignored | -Ddubbo.network.interface.ignored=eth1,eth2 | 在多网卡环境下,当需要手动控制注册到注册中心的网卡地址时使用。用于排除某些网卡 | +| dubbo.network.interface.preferred | -Ddubbo.network.interface.ignored=eth0 | 在多网卡环境下,当需要手动控制注册到注册中心的网卡地址时使用。用于指定一个特定网卡 | +| sun.rmi.transport.tcp.responseTimeout | -Dsun.rmi.transport.tcp.responseTimeout=5000 | 用于设置 RMI 协议下的超时时间,单位ms | +| env | | Apollo 配置中心特有参数 | +| app.id | | Apollo 配置中心特有参数 | +| apollo.cluster | | Apollo 配置中心特有参数 | +| apollo.meta | | Apollo 配置中心特有参数 | +| dubbo.mapping.cache.filePath | -Ddubbo.mapping.cache.filePath=~/.dubbo/mapping/ | 用于设置`接口-应用`映射关系缓存文件,通常用于服务发现。文件绝对路径地址 | +| dubbo.mapping.cache.fileName | -Ddubbo.mapping.cache.fileName=dubbo-mapping | 用于设置`接口-应用`映射关系缓存文件,通常用于服务发现。文件名,如此示例最终会读取和存储在文件 dubbo-mapping.dubbo.cache | +| dubbo.mapping.cache.entrySize | -Ddubbo.mapping.cache.maxFileSize=300 | 用于设置`接口-应用`映射关系缓存文件,通常用于服务发现。文件名中内容最大条目数限制 | +| dubbo.mapping.cache.maxFileSize | -Ddubbo.mapping.cache.maxFileSize=104857600 | 用于设置`接口-应用`映射关系缓存文件,通常用于服务发现。文件最大占用空间限制,单位byte | +| dubbo.meta.cache.filePath | -Ddubbo.meta.cache.filePath=~/.dubbo/meta/ | 用于设置`metadata元数据`缓存文件,通常用于服务发现。文件绝对路径地址 | +| dubbo.meta.cache.fileName | -Ddubbo.meta.cache.fileName=dubbo-meta | 用于设置`metadata元数据`缓存文件,通常用于服务发现。文件名,如此示例最终会读取和存储在文件 dubbo-meta.dubbo.cache | +| dubbo.meta.cache.entrySize | -Ddubbo.meta.cache.maxFileSize=300 | 用于设置`metadata元数据`缓存文件,通常用于服务发现。文件名中内容最大条目数限制 | +| dubbo.meta.cache.maxFileSize | -Ddubbo.meta.cache.maxFileSize=104857600 | 用于设置`metadata元数据`缓存文件,通常用于服务发现。文件最大占用空间限制,单位byte | +| dubbo.application.use-secure-random-request-id | -Ddubbo.application.use-secure-random-request-id=true | 设置每次 rpc 调用 request id 的生成规则,是不是用随机值。如不设置则使用递增值。 | +| dubbo.protocol.default-close-timeout | -Ddubbo.protocol.default-close-timeout=10000 | 设置 tcp server 关闭等待时间,单位毫秒ms | +| dubbo.protocol.default-heartbeat | -Ddubbo.protocol.default-heartbeat=10000 | 设置发起心跳 heartbeat 的间隔,单位毫秒ms | +| dubbo.hessian.allowNonSerializable | | 是否允许对没有实现 Serializable 接口的类进行序列化,对hessian序列化有效 | +| dubbo.application.hessian2.whitelist | -Ddubbo.application.hessian2.whitelist=true | 设置是否启用白名单机制,对hessian序列化有效。如果设置 true,则继续配置下面的 allow 规则;否则,配置 deny 规则 | +| dubbo.application.hessian2.allow | -Ddubbo.application.hessian2.allow=org.apache.dubbo.*;com.company.* | 如果设置 true,则继续配置配置 allow 规则,参见文档说明 | +| dubbo.application.hessian2.deny | -Ddubbo.application.hessian2.deny=org.apache.dubbo.*;io.commons.* | 如果设置 false,则继续配置配置 deny 规则,参见文档说明 | +| dubbo.application.manual-register | -Ddubbo.application.manual-register=true | 设置之后,所有服务都不会被自动注册到注册中心,直到用户调用 online 等命令手动完成注册 | +| dubbo.compact.enable | | | +| dubbo.migration-file.enable | -Ddubbo.migration-file.enable=true | 在往应用级地址发现迁移时,是否启用规则文件读取 | +| dubbo.migration.file | -Ddubbo.migration.file=dubbo-migration.yaml | 指定往应用级地址发现迁移的规则文件路径,可以是绝对路径或者classpath相对路径。默认值为 dubbo-migration.yaml | +| dubbo.application.logger | -Ddubbo.application.logger=slf4j | 设置dubbo框架使用的日志组件,设置后,dubbo框架自身的日志将打印到这里(不影响应用自身);目前支持的 slf4j、log4j、log4j2 等,设置之后须确保相应的组件依赖已经加入应用。 | +| dubbo.properties.file | -Ddubbo.properties.file=foo.properties | 指定 properties 配置文件地址,可以是绝对路径或者classpath相对路径。默认值为 dubbo.properties | + + +## 环境变量 + +| 环境变量 | 示例值 | 说明 | +| --- | --- | --- | +| DUBBO_{CONFIG-NAME}.{PROPERTY} | DUBBO_APPLICATION_NAME="dubbo-demo"

DUBBO_REGISTRY_ADDRESS="nacos://host:port"

DUBBO_PROTOCOL_PORT="20880"

...... | Dubbo支持[所有的配置项](aaa)以环境变量格式指定。其中`CONFIG-NAME` 是指如 application、registry、protocol 等配置项,而 `PROPERTY`则是指每个配置项中的具体属性。 | +| DUBBO_DEFAULT_SERIALIZATION | DUBBO_DEFAULT_SERIALIZATION="hessan2" | 设置框架的默认序列化方式,如hessian2、fastjson2、msgpack等 | +| DUBBO2_COMPACT_ENABLE | DUBBO2_COMPAT_ENABLE="true" | | +| DUBBO_ENV_KEYS| DUBBO_LABELS="tag1=value1; tag2=value2" | `tag1=value1`会作为附加参数上报到地址 URL,作为系统环境变量可用于为实例打标等。 | +| DUBBO_LABELS | DUBBO_ENV_KEYS="DUBBO_TAG1, DUBBO_TAG2" | Dubbo 会读取 `DUBBO_TAG1`、`DUBBO_TAG2`两个环境变量,并将读取的值 value `DUBBO_TAG1=value` 作为附加参数上报到地址 URL。 | +| POD_NAMESPACE | | 用于 Kubernetes Service 场景,指定命名空间 | +| CLUSTER_DOMAIN | | 用于 Kubernetes Service 场景,指定集群名称,默认 default | +| DUBBO_IP_TO_REGISTRY | DUBBO_IP_TO_REGISTRY=30.123.45.187 | 指定注册到注册中心 URL 中的 ip 地址 | +| DUBBO_PORT_TO_REGISTRY | DUBBO_PORT_TO_REGISTRY=20880 | 指定注册到注册中心 URL 中的 port 端口号 | +| DUBBO_{PROTOCOL}_PORT_TO_REGISTRY | DUBBO_DUBBO_IP_TO_REGISTRY=30.123.45.187

DUBBO_TRI_IP_TO_REGISTRY=30.123.45.187 | 指定注册到注册中心 URL 中的 ip 地址,可以为不同协议指定不同 ip | +| DUBBO_{PROTOCOL}_PORT_TO_REGISTRY | DUBBO_DUBBO_PORT_TO_REGISTRY=20880

DUBBO_TRI_PORT_TO_REGISTRY=50051 | 指定注册到注册中心 URL 中的 port 端口,可以为不同协议指定不同 port | +| DUBBO_IP_TO_BIND | DUBBO_IP_TO_BIND=30.123.45.187 | 指定 tcp 监听绑定的 ip 地址 | +| DUBBO_PORT_TO_BIND | DUBBO_PORT_TO_BIND=20880 | 指定 tcp 监听绑定的 port 端口 | +| DUBBO_{PROTOCOL}_IP_TO_BIND | DUBBO_DUBBO_IP_TO_BIND=30.123.45.187

DUBBO_TRI_IP_TO_BIND=30.123.45.187 | 指定 tcp 监听绑定的 ip 地址,可以为不同协议指定不同 ip | +| DUBBO_{PROTOCOL}_PORT_TO_BIND | DUBBO_DUBBO_PORT_TO_BIND=20880

DUBBO_TRI_PORT_TO_BIND=50051 | 指定 tcp 监听绑定的 port 端口,可以为不同协议指定不同 port | +| dubbo.properties.file | dubbo.properties.file=foo.properties | 指定 properties 配置文件地址,可以是绝对路径或者classpath相对路径。默认值为 dubbo.properties | +| dubbo.migration.file | dubbo.migration.file=dubbo-migration.yaml | 指定应用级地址发现的迁移规则的文件地址,可以是绝对路径或者classpath相对路径。默认值为 dubbo-migration.yaml | + + +## 配置项手册 +不论您是使用 Spring Boot、XML、注解还是 API 编写 Dubbo 应用,都可以通过以下表格参考每一项的具体含义。 + +### dubbo.tracing.baggage.correlation +**Class:** `org.apache.dubbo.config.nested.BaggageConfig$Correlation` + +|Key|Type|Description|Default value|Deprecation| +|---|----|-----------|-------------|-----------| +| enabled| java.lang.Boolean| Whether to enable correlation of the baggage context with logging contexts.| true| | +| fields| java.util.List<java.lang.String>| List of fields that should be correlated with the logging context. That means that these fields would end up as key-value pairs in e.g. MDC.| | | +### dubbo.tracing.tracing-exporter.otlp-config +**Class:** `org.apache.dubbo.config.nested.ExporterConfig$OtlpConfig` + +|Key|Type|Description|Default value|Deprecation| +|---|----|-----------|-------------|-----------| +| compression-method| java.lang.String| The method used to compress payloads. If unset, compression is disabled. Currently supported compression methods include "gzip" and "none".| none| | +| endpoint| java.lang.String| URL to the Otlp API.| | | +| headers| java.util.Map<java.lang.String,java.lang.String>| | | | +| timeout| java.time.Duration| The maximum time to wait for the collector to process an exported batch of spans. (seconds)| 10| | +### dubbo.tracing.tracing-exporter.zipkin-config +**Class:** `org.apache.dubbo.config.nested.ExporterConfig$ZipkinConfig` + +|Key|Type|Description|Default value|Deprecation| +|---|----|-----------|-------------|-----------| +| connect-timeout| java.time.Duration| Connection timeout for requests to Zipkin. (seconds)| 1| | +| endpoint| java.lang.String| URL to the Zipkin API.| | | +| read-timeout| java.time.Duration| Read timeout for requests to Zipkin. (seconds)| 10| | +### dubbo.metrics.prometheus.exporter +**Class:** `org.apache.dubbo.config.nested.PrometheusConfig$Exporter` + +|Key|Type|Description|Default value|Deprecation| +|---|----|-----------|-------------|-----------| +| enable-http-service-discovery| java.lang.Boolean| Enable http service discovery for prometheus| | | +| enabled| java.lang.Boolean| Enable prometheus exporter| | | +| http-service-discovery-url| java.lang.String| Http service discovery url| | | +### dubbo.metrics.prometheus.pushgateway +**Class:** `org.apache.dubbo.config.nested.PrometheusConfig$Pushgateway` + +|Key|Type|Description|Default value|Deprecation| +|---|----|-----------|-------------|-----------| +| base-url| java.lang.String| Base URL for the Pushgateway| | | +| enabled| java.lang.Boolean| Enable publishing via a Prometheus Pushgateway| | | +| job| java.lang.String| Job identifier for this application instance| | | +| password| java.lang.String| Login password of the Prometheus Pushgateway| | | +| push-interval| java.lang.Integer| Frequency with which to push metrics| | | +| username| java.lang.String| Login user of the Prometheus Pushgateway| | | +### Unknown group +**Class:** `Unknown` + +|Key|Type|Description|Default value|Deprecation| +|---|----|-----------|-------------|-----------| +| dubbo.config-center.include-spring-env| java.lang.Boolean| Whether to include Spring Environment.| | | +| dubbo.config.mode| org.apache.dubbo.config.context.ConfigMode| Config processing mode. See <code>org.apache.dubbo.config.context.ConfigMode</code>.| | | +| dubbo.config.multiple| java.lang.Boolean| Whether to enable multiple configurations in Dubbo, allowing multiple configurations to be loaded and used, default value is <code>true</code>.| | | +| dubbo.config.override| java.lang.Boolean| Whether to allow configuration override in Dubbo, default value is <code>true</code>.| | | +| dubbo.enabled| java.util.Set<java.lang.String>| Whether enable autoconfiguration of dubbo, default value is <code>true</code>.| | | +| dubbo.env.keys| java.lang.String| The keys for specify environment-specific keys, allowing for differentiation and utilization of various runtime environments (e.g., development, testing, production), the multiple-value is delimited by comma.| | | +| dubbo.labels| java.lang.String| The labels for these service providers, enabling categorization and grouping, thereby enhancing their management and monitoring, the multiple-value is delimited by ';'.| | | +| dubbo.scan.base-packages| java.util.Set<java.lang.String>| The basePackages to scan, the multiple-value is delimited by comma @see EnableDubbo#scanBasePackages().| | | +### dubbo.tracing.baggage +**Class:** `org.apache.dubbo.config.nested.BaggageConfig` + +|Key|Type|Description|Default value|Deprecation| +|---|----|-----------|-------------|-----------| +| enabled| java.lang.Boolean| Whether baggage is enabled or not.| true| | +| remote-fields| java.util.List<java.lang.String>| List of fields that are referenced the same in-process as it is on the wire. For example, the field "x-vcap-request-id" would be set as-is including the prefix.| | | +### dubbo.tracing.propagation +**Class:** `org.apache.dubbo.config.nested.PropagationConfig` + +|Key|Type|Description|Default value|Deprecation| +|---|----|-----------|-------------|-----------| +| type| java.lang.String| Tracing context propagation type.| W3C| | +### dubbo.tracing.sampling +**Class:** `org.apache.dubbo.config.nested.SamplingConfig` + +|Key|Type|Description|Default value|Deprecation| +|---|----|-----------|-------------|-----------| +| probability| java.lang.Float| Probability in the range from 0.0 to 1.0 that a trace will be sampled.| 0.1| | +### dubbo.tracing.tracing-exporter +**Class:** `org.apache.dubbo.config.nested.ExporterConfig` + +|Key|Type|Description|Default value|Deprecation| +|---|----|-----------|-------------|-----------| +### dubbo.rpc.tri +**Class:** `org.apache.dubbo.config.TripleConfig` + +|Key|Type|Description|Default value|Deprecation| +|---|----|-----------|-------------|-----------| +| enable-push| java.lang.Boolean| Whether to enable push, default is false.| | | +| header-table-size| java.lang.String| The header table size.| | | +| initial-window-size| java.lang.String| Initial window size.| | | +| max-concurrent-streams| java.lang.String| Maximum concurrent streams.| | | +| max-frame-size| java.lang.String| Maximum frame size.| | | +| max-header-list-size| java.lang.String| Maximum header list size.| | | +### dubbo +**Class:** `org.apache.dubbo.spring.boot.autoconfigure.DubboConfigurationProperties` + +|Key|Type|Description|Default value|Deprecation| +|---|----|-----------|-------------|-----------| +| config-centers| java.util.Map<java.lang.String,org.apache.dubbo.config.ConfigCenterConfig>| Multiple configurations for ConfigCenterBean.| | | +| consumers| java.util.Map<java.lang.String,org.apache.dubbo.config.ConsumerConfig>| Multiple configurations for Consumer.| | | +| metadata-reports| java.util.Map<java.lang.String,org.apache.dubbo.config.MetadataReportConfig>| Multiple configurations for MetadataReportConfig.| | | +| metricses| java.util.Map<java.lang.String,org.apache.dubbo.config.MetricsConfig>| Multiple configurations for MetricsConfig.| | | +| modules| java.util.Map<java.lang.String,org.apache.dubbo.config.ModuleConfig>| Multiple configurations for Module.| | | +| monitors| java.util.Map<java.lang.String,org.apache.dubbo.config.MonitorConfig>| Multiple configurations for Monitor.| | | +| protocols| java.util.Map<java.lang.String,org.apache.dubbo.config.ProtocolConfig>| Multiple configurations for Protocol.| | | +| providers| java.util.Map<java.lang.String,org.apache.dubbo.config.ProviderConfig>| Multiple configurations for Provider.| | | +| registries| java.util.Map<java.lang.String,org.apache.dubbo.config.RegistryConfig>| Multiple configurations for Registry.| | | +| tracings| java.util.Map<java.lang.String,org.apache.dubbo.config.TracingConfig>| Multiple configurations for TracingConfig.| | | +### dubbo.application +**Class:** `org.apache.dubbo.config.ApplicationConfig` + +|Key|Type|Description|Default value|Deprecation| +|---|----|-----------|-------------|-----------| +| architecture| java.lang.String| Architecture layer.| | | +| auto-trust-serialize-class| java.lang.Boolean| Whether to automatically trust serialized classes.| | | +| check-serializable| java.lang.Boolean| Whether to check serializable.| | | +| compiler| java.lang.String| Java compiler.| | | +| default| java.lang.Boolean| | | | +| dump-directory| java.lang.String| Directory for saving thread dump.| | | +| dump-enable| java.lang.Boolean| Whether to enable saving thread dump or not.| | | +| enable-empty-protection| java.lang.Boolean| Whether to enable protection against empty objects.| | | +| enable-file-cache| java.lang.Boolean| Whether to enable file caching.| | | +| environment| java.lang.String| Environment, e.g., dev, test, or production.| | | +| executor-management-mode| java.lang.String| Thread pool management mode: 'default' or 'isolation'.| | | +| id| java.lang.String| Identifier for this configuration.| | | +| liveness-probe| java.lang.String| Used to set extensions of the probe in QoS.| | | +| logger| java.lang.String| The type of log access.| | | +| mapping-retry-interval| java.lang.Integer| The retry interval of service name mapping.| | | +| meta-data| java.util.Map<java.lang.String,java.lang.String>| | | | +| metadata-service-port| java.lang.Integer| Metadata Service, used in Service Discovery.| | | +| metadata-service-protocol| java.lang.String| The protocol used for peer-to-peer metadata transmission.| | | +| metadata-type| java.lang.String| Metadata type, local or remote. If 'remote' is chosen, you need to specify a metadata center further.| | | +| monitor| org.apache.dubbo.config.MonitorConfig| Monitor center.| | | +| name| java.lang.String| The Application name.| | | +| need-refresh| java.lang.Boolean| Specifies if this configuration should be refreshed (true for refreshing).| true| | +| organization| java.lang.String| The application's organization (BU).| | | +| owner| java.lang.String| The application owner.| | | +| parameters| java.util.Map<java.lang.String,java.lang.String>| Customized parameters.| | | +| prefixes| java.util.List<java.lang.String>| | | | +| protocol| java.lang.String| The preferred protocol (name) of this application, convenient for places where it's hard to determine the preferred protocol.| | | +| qos-accept-foreign-ip| java.lang.Boolean| Should we accept foreign IP or not?| | | +| qos-accept-foreign-ip-compatible| java.lang.Boolean| | | | +| qos-accept-foreign-ip-whitelist| java.lang.String| When we disable accepting foreign IP, support specifying foreign IPs in the whitelist.| | | +| qos-accept-foreign-ip-whitelist-compatible| java.lang.String| | | | +| qos-anonymous-access-permission-level| java.lang.String| The anonymous (any foreign IP) access permission level, default is NONE, which means no access to any command.| | | +| qos-anonymous-access-permission-level-compatible| java.lang.String| | | | +| qos-anonymous-allow-commands| java.lang.String| The anonymous (any foreign IP) allowed commands, default is empty, which means no access to any command.| | | +| qos-check| java.lang.Boolean| Whether QoS should start successfully or not, will check qosEnable first.| | | +| qos-enable| java.lang.Boolean| Whether to enable Quality of Service (QoS) or not.| | | +| qos-enable-compatible| java.lang.Boolean| | | | +| qos-host| java.lang.String| The QoS host to listen.| | | +| qos-host-compatible| java.lang.String| | | | +| qos-port| java.lang.Integer| The QoS port to listen.| | | +| qos-port-compatible| java.lang.Integer| | | | +| readiness-probe| java.lang.String| The probe for checking the readiness of the application.| | | +| register-consumer| java.lang.Boolean| Used to control whether to register the instance with the registry or not. Set to 'false' only when the instance is a pure consumer.| | | +| register-mode| java.lang.String| Register mode.| | | +| registries| java.util.List<org.apache.dubbo.config.RegistryConfig>| Registry centers.| | | +| registry| org.apache.dubbo.config.RegistryConfig| | | | +| registry-ids| java.lang.String| The comma-separated list of registry IDs to which the service will be registered.| | | +| repository| java.lang.String| Repository.| | | +| scope-model| org.apache.dubbo.rpc.model.ScopeModel| The scope model of this config instance. <p> <b>NOTE:</b> the model maybe changed during config processing, the extension spi instance needs to be reinitialized after changing the model!| | | +| serialize-check-status| java.lang.String| The status of class serialization checking.| | | +| shutwait| java.lang.String| Config the shutdown wait.| | | +| startup-probe| java.lang.String| The probe for checking the startup of the application.| | | +| trust-serialize-class-level| java.lang.Integer| The trust level for serialized classes.| | | +| version| java.lang.String| The application version.| | | +### dubbo.config-center +**Class:** `org.apache.dubbo.config.ConfigCenterConfig` + +|Key|Type|Description|Default value|Deprecation| +|---|----|-----------|-------------|-----------| +| address| java.lang.String| The address (URL or hostname) of the config center server.| | | +| app-config-file| java.lang.String| The properties file under 'configFile' is global shared, while '.properties' under this one is limited only to this application.| | | +| app-external-configuration| java.util.Map<java.lang.String,java.lang.String>| Application-specific external configuration for the config center.| | | +| check| java.lang.Boolean| Behavior when the initial connection attempt to the config center fails. 'true' means interrupt the whole process once a failure occurs. Default value is true.| | | +| cluster| java.lang.String| The config center cluster, its actual meaning may vary depending on the specific config center product.| | | +| config-file| java.lang.String| Key mapping for properties files. Most of the time, you do not need to change this parameter. Default value is CommonConstants.DEFAULT_DUBBO_PROPERTIES.| | | +| default| java.lang.Boolean| | | | +| external-configuration| java.util.Map<java.lang.String,java.lang.String>| External configuration for the config center.| | | +| group| java.lang.String| The group of the config center, often used to identify an isolated space for a batch of config items. Its actual meaning depends on the specific config center you use. Default value is CommonConstants.DUBBO.| | | +| highest-priority| java.lang.Boolean| If the config center should have the highest priority and override all other configurations. Deprecated and no longer used. Default value is true.| | Reason: null, use for replacement: null| +| id| java.lang.String| Identifier for this configuration.| | | +| meta-data| java.util.Map<java.lang.String,java.lang.String>| | | | +| namespace| java.lang.String| The namespace of the config center, generally used for multi-tenancy. Its actual meaning depends on the specific config center you use. Default value is CommonConstants.DUBBO.| | | +| need-refresh| java.lang.Boolean| Specifies if this configuration should be refreshed (true for refreshing).| true| | +| parameters| java.util.Map<java.lang.String,java.lang.String>| Additional parameters specific to your config center product can be added here. For example, with XML: <dubbo:config-center> <dubbo:parameter key="{your key}" value="{your value}" /> </dubbo:config-center>| | | +| password| java.lang.String| Password for authentication with the config center.| | | +| port| java.lang.Integer| The port number for the config center server.| | | +| prefixes| java.util.List<java.lang.String>| | | | +| protocol| java.lang.String| The protocol used for accessing the config center.| | | +| scope-model| org.apache.dubbo.rpc.model.ScopeModel| The scope model of this config instance. <p> <b>NOTE:</b> the model maybe changed during config processing, the extension spi instance needs to be reinitialized after changing the model!| | | +| timeout| java.lang.Long| The timeout for accessing the config center. Default value is 30000L.| | | +| username| java.lang.String| Username for authentication with the config center.| | | +### dubbo.consumer +**Class:** `org.apache.dubbo.config.ConsumerConfig` + +|Key|Type|Description|Default value|Deprecation| +|---|----|-----------|-------------|-----------| +| actives| java.lang.Integer| Maximum concurrent invocations allowed.| | | +| application| org.apache.dubbo.config.ApplicationConfig| Application configuration for the service.| | Reason: null, use for replacement: null| +| async| java.lang.Boolean| Enable asynchronous invocation. Note that it is unreliable asynchronous, ignoring return values and not blocking threads.| | | +| auth| java.lang.Boolean| Enable service authentication.| | | +| cache| java.lang.String| Cache provider for caching return results. available options: lru, threadlocal, jcache etc.| | | +| callbacks| java.lang.Integer| Callback limits for the service.| | | +| check| java.lang.Boolean| Check if service provider exists, if not exists, it will be fast fail| | | +| client| java.lang.String| client type| | | +| cluster| java.lang.String| Cluster type for service.| | | +| config-center| org.apache.dubbo.config.ConfigCenterConfig| Configuration center settings.| | Reason: null, use for replacement: null| +| connections| java.lang.Integer| Connection limits: 0 for shared connection, otherwise specifying connections for the service.| | | +| corethreads| java.lang.Integer| Consumer threadpool core thread size| | | +| default| java.lang.Boolean| | | | +| exported-urls| java.util.List<org.apache.dubbo.common.URL>| | | | +| filter| java.lang.String| Filters for service exposure or reference (multiple filters can be separated by commas).| | | +| forks| java.lang.Integer| Forks for forking cluster.| | | +| generic| java.lang.String| Whether to use generic interface| | | +| group| java.lang.String| Group of the remote service referenced by the consumer/provider.| | | +| id| java.lang.String| Identifier for this configuration.| | | +| init| java.lang.Boolean| Whether to eagle-init| | | +| injvm| java.lang.Boolean| Whether to find reference's instance from the current JVM| | Reason: null, use for replacement: null| +| interface| java.lang.String| | | | +| layer| java.lang.String| Layer of service providers.| | | +| lazy| java.lang.Boolean| Lazy create connection| | | +| listener| java.lang.String| Listeners for service exposure or reference (multiple listeners can be separated by commas).| | | +| loadbalance| java.lang.String| Load balancing strategy for service invocation.| | | +| local| java.lang.String| Local implementation class name for the service interface.| | Reason: null, use for replacement: null| +| merger| java.lang.String| Merger for result data.| | | +| mesh-enable| java.lang.Boolean| enable mesh mode @since 3.1.0| | | +| meta-data| java.util.Map<java.lang.String,java.lang.String>| | | | +| metadata-report-config| org.apache.dubbo.config.MetadataReportConfig| Metadata report configuration.| | Reason: null, use for replacement: null| +| methods| java.util.List<org.apache.dubbo.config.MethodConfig>| Method-specific configuration.| | | +| mock| java.lang.String| Mock class name to be called when a service fails to execute. The mock doesn't support on the provider side, and it is executed when a non-business exception occurs after a remote service call.| | | +| module| org.apache.dubbo.config.ModuleConfig| Module configuration for the service.| | Reason: null, use for replacement: null| +| monitor| org.apache.dubbo.config.MonitorConfig| Service monitoring configuration.| | Reason: null, use for replacement: null| +| need-refresh| java.lang.Boolean| Specifies if this configuration should be refreshed (true for refreshing).| true| | +| onconnect| java.lang.String| Event handler for connection establishment.| | | +| ondisconnect| java.lang.String| Event handler for disconnection.| | | +| owner| java.lang.String| Owner of the service providers.| | | +| parameters| java.util.Map<java.lang.String,java.lang.String>| Customized parameters for configuration.| | | +| prefixes| java.util.List<java.lang.String>| | | | +| protocol| java.lang.String| Only the service provider of the specified protocol is invoked, and other protocols are ignored.| | | +| provided-by| java.lang.String| declares which app or service this interface belongs to| | | +| provider-namespace| java.lang.String| assign the namespace that provider belong to @since 3.1.1| | | +| provider-port| java.lang.Integer| By VirtualService and DestinationRule, envoy will generate a new route rule,such as 'demo.default.svc.cluster.local:80',the default port is 80. When you want to specify the provider port,you can use this config. @since 3.1.0| | | +| proxy| java.lang.String| Strategy for generating dynamic agents (options: "jdk" or "javassist").| | | +| queues| java.lang.Integer| Consumer threadpool queue size| | | +| reconnect| java.lang.String| | | | +| refer-async| java.lang.Boolean| Weather the reference is referred asynchronously @see ModuleConfig#referAsync @deprecated| | Reason: null, use for replacement: null| +| refer-background| java.lang.Boolean| Whether refer should run in background or not. @see ModuleConfig#setBackground(Boolean) @deprecated replace with {@link ModuleConfig#setBackground(Boolean)}| | Reason: null, use for replacement: null| +| refer-thread-num| java.lang.Integer| Thread num for asynchronous refer pool size| | | +| registries| java.util.List<org.apache.dubbo.config.RegistryConfig>| Registries where the service will be registered (use this or registryIds, not both).| | | +| registry| org.apache.dubbo.config.RegistryConfig| | | | +| registry-ids| java.lang.String| Registry IDs for service registration (use this or registries, not both).| | | +| retries| java.lang.Integer| Retry times for failed invocations.| | | +| router| java.lang.String| | | | +| scope| java.lang.String| Service scope ("local" implies searching in the current JVM only).| | | +| scope-model| org.apache.dubbo.rpc.model.ScopeModel| The scope model of this config instance. <p> <b>NOTE:</b> the model maybe changed during config processing, the extension spi instance needs to be reinitialized after changing the model!| | | +| sent| java.lang.Boolean| Acknowledge asynchronous-sent invocations.| | | +| shareconnections| java.lang.Integer| By default, a TCP long-connection communication is shared between the consumer process and the provider process. This property can be set to share multiple TCP long-connection communications. Note that only the dubbo protocol takes effect.| | | +| singleton| java.lang.Boolean| Use separate instances for services with the same serviceKey (applies when using ReferenceConfig and SimpleReferenceCache together). Directly calling ReferenceConfig.get() will not check this attribute.| | | +| sticky| java.lang.Boolean| | | | +| stub| java.lang.String| Local stub class name for the service interface.| | | +| tag| java.lang.String| Custom tag for the service configuration.| | | +| threadpool| java.lang.String| Consumer thread pool type: cached, fixed, limit, eager| | | +| threads| java.lang.Integer| Consumer threadpool thread size| | | +| timeout| java.lang.Integer| Timeout for remote invocation in milliseconds.| | | +| url-merge-processor| java.lang.String| Url Merge Processor Used to customize the URL merge of consumer and provider| | | +| validation| java.lang.String| Enable JSR303 standard annotation validation for method parameters.| | | +| version| java.lang.String| Version of the remote service referenced by the consumer/provider.| | | +### dubbo.metadata-report +**Class:** `org.apache.dubbo.config.MetadataReportConfig` + +|Key|Type|Description|Default value|Deprecation| +|---|----|-----------|-------------|-----------| +| address| java.lang.String| The address of the metadata center.| | | +| check| java.lang.Boolean| Decide the behavior when the initial connection attempt fails, where 'true' means interrupt the whole process once it fails. The default value is true.| | | +| cluster| java.lang.Boolean| Whether to use a cluster configuration for the metadata center.| | | +| cycle-report| java.lang.Boolean| By default, the metadata store will store full metadata repeatedly every day.| | | +| default| java.lang.Boolean| | | | +| file| java.lang.String| The file path for saving the metadata center's dynamic list.| | | +| group| java.lang.String| The group for the metadata center, which is similar to the registry group.| | | +| id| java.lang.String| Identifier for this configuration.| | | +| meta-data| java.util.Map<java.lang.String,java.lang.String>| | | | +| need-refresh| java.lang.Boolean| Specifies if this configuration should be refreshed (true for refreshing).| true| | +| parameters| java.util.Map<java.lang.String,java.lang.String>| Customized parameters for the metadata center.| | | +| password| java.lang.String| The password used to log in to the metadata center.| | | +| port| java.lang.Integer| The default port for the metadata center.| | | +| prefixes| java.util.List<java.lang.String>| | | | +| protocol| java.lang.String| The protocol for the metadata center.| | | +| registry| java.lang.String| The registry ID for the metadata center.| | | +| report-definition| java.lang.Boolean| Whether to report definition.| | | +| report-metadata| java.lang.Boolean| Whether to report metadata.| | | +| retry-period| java.lang.Integer| The retry period in milliseconds when connecting to the metadata center.| | | +| retry-times| java.lang.Integer| The number of retry times when connecting to the metadata center.| | | +| scope-model| org.apache.dubbo.rpc.model.ScopeModel| The scope model of this config instance. <p> <b>NOTE:</b> the model maybe changed during config processing, the extension spi instance needs to be reinitialized after changing the model!| | | +| sync-report| java.lang.Boolean| Synchronization report, with the default value as asynchronous.| | | +| timeout| java.lang.Integer| The request timeout in milliseconds for the metadata center.| | | +| username| java.lang.String| The username used to log in to the metadata center.| | | +### dubbo.metrics +**Class:** `org.apache.dubbo.config.MetricsConfig` + +|Key|Type|Description|Default value|Deprecation| +|---|----|-----------|-------------|-----------| +| collector-sync-period| java.lang.Integer| Collector synchronization period.| | | +| default| java.lang.Boolean| | | | +| enable-collector-sync| java.lang.Boolean| Whether to enable collector synchronization.| | | +| enable-jvm| java.lang.Boolean| Whether to enable JVM metrics collection.| | | +| enable-metadata| java.lang.Boolean| Whether to enable metadata metrics collection.| | | +| enable-metrics-init| java.lang.Boolean| Whether to enable metrics initialization.| | | +| enable-netty| java.lang.Boolean| Whether to enable Netty metrics collection.| | | +| enable-registry| java.lang.Boolean| Whether to enable registry metrics collection.| | | +| enable-rpc| java.lang.Boolean| Whether to enable RPC (Remote Procedure Call) metrics collection.| | | +| enable-threadpool| java.lang.Boolean| Whether to enable thread pool metrics collection.| | | +| export-metrics-service| java.lang.Boolean| Whether to export metrics service.| | | +| export-service-port| java.lang.Integer| Port used for exporting metrics services.| | | +| export-service-protocol| java.lang.String| Protocol used for metrics collection and export.| | | +| id| java.lang.String| Identifier for this configuration.| | | +| meta-data| java.util.Map<java.lang.String,java.lang.String>| | | | +| need-refresh| java.lang.Boolean| Specifies if this configuration should be refreshed (true for refreshing).| true| | +| port| java.lang.String| Deprecated: This parameter should no longer be used and will be removed in the future.| | | +| prefixes| java.util.List<java.lang.String>| | | | +| protocol| java.lang.String| Protocol used for metrics.| | | +| rpc-level| java.lang.String| The level of metrics collection, which can be "SERVICE" or "METHOD". The default is "METHOD".| | | +| scope-model| org.apache.dubbo.rpc.model.ScopeModel| The scope model of this config instance. <p> <b>NOTE:</b> the model maybe changed during config processing, the extension spi instance needs to be reinitialized after changing the model!| | | +| use-global-registry| java.lang.Boolean| Decide whether to use the global registry of Micrometer.| | | +### dubbo.module +**Class:** `org.apache.dubbo.config.ModuleConfig` + +|Key|Type|Description|Default value|Deprecation| +|---|----|-----------|-------------|-----------| +| background| java.lang.Boolean| Whether to start the module in the background. If started in the background, it does not await finish on Spring ContextRefreshedEvent. @see org.apache.dubbo.config.spring.context.DubboDeployApplicationListener| | | +| check-reference-timeout| java.lang.Long| The timeout to check references.| | | +| default| java.lang.Boolean| | | | +| export-async| java.lang.Boolean| Whether the service is exported asynchronously.| | | +| export-thread-num| java.lang.Integer| The thread number for asynchronous export pool size.| | | +| id| java.lang.String| Identifier for this configuration.| | | +| meta-data| java.util.Map<java.lang.String,java.lang.String>| | | | +| monitor| org.apache.dubbo.config.MonitorConfig| Monitor center| | | +| name| java.lang.String| The module name| | | +| need-refresh| java.lang.Boolean| Specifies if this configuration should be refreshed (true for refreshing).| true| | +| organization| java.lang.String| The module's organization| | | +| owner| java.lang.String| The module owner| | | +| prefixes| java.util.List<java.lang.String>| | | | +| refer-async| java.lang.Boolean| Whether the reference is referred asynchronously.| | | +| refer-thread-num| java.lang.Integer| The thread number for asynchronous reference pool size.| | | +| registries| java.util.List<org.apache.dubbo.config.RegistryConfig>| Registry centers| | | +| registry| org.apache.dubbo.config.RegistryConfig| | | | +| scope-model| org.apache.dubbo.rpc.model.ScopeModel| The scope model of this config instance. <p> <b>NOTE:</b> the model maybe changed during config processing, the extension spi instance needs to be reinitialized after changing the model!| | | +| version| java.lang.String| The module version| | | +### dubbo.monitor +**Class:** `org.apache.dubbo.config.MonitorConfig` + +|Key|Type|Description|Default value|Deprecation| +|---|----|-----------|-------------|-----------| +| address| java.lang.String| The monitor address| | | +| default| java.lang.Boolean| | | | +| group| java.lang.String| The monitor group| | | +| id| java.lang.String| Identifier for this configuration.| | | +| interval| java.lang.String| The monitor reporting interval| | | +| meta-data| java.util.Map<java.lang.String,java.lang.String>| | | | +| need-refresh| java.lang.Boolean| Specifies if this configuration should be refreshed (true for refreshing).| true| | +| parameters| java.util.Map<java.lang.String,java.lang.String>| Customized parameters| | | +| password| java.lang.String| The monitor password| | | +| prefixes| java.util.List<java.lang.String>| | | | +| protocol| java.lang.String| The protocol of the monitor. If the value is "registry" it will search the monitor address from the registry center. Otherwise, it will directly connect to the monitor center.| | | +| scope-model| org.apache.dubbo.rpc.model.ScopeModel| The scope model of this config instance. <p> <b>NOTE:</b> the model maybe changed during config processing, the extension spi instance needs to be reinitialized after changing the model!| | | +| username| java.lang.String| The monitor username| | | +| version| java.lang.String| The monitor version| | | +### dubbo.protocol +**Class:** `org.apache.dubbo.config.ProtocolConfig` + +|Key|Type|Description|Default value|Deprecation| +|---|----|-----------|-------------|-----------| +| accepts| java.lang.Integer| The maximum acceptable connections.| | | +| accesslog| java.lang.String| The access log configuration.| | | +| alive| java.lang.Integer| The keep-alive time for threads in the thread pool (default unit is TimeUnit.MILLISECONDS).| | | +| buffer| java.lang.Integer| The buffer size.| | | +| charset| java.lang.String| The character set used for communication.| | | +| client| java.lang.String| The client implementation.| | | +| codec| java.lang.String| The protocol codec.| | | +| contextpath| java.lang.String| The context path for the service.| | | +| corethreads| java.lang.Integer| The core thread size of the thread pool.| | | +| default| java.lang.Boolean| | | | +| dispatcher| java.lang.String| The thread dispatch mode.| | | +| dispather| java.lang.String| | | Reason: null, use for replacement: null| +| exchanger| java.lang.String| The method of information exchange.| | | +| ext-protocol| java.lang.String| Extra protocol for this service, using Port Unification Server.| | | +| extension| java.lang.String| Additional extensions.| | | +| heartbeat| java.lang.Integer| The interval for sending heartbeats.| | | +| host| java.lang.String| The service's IP address (useful when there are multiple network cards available).| | | +| id| java.lang.String| Identifier for this configuration.| | | +| iothreads| java.lang.Integer| The fixed size of the IO thread pool.| | | +| json-check-level| java.lang.String| JSON check level for serialization.| | | +| keep-alive| java.lang.Boolean| Indicates whether it is a persistent connection.| | | +| meta-data| java.util.Map<java.lang.String,java.lang.String>| | | | +| name| java.lang.String| The name of the protocol.| | | +| need-refresh| java.lang.Boolean| Specifies if this configuration should be refreshed (true for refreshing).| true| | +| networker| java.lang.String| The networker implementation.| | | +| optimizer| java.lang.String| The optimizer used for dubbo protocol.| | | +| parameters| java.util.Map<java.lang.String,java.lang.String>| Custom parameters.| | | +| path| java.lang.String| | | Reason: null, use for replacement: null| +| payload| java.lang.Integer| The maximum payload length.| | | +| port| java.lang.Integer| The service's port number.| | | +| prefer-serialization| java.lang.String| Specifies the preferred serialization method for the consumer. If specified, the consumer will use this parameter first. If the Dubbo Sdk you are using contains the serialization type, the serialization method specified by the argument is used. <p> When this parameter is null or the serialization type specified by this parameter does not exist in the Dubbo SDK, the serialization type specified by serialization is used. If the Dubbo SDK if still does not exist, the default type of the Dubbo SDK is used. For Dubbo SDK >= 3.2, <code>preferSerialization</code> takes precedence over <code>serialization</code> <p> Supports multiple values separated by commas, e.g., "fastjson2,fastjson,hessian2".| | | +| prefixes| java.util.List<java.lang.String>| | | | +| prompt| java.lang.String| The command line prompt.| | | +| queues| java.lang.Integer| The length of the thread pool's queue.| | | +| register| java.lang.Boolean| Indicates whether the service should be registered.| | | +| scope-model| org.apache.dubbo.rpc.model.ScopeModel| The scope model of this config instance. <p> <b>NOTE:</b> the model maybe changed during config processing, the extension spi instance needs to be reinitialized after changing the model!| | | +| serialization| java.lang.String| The serialization method.| | | +| server| java.lang.String| The server implementation.| | | +| ssl-enabled| java.lang.Boolean| Indicates whether SSL is enabled.| | | +| status| java.lang.String| The status check configuration.| | | +| telnet| java.lang.String| Supported Telnet commands, separated by commas.| | | +| thread-pool-exhausted-listeners| java.lang.String| Listeners for exhausted thread pool.| | | +| threadpool| java.lang.String| The name of the thread pool.| | | +| threads| java.lang.Integer| The fixed size of the thread pool.| | | +| transporter| java.lang.String| The transporter used for communication.| | | +### dubbo.provider +**Class:** `org.apache.dubbo.config.ProviderConfig` + +|Key|Type|Description|Default value|Deprecation| +|---|----|-----------|-------------|-----------| +| accepts| java.lang.Integer| The maximum number of acceptable connections.| | | +| accesslog| java.lang.String| Whether to export access logs to logs.| | | +| actives| java.lang.Integer| Maximum concurrent invocations allowed.| | | +| alive| java.lang.Integer| The keep-alive time of the thread pool, default unit: TimeUnit.MILLISECONDS.| | | +| application| org.apache.dubbo.config.ApplicationConfig| Application configuration for the service.| | Reason: null, use for replacement: null| +| async| java.lang.Boolean| Enable asynchronous invocation. Note that it is unreliable asynchronous, ignoring return values and not blocking threads.| | | +| auth| java.lang.Boolean| Enable service authentication.| | | +| buffer| java.lang.Integer| The size of the network I/O buffer.| | | +| cache| java.lang.String| Cache provider for caching return results. available options: lru, threadlocal, jcache etc.| | | +| callbacks| java.lang.Integer| Callback limits for the service.| | | +| charset| java.lang.String| The charset used for serialization.| | | +| client| java.lang.String| The client-side implementation model of the protocol.| | | +| cluster| java.lang.String| Cluster type for service.| | | +| codec| java.lang.String| The codec used by the protocol.| | | +| config-center| org.apache.dubbo.config.ConfigCenterConfig| Configuration center settings.| | Reason: null, use for replacement: null| +| connections| java.lang.Integer| Connection limits: 0 for shared connection, otherwise specifying connections for the service.| | | +| contextpath| java.lang.String| The context path of the service.| | | +| default| java.lang.Boolean| | | | +| delay| java.lang.Integer| The time delay to register the service (in milliseconds).| | | +| deprecated| java.lang.Boolean| Whether the service is deprecated.| | | +| dispatcher| java.lang.String| The mode of thread dispatching.| | | +| dispather| java.lang.String| | | Reason: null, use for replacement: null| +| document| java.lang.String| Document center for the service.| | | +| dynamic| java.lang.Boolean| Whether to register the service as a dynamic service on the registry. If true, the service will be enabled automatically after registration, and manual disabling is required to stop it.| | | +| exchanger| java.lang.String| The method of information exchange.| | | +| executes| java.lang.Integer| Max allowed executing times.| | | +| executor| java.util.concurrent.Executor| used for thread pool isolation between services| | | +| export| java.lang.Boolean| Whether to export the service.| | | +| export-async| java.lang.Boolean| Weather the service is export asynchronously @deprecated @see ModuleConfig#exportAsync| | Reason: null, use for replacement: null| +| export-background| java.lang.Boolean| Whether the export should run in the background or not. @deprecated Replace with {@link ModuleConfig#setBackground(Boolean)} @see ModuleConfig#setBackground(Boolean)| | Reason: null, use for replacement: null| +| export-thread-num| java.lang.Integer| The number of threads for the asynchronous export pool.| | Reason: null, use for replacement: null| +| exported-urls| java.util.List<org.apache.dubbo.common.URL>| | | | +| filter| java.lang.String| Filters for service exposure or reference (multiple filters can be separated by commas).| | | +| forks| java.lang.Integer| Forks for forking cluster.| | | +| group| java.lang.String| The service group.| | | +| host| java.lang.String| The IP addresses of the service (used when there are multiple network cards available).| | | +| id| java.lang.String| Identifier for this configuration.| | | +| interface| java.lang.String| | | | +| iothreads| java.lang.Integer| The size of the I/O thread pool (fixed size).| | | +| layer| java.lang.String| Layer of service providers.| | | +| listener| java.lang.String| Listeners for service exposure or reference (multiple listeners can be separated by commas).| | | +| loadbalance| java.lang.String| Load balancing strategy for service invocation.| | | +| local| java.lang.String| Local implementation class name for the service interface.| | Reason: null, use for replacement: null| +| merger| java.lang.String| Merger for result data.| | | +| meta-data| java.util.Map<java.lang.String,java.lang.String>| | | | +| metadata-report-config| org.apache.dubbo.config.MetadataReportConfig| Metadata report configuration.| | Reason: null, use for replacement: null| +| methods| java.util.List<org.apache.dubbo.config.MethodConfig>| Method-specific configuration.| | | +| mock| java.lang.String| Mock class name to be called when a service fails to execute. The mock doesn't support on the provider side, and it is executed when a non-business exception occurs after a remote service call.| | | +| module| org.apache.dubbo.config.ModuleConfig| Module configuration for the service.| | Reason: null, use for replacement: null| +| monitor| org.apache.dubbo.config.MonitorConfig| Service monitoring configuration.| | Reason: null, use for replacement: null| +| need-refresh| java.lang.Boolean| Specifies if this configuration should be refreshed (true for refreshing).| true| | +| networker| java.lang.String| The networker used by the protocol.| | | +| onconnect| java.lang.String| Event handler for connection establishment.| | | +| ondisconnect| java.lang.String| Event handler for disconnection.| | | +| owner| java.lang.String| Owner of the service providers.| | | +| parameters| java.util.Map<java.lang.String,java.lang.String>| Customized parameters for configuration.| | | +| path| java.lang.String| | | Reason: null, use for replacement: null| +| payload| java.lang.Integer| The maximum payload length.| | | +| port| java.lang.Integer| The port of the service.| | Reason: null, use for replacement: null| +| prefer-serialization| java.lang.String| Specifies the preferred serialization method for the consumer. If specified, the consumer will use this parameter first. If the Dubbo Sdk you are using contains the serialization type, the serialization method specified by the argument is used. <p> When this parameter is null or the serialization type specified by this parameter does not exist in the Dubbo SDK, the serialization type specified by serialization is used. If the Dubbo SDK if still does not exist, the default type of the Dubbo SDK is used. For Dubbo SDK >= 3.2, <code>preferSerialization</code> takes precedence over <code>serialization</code> <p> Supports multiple values separated by commas, e.g., "fastjson2,fastjson,hessian2".| | | +| prefixes| java.util.List<java.lang.String>| | | | +| prompt| java.lang.String| The command line prompt.| | | +| protocol| org.apache.dubbo.config.ProtocolConfig| | | | +| protocol-ids| java.lang.String| Id list of protocols the service will export with (use this or protocols, not both).| | | +| protocols| java.util.List<org.apache.dubbo.config.ProtocolConfig>| List of protocols the service will export with (use this or protocolIds, not both).| | | +| proxy| java.lang.String| Strategy for generating dynamic agents (options: "jdk" or "javassist").| | | +| queues| java.lang.Integer| The length of the thread pool queue.| | | +| register| java.lang.Boolean| Whether to register the service.| | | +| registries| java.util.List<org.apache.dubbo.config.RegistryConfig>| Registries where the service will be registered (use this or registryIds, not both).| | | +| registry| org.apache.dubbo.config.RegistryConfig| | | | +| registry-ids| java.lang.String| Registry IDs for service registration (use this or registries, not both).| | | +| retries| java.lang.Integer| Retry times for failed invocations.| | | +| scope| java.lang.String| Service scope ("local" implies searching in the current JVM only).| | | +| scope-model| org.apache.dubbo.rpc.model.ScopeModel| The scope model of this config instance. <p> <b>NOTE:</b> the model maybe changed during config processing, the extension spi instance needs to be reinitialized after changing the model!| | | +| sent| java.lang.Boolean| Acknowledge asynchronous-sent invocations.| | | +| serialization| java.lang.String| Serialization type for service communication.| | | +| server| java.lang.String| The server-side implementation model of the protocol.| | | +| singleton| java.lang.Boolean| Use separate instances for services with the same serviceKey (applies when using ReferenceConfig and SimpleReferenceCache together). Directly calling ReferenceConfig.get() will not check this attribute.| | | +| status| java.lang.String| The status check configuration.| | | +| stub| java.lang.String| Local stub class name for the service interface.| | | +| tag| java.lang.String| Custom tag for the service configuration.| | | +| telnet| java.lang.String| Supported telnet commands, separated by commas.| | | +| threadname| java.lang.String| The name of the thread pool.| | | +| threadpool| java.lang.String| The thread pool configuration.| | | +| threads| java.lang.Integer| The size of the thread pool (fixed size).| | | +| timeout| java.lang.Integer| Timeout for remote invocation in milliseconds.| | | +| token| java.lang.String| Whether to use a token for authentication.| | | +| transporter| java.lang.String| The transporter used by the protocol.| | | +| use-java-package-as-path| java.lang.Boolean| Whether to use java_package in IDL as path. Default use package. This param only available when service using native stub.| | | +| validation| java.lang.String| Enable JSR303 standard annotation validation for method parameters.| | | +| version| java.lang.String| The service version.| | | +| wait| java.lang.Integer| The wait time when stopping the service.| | | +| warmup| java.lang.Integer| Warm-up period for the service.| | | +| weight| java.lang.Integer| The service weight.| | | +### dubbo.registry +**Class:** `org.apache.dubbo.config.RegistryConfig` + +|Key|Type|Description|Default value|Deprecation| +|---|----|-----------|-------------|-----------| +| accepts| java.lang.String| List of RPC protocols accepted by this registry, e.g., "dubbo,rest".| | | +| address| java.lang.String| Register center address.| | | +| check| java.lang.Boolean| Whether to check if the register center is available when booting up.| | | +| client| java.lang.String| Client implementation.| | | +| cluster| java.lang.String| Affects how traffic distributes among registries, useful when subscribing to multiple registries. Available options: - "zone-aware": A certain type of traffic always goes to one Registry according to where the traffic is originated.| | | +| default| java.lang.Boolean| | | | +| dynamic| java.lang.Boolean| Whether to allow dynamic service registration on the register center.| | | +| enable-empty-protection| java.lang.Boolean| Enable empty protection.| | | +| extra-keys| java.lang.String| After simplifying the registry, add some parameters individually, useful for providers. Example: extra-keys = "A, b, c, d". @since 2.7.0| | | +| file| java.lang.String| File for saving the register center dynamic list.| | | +| group| java.lang.String| The group that services registry belongs to.| | | +| id| java.lang.String| Identifier for this configuration.| | | +| meta-data| java.util.Map<java.lang.String,java.lang.String>| | | | +| need-refresh| java.lang.Boolean| Specifies if this configuration should be refreshed (true for refreshing).| true| | +| parameters| java.util.Map<java.lang.String,java.lang.String>| Customized parameters.| | | +| password| java.lang.String| Password to login the register center.| | | +| port| java.lang.Integer| Default port for the register center.| | | +| preferred| java.lang.Boolean| Always use this registry first if set to true, useful when subscribing to multiple registries.| | | +| prefixes| java.util.List<java.lang.String>| | | | +| protocol| java.lang.String| Protocol used for the register center.| | | +| register| java.lang.Boolean| Whether to allow exporting service on the register center.| | | +| register-mode| java.lang.String| Register mode.| | | +| scope-model| org.apache.dubbo.rpc.model.ScopeModel| The scope model of this config instance. <p> <b>NOTE:</b> the model maybe changed during config processing, the extension spi instance needs to be reinitialized after changing the model!| | | +| secure| java.lang.String| Security settings.| | | +| server| java.lang.String| Server implementation.| | | +| session| java.lang.Integer| Session timeout in milliseconds for the register center.| | | +| simplified| java.lang.Boolean| Simplify the registry, useful for both providers and consumers. @since 2.7.0| | | +| subscribe| java.lang.Boolean| Whether to allow subscribing to services on the register center.| | | +| timeout| java.lang.Integer| Connect timeout in milliseconds for the register center.| | | +| transport| java.lang.String| | | Reason: null, use for replacement: null| +| transporter| java.lang.String| Network transmission type.| | | +| use-as-config-center| java.lang.Boolean| Indicates whether the address works as a configuration center or not.| | | +| use-as-metadata-center| java.lang.Boolean| Indicates whether the address works as a remote metadata center or not.| | | +| username| java.lang.String| Username to login the register center.| | | +| version| java.lang.String| Version of the registry.| | | +| wait| java.lang.Integer| Wait time before stopping.| | Reason: null, use for replacement: null| +| weight| java.lang.Integer| Affects traffic distribution among registries, useful when subscribing to multiple registries. Takes effect only when no preferred registry is specified.| | | +| zone| java.lang.String| The region where the registry belongs, usually used to isolate traffics.| | | +### dubbo.rpc +**Class:** `org.apache.dubbo.spring.boot.autoconfigure.DubboConfigurationProperties$RpcConfig` + +|Key|Type|Description|Default value|Deprecation| +|---|----|-----------|-------------|-----------| +### dubbo.ssl +**Class:** `org.apache.dubbo.config.SslConfig` + +|Key|Type|Description|Default value|Deprecation| +|---|----|-----------|-------------|-----------| +| ca-address| java.lang.String| Address for Certificate Authority (CA).| | | +| ca-cert-path| java.lang.String| Path to the CA certificate file.| | | +| client-key-cert-chain-path| java.lang.String| Path to the client's key certificate chain file.| | | +| client-key-cert-chain-path-stream| java.io.InputStream| Input stream for the client's key certificate chain (if provided).| | | +| client-key-password| java.lang.String| Password for the client's private key (if applicable).| | | +| client-private-key-path| java.lang.String| Path to the client's private key file.| | | +| client-private-key-path-stream| java.io.InputStream| Input stream for the client's private key (if provided).| | | +| client-trust-cert-collection-path| java.lang.String| Path to the client's trust certificate collection file.| | | +| client-trust-cert-collection-path-stream| java.io.InputStream| Input stream for the client's trust certificate collection (if provided).| | | +| default| java.lang.Boolean| | | | +| env-type| java.lang.String| Environment type for SSL configuration.| | | +| id| java.lang.String| Identifier for this configuration.| | | +| meta-data| java.util.Map<java.lang.String,java.lang.String>| | | | +| need-refresh| java.lang.Boolean| Specifies if this configuration should be refreshed (true for refreshing).| true| | +| oidc-token-path| java.lang.String| Path to the OIDC (OpenID Connect) token file.| | | +| prefixes| java.util.List<java.lang.String>| | | | +| scope-model| org.apache.dubbo.rpc.model.ScopeModel| The scope model of this config instance. <p> <b>NOTE:</b> the model maybe changed during config processing, the extension spi instance needs to be reinitialized after changing the model!| | | +| server-key-cert-chain-path| java.lang.String| Path to the server's key certificate chain file.| | | +| server-key-cert-chain-path-stream| java.io.InputStream| Input stream for the server's key certificate chain (if provided).| | | +| server-key-password| java.lang.String| Password for the server's private key (if applicable).| | | +| server-private-key-path| java.lang.String| Path to the server's private key file.| | | +| server-private-key-path-stream| java.io.InputStream| Input stream for the server's private key (if provided).| | | +| server-trust-cert-collection-path| java.lang.String| Path to the server's trust certificate collection file.| | | +| server-trust-cert-collection-path-stream| java.io.InputStream| Input stream for the server's trust certificate collection (if provided).| | | +### dubbo.tracing +**Class:** `org.apache.dubbo.config.TracingConfig` + +|Key|Type|Description|Default value|Deprecation| +|---|----|-----------|-------------|-----------| +| default| java.lang.Boolean| | | | +| enabled| java.lang.Boolean| Indicates whether the feature is enabled (default is false).| false| | +| id| java.lang.String| Identifier for this configuration.| | | +| meta-data| java.util.Map<java.lang.String,java.lang.String>| | | | +| need-refresh| java.lang.Boolean| Specifies if this configuration should be refreshed (true for refreshing).| true| | +| prefixes| java.util.List<java.lang.String>| | | | +| scope-model| org.apache.dubbo.rpc.model.ScopeModel| The scope model of this config instance. <p> <b>NOTE:</b> the model maybe changed during config processing, the extension spi instance needs to be reinitialized after changing the model!| | | +### dubbo.metrics.aggregation +**Class:** `org.apache.dubbo.config.nested.AggregationConfig` + +|Key|Type|Description|Default value|Deprecation| +|---|----|-----------|-------------|-----------| +| bucket-num| java.lang.Integer| The number of buckets for time window quantile.| | | +| enable-qps| java.lang.Boolean| Enable QPS (Queries Per Second) aggregation or not.| | | +| enable-request| java.lang.Boolean| Enable Request aggregation or not.| | | +| enable-rt| java.lang.Boolean| Enable Response Time aggregation or not.| | | +| enable-rt-pxx| java.lang.Boolean| Enable Response Time Percentile (Pxx) aggregation or not.| | | +| enabled| java.lang.Boolean| Enable aggregation or not.| | | +| qps-time-window-mill-seconds| java.lang.Integer| The time window in milliseconds for QPS (Queries Per Second) aggregation.| | | +| time-window-seconds| java.lang.Integer| The time window in seconds for time window quantile.| | | +### dubbo.metrics.histogram +**Class:** `org.apache.dubbo.config.nested.HistogramConfig` + +|Key|Type|Description|Default value|Deprecation| +|---|----|-----------|-------------|-----------| +| buckets-ms| java.lang.Integer[]| Buckets in milliseconds for the histograms. Defines the histogram bucket boundaries.| | | +| distribution-statistic-expiry-min| java.lang.Integer| Expiry time in minutes for distribution statistics. After this time, the statistics are expired.| | | +| enabled| java.lang.Boolean| Whether histograms are enabled or not. Default is not enabled (false).| | | +| enabled-percentiles| java.lang.Boolean| Whether enabledPercentiles are enabled or not. Default is not enabled (false).| | | +| max-expected-ms| java.lang.Integer| Maximum expected value in milliseconds for the histograms. Values higher than this will be considered outliers.| | | +| min-expected-ms| java.lang.Integer| Minimum expected value in milliseconds for the histograms. Values lower than this will be considered outliers.| | | +| percentiles| java.lang.Double[]| Array of percentiles to be calculated for the histograms. Each percentile is a double value.| | | +### dubbo.metrics.prometheus +**Class:** `org.apache.dubbo.config.nested.PrometheusConfig` + +|Key|Type|Description|Default value|Deprecation| +|---|----|-----------|-------------|-----------| - - -## 配置选项 -### application - -每个应用必须要有且只有一个 application 配置 - -> 对应的配置类:`org.apache.dubbo.config.ApplicationConfig` - -| 属性 | 对应URL参数 | 类型 | 是否必填 | 缺省值 | 作用 | 描述 | 兼容性 | -| --- | --- | ---- | --- | --- | --- | --- | --- | -| name | application | string | 必填 | | 服务治理 | 当前应用名称,用于注册中心计算应用间依赖关系,注意:消费者和提供者应用名不要一样,此参数不是匹配条件,你当前项目叫什么名字就填什么,和提供者消费者角色无关,比如:kylin应用调用了morgan应用的服务,则kylin项目配成kylin,morgan项目配成morgan,可能kylin也提供其它服务给别人使用,但kylin项目永远配成kylin,这样注册中心将显示kylin依赖于morgan | 2.7.0以上版本 | -| compiler | compiler | string | 可选 | javassist | 性能优化 | Java字节码编译器,用于动态类的生成,可选:jdk或javassist | 2.7.0以上版本 | -| logger | logger | string | 可选 | slf4j | 性能优化 | 日志输出方式,可选:slf4j,jcl,log4j,log4j2,jdk | 2.7.0以上版本 | -| owner | owner | string | 可选 | | 服务治理 | 应用负责人,用于服务治理,请填写负责人公司邮箱前缀 | 2.0.5以上版本 | -| organization | organization | string | 可选 | | 服务治理 | 组织名称(BU或部门),用于注册中心区分服务来源,此配置项建议不要使用autoconfig,直接写死在配置中,比如china,intl,itu,crm,asc,dw,aliexpress等 | 2.0.0以上版本 | -| architecture
| architecture
| string | 可选 | | 服务治理 | 用于服务分层对应的架构。如,intl、china。不同的架构使用不同的分层。 | 2.0.7以上版本 | -| environment | environment | string | 可选 | | 服务治理 | 应用环境,如:develop/test/product,不同环境使用不同的缺省值,以及作为只用于开发测试功能的限制条件 | 2.0.0以上版本 | -| version | application.version | string | 可选 | | 服务治理 | 当前应用的版本 | 2.7.0以上版本 | -| dumpDirectory | dump.directory | string | 可选 | | 服务治理 | 当进程出问题如线程池满时,框架自动dump文件的存储路径 | 2.7.0以上版本 | -| qosEnable | qos.enable | boolean | 可选 | | 服务治理 | 是否启用 qos 运维端口 | 2.7.0以上版本 | -| qosHost | qos.host | string | 可选 | | 服务治理 | 监听的网络接口地址,默认 0.0.0.0 | 2.7.3以上版本 | -| qosPort | qos.port | int | 可选 | | 服务治理 | 监听的网络端口 | 2.7.0以上版本 | -| qosAcceptForeignIp | qos.accept.foreign.ip | boolean | 可选 | | 服务治理 | 安全配置,是否接收除localhost本机访问之外的外部请求 | 2.7.0以上版本 | -| shutwait | dubbo.service.shutdown.wait | string | 可选 | | 服务治理 | 优雅停机时 shutdown 的等待时间(ms) | 2.7.0以上版本 | -| hostname | | string | 可选 | 本机主机名 | 服务治理 | 主机名 | 2.7.5以上版本 | -| registerConsumer | registerConsumer | boolean | 可选 | true | 服务治理 | 是否注册实例到注册中心。当时实例为纯消费者时才设置为`false` | 2.7.5以上版本 | -| repository | application.version | string | 可选 | | 服务治理 | 当前应用的版本 | 2.7.6以上版本 | -| enableFileCache | file.cache | boolean | 可选 | true | 服务治理 | 是否开启本地缓存 | 3.0.0以上版本 | -| protocol | | string | 可选 | dubbo | 服务治理 | 首选协议,适用于无法确定首选协议的时候 | 3.0.0以上版本 | -| metadataType | metadata-type |String| 可选 | local | 服务治理 | 应用级服务发现 metadata 传递方式,是以 Provider 视角而言的,Consumer 侧配置无效,可选值有:
* remote - Provider 把 metadata 放到远端注册中心,Consumer 从注册中心获取;
* local - Provider 把 metadata 放在本地,Consumer 从 Provider 处直接获取;| 2.7.5以上版本 | -| metadataServiceProtocol | metadata-service-protocol | string | 可选 | dubbo | 服务治理 | 如 metadataType 配置为 local,则该属性设置 MetadataService 服务所用的通信协议,默认为 dubbo| 3.0.0以上版本 | -| metadataServicePort | metadata-service-port | int | 可选 | | 服务治理 | 如 metadataType 配置为 local,则该属性设置 MetadataService 服务所用的端口号| 2.7.9以上版本 | -| livenessProbe | liveness-probe | string | 可选 | | 服务治理 | 概念和格式对应 k8s 体系 liveness probe | 3.0.0以上版本 | -| readinessProbe | readiness-probe | string | 可选 | | 服务治理 | 概念和格式对应 k8s 体系 readiness probe | 3.0.0以上版本 | -| startupProbe | startup-probe | string | 可选 | | 服务治理 | 概念和格式对应 k8s 体系 startup probe | 3.0.0以上版本 | -| registerMode | register-mode | string | 可选 | all | 服务治理 | 控制地址注册行为,应用级服务发现迁移用。
* instance 只注册应用级地址;
* interface 只注册接口级地址;
* all(默认) 同时注册应用级和接口级地址; | 3.0.0以上版本 | -| enableEmptyProtection | enable-empty-protection | boolean | 可选 | true | 服务治理 | 是否全局启用消费端的空地址列表保护,开启后注册中心的空地址推送将被忽略,默认 true | 3.0.0以上版本 | -| parameters | 无 | Map | 可选 | | 服务治理 | 扩展预留,可扩展定义任意参数,所有扩展参数都将原样反映在 URL 配置上 | 2.7.0以上版本 | - - -### service - -服务提供者暴露服务配置。 - -> 对应的配置类:`org.apache.dubbo.config.ServiceConfig` - -| 属性 | 对应URL参数 | 类型 | 是否必填 | 缺省值 | 作用 | 描述 | 兼容性 | -| --- | --- | ---- | --- | --- | --- | --- | --- | -| interface | | class | 必填 | | 服务发现 | 服务接口名 | 1.0.0以上版本 | -| ref | | object | 必填 | | 服务发现 | 服务对象实现引用 | 1.0.0以上版本 | -| version | version | string | 可选 | 0.0.0 | 服务发现 | 服务版本,建议使用两位数字版本,如:1.0,通常在接口不兼容时版本号才需要升级 | 1.0.0以上版本 | -| group | group | string | 可选 | | 服务发现 | 服务分组,当一个接口有多个实现,可以用分组区分 | 1.0.7以上版本 | -| path | <path> | string | 可选 | 缺省为接口名 | 服务发现 | 服务路径 (注意:1.0不支持自定义路径,总是使用接口名,如果有1.0调2.0,配置服务路径可能不兼容) | 1.0.12以上版本 | -| delay | delay | int | 可选 | 0 | 性能调优 | 延迟注册服务时间(毫秒) ,设为-1时,表示延迟到Spring容器初始化完成时暴露服务 | 1.0.14以上版本 | -| timeout | timeout | int | 可选 | 1000 | 性能调优 | 远程服务调用超时时间(毫秒) | 2.0.0以上版本 | -| retries | retries | int | 可选 | 2 | 性能调优 | 远程服务调用重试次数,不包括第一次调用,不需要重试请设为0 | 2.0.0以上版本 | -| connections | connections | int | 可选 | 100 | 性能调优 | 对每个提供者的最大连接数,rmi、http、hessian等短连接协议表示限制连接数,dubbo等长连接协表示建立的长连接个数 | 2.0.0以上版本 | -| loadbalance | loadbalance | string | 可选 | random | 性能调优 | 负载均衡策略,可选值:
* random - 随机;
* roundrobin - 轮询;
* leastactive - 最少活跃调用;
* consistenthash - 哈希一致 (2.1.0以上版本);
* shortestresponse - 最短响应 (2.7.7以上版本);| 2.0.0以上版本 | -| async | async | boolean | 可选 | false | 性能调优 | 是否缺省异步执行,不可靠异步,只是忽略返回值,不阻塞执行线程 | 2.0.0以上版本 | -| local | local | class/boolean | 可选 | false | 服务治理 | 设为true,表示使用缺省代理类名,即:接口名 + Local后缀,已废弃,请使用stub| 2.0.0以上版本 | -| stub | stub | class/boolean | 可选 | false | 服务治理 | 设为true,表示使用缺省代理类名,即:接口名 + Stub后缀,服务接口客户端本地代理类名,用于在客户端执行本地逻辑,如本地缓存等,该本地代理类的构造函数必须允许传入远程代理对象,构造函数如:public XxxServiceStub(XxxService xxxService) | 2.0.0以上版本 | -| mock | mock | class/boolean | 可选 | false | 服务治理 | 设为true,表示使用缺省Mock类名,即:接口名 + Mock后缀,服务接口调用失败Mock实现类,该Mock类必须有一个无参构造函数,与Local的区别在于,Local总是被执行,而Mock只在出现非业务异常(比如超时,网络异常等)时执行,Local在远程调用之前执行,Mock在远程调用后执行。 | 2.0.0以上版本 | -| token | token | string/boolean | 可选 | | 服务治理 | 令牌验证,为空表示不开启,如果为true,表示随机生成动态令牌,否则使用静态令牌,令牌的作用是防止消费者绕过注册中心直接访问,保证注册中心的授权功能有效,如果使用点对点调用,需关闭令牌功能 | 2.0.0以上版本 | -| registry | | string | 可选 | 缺省向所有registry注册 | 配置关联 | 向指定注册中心注册,在多个注册中心时使用,值为<dubbo:registry>的id属性,多个注册中心ID用逗号分隔,如果不想将该服务注册到任何registry,可将值设为N/A | 2.0.0以上版本 | -| provider | | string | 可选 | 缺省使用第一个provider配置 | 配置关联 | 指定provider,值为<dubbo:provider>的id属性 | 2.0.0以上版本 | -| deprecated | deprecated | boolean | 可选 | false | 服务治理 | 服务是否过时,如果设为true,消费方引用时将打印服务过时警告error日志 | 2.0.5以上版本 | -| dynamic | dynamic | boolean | 可选 | true | 服务治理 | 服务是否动态注册,如果设为false,注册后将显示后disable状态,需人工启用,并且服务提供者停止时,也不会自动取消册,需人工禁用。 | 2.0.5以上版本 | -| accesslog | accesslog | string/boolean | 可选 | false | 服务治理 | 设为true,将向logger中输出访问日志,也可填写访问日志文件路径,直接把访问日志输出到指定文件 | 2.0.5以上版本 | -| owner | owner | string | 可选 | | 服务治理 | 服务负责人,用于服务治理,请填写负责人公司邮箱前缀 | 2.0.5以上版本 | -| document | document | string | 可选 | | 服务治理 | 服务文档URL | 2.0.5以上版本 | -| weight | weight | int | 可选 | | 性能调优 | 服务权重 | 2.0.5以上版本 | -| executes | executes | int | 可选 | 0 | 性能调优 | 服务提供者每服务每方法最大可并行执行请求数 | 2.0.5以上版本 | -| actives | actives | int | 可选 | 0 | 性能调优 | 每服务消费者每服务每方法最大并发调用数 | 2.0.5以上版本 | -| proxy | proxy | string | 可选 | javassist | 性能调优 | 生成动态代理方式,可选:jdk/javassist | 2.0.5以上版本 | -| cluster | cluster | string | 可选 | failover | 性能调优 | 集群方式,可选:failover/failfast/failsafe/failback/forking/available/mergeable(2.1.0以上版本)/broadcast(2.1.0以上版本)/zone-aware(2.7.5以上版本) | 2.0.5以上版本 | -| filter | service.filter | string | 可选 | default | 性能调优 | 服务提供方远程调用过程拦截器名称,多个名称用逗号分隔 | 2.0.5以上版本 | -| listener | exporter.listener | string | 可选 | default | 性能调优 | 服务提供方导出服务监听器名称,多个名称用逗号分隔 | | -| protocol | | string | 可选 | | 配置关联 | 使用指定的协议暴露服务,在多协议时使用,值为<dubbo:protocol>的id属性,多个协议ID用逗号分隔 | 2.0.5以上版本 | -| layer | layer | string | 可选 | | 服务治理 | 服务提供者所在的分层。如:biz、dao、intl:web、china:acton。 | 2.0.7以上版本 | -| register | register | boolean | 可选 | true | 服务治理 | 该协议的服务是否注册到注册中心 | 2.0.8以上版本 | -| validation | validation | string | 可选 | | 服务治理 | 是否启用JSR303标准注解验证,如果启用,将对方法参数上的注解进行校验 | 2.7.0以上版本 | -| parameters | 无 | Map | 可选 | | 服务治理 | 扩展预留,可扩展定义任意参数,所有扩展参数都将原样反映在 URL 配置上 | 2.0.0以上版本 | - -### reference - - -服务消费者引用服务配置。 - -> 对应的配置类: `org.apache.dubbo.config.ReferenceConfig` - -| 属性 | 对应URL参数 | 类型 | 是否必填 | 缺省值 | 作用 | 描述 | 兼容性 | -| --- | --- | ---- | --- | --- | --- | --- | --- | -| id | | string | 必填 | | 配置关联 | 服务引用BeanId | 1.0.0以上版本 | -| interface | | class | 必填 | | 服务发现 | 服务接口名 | 1.0.0以上版本 | -| version | version | string | 可选 | | 服务发现 | 服务版本,与服务提供者的版本一致 | 1.0.0以上版本 | -| group | group | string | 可选 | | 服务发现 | 服务分组,当一个接口有多个实现,可以用分组区分,必需和服务提供方一致 | 1.0.7以上版本 | -| timeout | timeout | long | 可选 | 缺省使用<dubbo:consumer>的timeout | 性能调优 | 服务方法调用超时时间(毫秒) | 1.0.5以上版本 | -| retries | retries | int | 可选 | 缺省使用<dubbo:consumer>的retries | 性能调优 | 远程服务调用重试次数,不包括第一次调用,不需要重试请设为0 | 2.0.0以上版本 | -| connections | connections | int | 可选 | 缺省使用<dubbo:consumer>的connections | 性能调优 | 对每个提供者的最大连接数,rmi、http、hessian等短连接协议表示限制连接数,dubbo等长连接协表示建立的长连接个数 | 2.0.0以上版本 | -| loadbalance | loadbalance | string | 可选 | 缺省使用<dubbo:consumer>的loadbalance | 性能调优 | 负载均衡策略,可选值:
* random - 随机;
* roundrobin - 轮询;
* leastactive - 最少活跃调用;
* consistenthash - 哈希一致 (2.1.0以上版本);
* shortestresponse - 最短响应 (2.7.7以上版本); | 2.0.0以上版本 | -| async | async | boolean | 可选 | 缺省使用<dubbo:consumer>的async | 性能调优 | 是否异步执行,不可靠异步,只是忽略返回值,不阻塞执行线程 | 2.0.0以上版本 | -| generic | generic | boolean | 可选 | 缺省使用<dubbo:consumer>的generic | 服务治理 | 是否缺省泛化接口,如果为泛化接口,将返回GenericService | 2.0.0以上版本 | -| check | check | boolean | 可选 | 缺省使用<dubbo:consumer>的check | 服务治理 | 启动时检查提供者是否存在,true报错,false忽略 | 2.0.0以上版本 | -| url | url | string | 可选 | | 服务治理 | 点对点直连服务提供者地址,将绕过注册中心 | 1.0.6以上版本 | -| stub | stub | class/boolean | 可选 | | 服务治理 | 服务接口客户端本地代理类名,用于在客户端执行本地逻辑,如本地缓存等,该本地代理类的构造函数必须允许传入远程代理对象,构造函数如:public XxxServiceLocal(XxxService xxxService) | 2.0.0以上版本 | -| mock | mock | class/boolean | 可选 | | 服务治理 | 服务接口调用失败Mock实现类名,该Mock类必须有一个无参构造函数,与Local的区别在于,Local总是被执行,而Mock只在出现非业务异常(比如超时,网络异常等)时执行,Local在远程调用之前执行,Mock在远程调用后执行。 | Dubbo1.0.13及其以上版本支持 | -| cache | cache | string/boolean | 可选 | | 服务治理 | 以调用参数为key,缓存返回结果,可选:lru, threadlocal, jcache等 | Dubbo2.1.0及其以上版本支持 | -| validation | validation | boolean | 可选 | | 服务治理 | 是否启用JSR303标准注解验证,如果启用,将对方法参数上的注解进行校验 | Dubbo2.1.0及其以上版本支持 | -| proxy | proxy | boolean | 可选 | javassist | 性能调优 | 选择动态代理实现策略,可选:javassist, jdk | 2.0.2以上版本 | -| client | client | string | 可选 | | 性能调优 | 客户端传输类型设置,如Dubbo协议的netty或mina。 | Dubbo2.0.0以上版本支持 | -| registry | | string | 可选 | 缺省将从所有注册中心获服务列表后合并结果 | 配置关联 | 从指定注册中心注册获取服务列表,在多个注册中心时使用,值为<dubbo:registry>的id属性,多个注册中心ID用逗号分隔 | 2.0.0以上版本 | -| owner | owner | string | 可选 | | 服务治理 | 调用服务负责人,用于服务治理,请填写负责人公司邮箱前缀 | 2.0.5以上版本 | -| actives | actives | int | 可选 | 0 | 性能调优 | 每服务消费者每服务每方法最大并发调用数 | 2.0.5以上版本 | -| cluster | cluster | string | 可选 | failover | 性能调优 | 集群方式,可选:failover/failfast/failsafe/failback/forking/available/mergeable(2.1.0以上版本)/broadcast(2.1.0以上版本)/zone-aware(2.7.5以上版本) | 2.0.5以上版本 | -| filter | reference.filter | string | 可选 | default | 性能调优 | 服务消费方远程调用过程拦截器名称,多个名称用逗号分隔 | 2.0.5以上版本 | -| listener | invoker.listener | string | 可选 | default | 性能调优 | 服务消费方引用服务监听器名称,多个名称用逗号分隔 | 2.0.5以上版本 | -| layer | layer | string | 可选 | | 服务治理 | 服务调用者所在的分层。如:biz、dao、intl:web、china:acton。 | 2.0.7以上版本 | -| init | init | boolean | 可选 | false | 性能调优 | 是否在afterPropertiesSet()时饥饿初始化引用,否则等到有人注入或引用该实例时再初始化。 | 2.0.10以上版本 | -| protocol | protocol | string | 可选 | | 服务治理 | 只调用指定协议的服务提供方,其它协议忽略。 | 2.7.0以上版本 | -| client | client | string | 可选 | dubbo协议缺省为netty | 服务发现 | 协议的客户端实现类型,比如:dubbo协议的mina,netty等 | 2.7.0以上版本 | -| providerPort | provider-port | int | 可选 | | Service Mesh | 当dubbo.consumer.meshEnable=true,Dubbo默认会将请求转换成K8S标准格式,结合VirtualService和DestinationRule进行流量治理,此时consumer端可以感知到provider。如果不想使用VirtualService和DestinationRule,请设置providerPort,使consumer端感知provider暴露的服务端口 | 3.1.0以上版本 | -| unloadClusterRelated | unloadClusterRelated | boolean | 可选 | false | Service Mesh | 当dubbo.consumer.meshEnable=true,在Service Mesh模式下,设置为true,可在当前调用中卸载与Cluster相关的Directory、Router和Load Balance,将重试、负载平衡、超时和其他流量管理功能下放至Sidecar,使用VirtualService和DestinationRule进行流量治理 | 3.1.0以上版本 | -| parameters | 无 | Map | 可选 | | 服务治理 | 扩展预留,可扩展定义任意参数,所有扩展参数都将原样反映在 URL 配置上 | 2.0.0以上版本 | -| providedBy | provided-by | string | 可选 | | Service Mesh | 当dubbo.consumer.meshEnable=true,Dubbo默认会将请求转换成K8S标准格式,结合VirtualService和DestinationRule进行流量治理,此时consumer端可以感知到provider。该值应当与声明的`k8s service`一致 | 3.1.0以上版本 | -| providerNamespace | provider-namespace | string | 可选 | | Service Mesh | 当dubbo.consumer.meshEnable=true,Dubbo默认会将请求转换成K8S标准格式,结合VirtualService和DestinationRule进行流量治理,此时consumer端可以感知到provider。请设置providerNamespace,使consumer端按照此配置寻址provider dns,默认`default` | 3.1.2以上版本 | - - -### registry - -注册中心配置。 - -> 对应的配置类: `org.apache.dubbo.config.RegistryConfig`。同时如果有多个不同的注册中心,可以声明多个 `` 标签,并在 `` 或 `` 的 `registry` 属性指定使用的注册中心。 - -| 属性 | 对应URL参数 | 类型 | 是否必填 | 缺省值 | 作用 | 描述 | 兼容性 | -| --- | --- | ---- | --- | --- | --- | --- | --- | -| id | | string | 可选 | | 配置关联 | 注册中心引用BeanId,可以在<dubbo:service registry="">或<dubbo:reference registry="">中引用此ID | 1.0.16以上版本 | -| address | <host:port> | string | 必填 | | 服务发现 | 注册中心服务器地址,如果地址没有端口缺省为9090,同一集群内的多个地址用逗号分隔,如:ip:port,ip:port,不同集群的注册中心,请配置多个<dubbo:registry>标签 | 1.0.16以上版本 | -| protocol | <protocol> | string | 可选 | dubbo | 服务发现 | 注册中心地址协议,支持`dubbo`, `multicast`, `zookeeper`, `redis`, `consul(2.7.1)`, `sofa(2.7.2)`, `etcd(2.7.2)`, `nacos(2.7.2)`等协议 | 2.0.0以上版本 | -| port | <port> | int | 可选 | 9090 | 服务发现 | 注册中心缺省端口,当address没有带端口时使用此端口做为缺省值 | 2.0.0以上版本 | -| username | <username> | string | 可选 | | 服务治理 | 登录注册中心用户名,如果注册中心不需要验证可不填 | 2.0.0以上版本 | -| password | <password> | string | 可选 | | 服务治理 | 登录注册中心密码,如果注册中心不需要验证可不填 | 2.0.0以上版本 | -| transport | registry.transporter | string | 可选 | netty | 性能调优 | 网络传输方式,可选mina,netty | 2.0.0以上版本 | -| timeout | registry.timeout | int | 可选 | 5000 | 性能调优 | 注册中心请求超时时间(毫秒) | 2.0.0以上版本 | -| session | registry.session | int | 可选 | 60000 | 性能调优 | 注册中心会话超时时间(毫秒),用于检测提供者非正常断线后的脏数据,比如用心跳检测的实现,此时间就是心跳间隔,不同注册中心实现不一样。 | 2.1.0以上版本 | -| zone | zone | string | 可选 | | 服务治理 | 注册表所属区域,通常用于流量隔离 | 2.7.5以上版本 -| file | registry.file | string | 可选 | | 服务治理 | 使用文件缓存注册中心地址列表及服务提供者列表,应用重启时将基于此文件恢复,注意:两个注册中心不能使用同一文件存储 | 2.0.0以上版本 | -| wait | registry.wait | int | 可选 | 0 | 性能调优 | 停止时等待通知完成时间(毫秒) | 2.0.0以上版本 | -| check | check | boolean | 可选 | true | 服务治理 | 注册中心不存在时,是否报错 | 2.0.0以上版本 | -| register | register | boolean | 可选 | true | 服务治理 | 是否向此注册中心注册服务,如果设为false,将只订阅,不注册 | 2.0.5以上版本 | -| subscribe | subscribe | boolean | 可选 | true | 服务治理 | 是否向此注册中心订阅服务,如果设为false,将只注册,不订阅 | 2.0.5以上版本 | -| dynamic | dynamic | boolean | 可选 | true | 服务治理 | 服务是否动态注册,如果设为false,注册后将显示为disable状态,需人工启用,并且服务提供者停止时,也不会自动取消注册,需人工禁用。 | 2.0.5以上版本 | -| group | group | string | 可选 | dubbo | 服务治理 | 服务注册分组,跨组的服务不会相互影响,也无法相互调用,适用于环境隔离。 | 2.0.5以上版本 | -| version | version | string | 可选 | | 服务发现 | 服务版本 | 1.0.0以上版本 | -| simplified | simplified | boolean | 可选 | false | 服务治理 | 注册到注册中心的URL是否采用精简模式的(与低版本兼容) | 2.7.0以上版本 | -| extra-keys | extraKeys | string | 可选 | | 服务治理 | 在simplified=true时,extraKeys允许你在默认参数外将额外的key放到URL中,格式:"interface,key1,key2"。 | 2.7.0以上版本 | -| useAsConfigCenter | | boolean | 可选 | | 服务治理 | 该注册中心是否作为配置中心使用 | 2.7.5以上版本 | -| useAsMetadataCenter | | boolean | 可选 | | 服务治理 | 该注册中心是否作为元数据中心使用 | 2.7.5以上版本 | -| accepts | accepts | string | 可选 | | 服务治理 | 该注册中心接收rpc协议列表,多协议用逗号隔开,例如dubbo,rest | 2.7.5以上版本 | -| preferred | preferred | boolean | 可选 | | 服务治理 | 是否作为首选注册中心。当订阅多注册中心时,如果设为true,该注册中心作为首选 | 2.7.5以上版本 | -| weight | weight | int | 可选 | | 性能调优 | 注册流量权重。使用多注册中心时,可通过该值调整注册流量的分布,当设置首选注册中心时该值不生效 | 2.7.5以上版本 | -| registerMode | register-mode | string | 可选 | all | 服务治理 | 控制地址注册行为,应用级服务发现迁移用。
* instance 只注册应用级地址;
* interface 只注册接口级地址;
* all(默认) 同时注册应用级和接口级地址; | 3.0.0以上版本 | -| enableEmptyProtection | enable-empty-protection | boolean | 可选 | true | 服务治理 | 是否全局启用消费端的空地址列表保护,开启后注册中心的空地址推送将被忽略,默认 true | 3.0.0以上版本 | -| parameters | 无 | Map | 可选 | | 服务治理 | 扩展预留,可扩展定义任意参数,所有扩展参数都将原样反映在 URL 配置上 | 2.0.0以上版本 | - -### config-center - -配置中心。 - -> 对应的配置类:`org.apache.dubbo.config.ConfigCenterConfig` - -| 属性 | 对应URL参数 | 类型 | 是否必填 | 缺省值 | 描述 | 兼容性 | -| ---------------- | ---------------------- | ------------------- | -------- | ---------------- | ------------------------------------------------------------ | ------ | -| protocol | protocol | string | 可选 | zookeeper | 使用哪个配置中心:apollo、zookeeper、nacos等。
以zookeeper为例
1. 指定protocol,则address可以简化为`127.0.0.1:2181`;
2. 不指定protocol,则address取值为`zookeeper://127.0.0.1:2181` | 2.7.0以上版本 | -| address | address | string | 必填 | | 配置中心地址。
取值参见protocol说明 | 2.7.0以上版本 | -| highestPriority | highest-priority| boolean | 可选 | true | 来自配置中心的配置项具有最高优先级,即会覆盖本地配置项。 | 2.7.0以上版本 | -| namespace | namespace | string | 可选 | dubbo | 通常用于多租户隔离,实际含义视具体配置中心而不同。
如:
zookeeper - 环境隔离,默认值`dubbo`;
apollo - 区分不同领域的配置集合,默认使用`dubbo`和`application` | 2.7.0以上版本 | -| cluster | cluster | string | 可选 | | 含义视所选定的配置中心而不同。
如Apollo中用来区分不同的配置集群 | 2.7.0以上版本 | -| group | group | string | 可选 | dubbo | 含义视所选定的配置中心而不同。
nacos - 隔离不同配置集
zookeeper - 隔离不同配置集 | 2.7.0以上版本 | -| check | check | boolean | 可选 | true | 当配置中心连接失败时,是否终止应用启动。 | 2.7.0以上版本 | -| configFile | config-file | string | 可选 | dubbo.properties | 全局级配置文件所映射到的key
zookeeper - 默认路径/dubbo/config/dubbo/dubbo.properties
apollo - dubbo namespace中的dubbo.properties键 | 2.7.0以上版本 | -| appConfigFile | app-config-file | string | 可选 | | “configFile”是全局级共享的。此项仅限于此应用程序配置的属性 | 2.7.0以上版本 | -| timeout | timeout | int | 可选 | 3000ms | 获取配置的超时时间 | 2.7.0以上版本 | -| username | username | string | 可选 | | 如果配置中心需要做校验,用户名
Apollo暂未启用 | 2.7.0以上版本 | -| password | password | string | 可选 | | 如果配置中心需要做校验,密码
Apollo暂未启用 | 2.7.0以上版本 | -| parameters | parameters | Map | 可选 | | 扩展参数,用来支持不同配置中心的定制化配置参数 | 2.7.0以上版本 | -| includeSpringEnv |include-spring-env| boolean | 可选 | false | 使用Spring框架时支持,为true时,会自动从Spring Environment中读取配置。
默认依次读取
key为dubbo.properties的配置
key为dubbo.properties的PropertySource | 2.7.0以上版本 | - -### metadata-report-config - -元数据中心。 - -> 对应的配置类:`org.apache.dubbo.config.MetadataReportConfig` - -| 属性 | 对应URL参数 | 类型 | 是否必填 | 缺省值 | 描述 | 兼容性 | -| --------------- | --------- | ------ | -------- | --------- | ------------------------------------------------------------ | ------ | -| address | address | string | 必填 | | 元数据中心地址。 | 2.7.0以上版本 | -| protocol | protocol | string | 可选 | zookeeper | 元数据中心协议:zookeeper、nacos、redis等。
以zookeeper为例
1. 指定protocol,则address可以简化为`127.0.0.1:2181`;
2. 不指定protocol,则address取值为`zookeeper://127.0.0.1:2181` | 2.7.13以上版本 | -| port | port | int | 可选 | | 元数据中心端口号。指定port,则address可简化,不用配置端口号 | 2.7.13以上版本 | -| username | username | string | 可选 | | 元数据中心需要做校验,用户名
Apollo暂未启用 | 2.7.0以上版本 | -| password | password | string | 可选 | | 元数据中心需要做校验,密码
Apollo暂未启用 | 2.7.0以上版本 | -| timeout | timeout | int | 可选 | | 获取元数据超时时间(ms) | 2.7.0以上版本 | -| group | group | string | 可选 | dubbo | 元数据分组,适用于环境隔离。与注册中心group意义相同 | 2.7.0以上版本 | -| retryTimes | retry-times| int | 可选 | 100 | 重试次数 | 2.7.0以上版本 | -| retryPeriod | retry-period | int | 可选 | 3000ms | 重试间隔时间(ms) | 2.7.0以上版本 | -| cycleReport | cycle-report | boolean| 可选 | true | 是否每天更新完整元数据 | 2.7.0以上版本 | -| syncReport | sync-report | boolean| 可选 | false | 是否同步更新元数据,默认为异步 | 2.7.0以上版本 | -| cluster | cluster | string | 可选 | | 含义视所选定的元数据中心而不同。
如Apollo中用来区分不同的配置集群 | 2.7.0以上版本 | -| file | file | string | 可选 | | 使用文件缓存元数据中心列表,应用重启时将基于此文件恢复,注意:两个元数据中心不能使用同一文件存储 | 2.7.0以上版本 | -| check | check | boolean | 可选 | true | 当元数据中心连接失败时,是否终止应用启动。 | 3.0.0以上版本 | -| reportMetadata | report-metadata | boolean | 可选 | false | 是否上报地址发现中的接口配置报元数据,`dubbo.application.metadata-type=remote` 该配置不起作用即一定会上报,`dubbo.application.metadata-type=local` 时是否上报由该配置值决定 | 3.0.0以上版本 | -| reportDefinition | report-definition | boolean | 可选 | true | 是否上报服务运维用元数据 | 3.0.0以上版本 | -| reportConsumerDefinition | report-consumer-definition | boolean | 可选 | true | 是否在消费端上报服务运维用元数据 | 3.0.0以上版本 | -| parameters | parameters | Map | 可选 | | 扩展参数,用来支持不同元数据中心的定制化配置参数 | 2.7.0以上版本 | - -### protocol - -服务提供者协议配置。 - -> 对应的配置类: `org.apache.dubbo.config.ProtocolConfig`。同时,如果需要支持多协议,可以声明多个 `` 标签,并在 `` 中通过 `protocol` 属性指定使用的协议。 - -| 属性 | 对应URL参数 | 类型 | 是否必填 | 缺省值 | 作用 | 描述 | 兼容性 | -| --- | --- | ---- | --- | --- | --- | --- | --- | -| id | | string | 可选 | dubbo | 配置关联 | 协议BeanId,可以在<dubbo:service protocol="">中引用此ID,如果ID不填,缺省和name属性值一样,重复则在name后加序号。 | 2.0.5以上版本 | -| name | <protocol> | string | 必填 | dubbo | 性能调优 | 协议名称 | 2.0.5以上版本 | -| port | <port> | int | 可选 | dubbo协议缺省端口为20880,rmi协议缺省端口为1099,http和hessian协议缺省端口为80;如果没有配置port,则自动采用默认端口,如果配置为-1,则会分配一个没有被占用的端口。Dubbo 2.4.0+,分配的端口在协议缺省端口的基础上增长,确保端口段可控。 | 服务发现 | 服务端口 | 2.0.5以上版本 | -| host | <host> | string | 可选 | 自动查找本机IP | 服务发现 | -服务主机名,多网卡选择或指定VIP及域名时使用,为空则自动查找本机IP,-建议不要配置,让Dubbo自动获取本机IP | 2.0.5以上版本 | -| threadpool | threadpool | string | 可选 | fixed | 性能调优 | 线程池类型,可选:fixed/cached/limit(2.5.3以上)/eager(2.6.x以上) | 2.0.5以上版本 | -| threadname | threadname | string | 可选 | | 性能调优 | 线程池名称 | 2.7.6以上版本 | -| threads | threads | int | 可选 | 200 | 性能调优 | 服务线程池大小(固定大小) | 2.0.5以上版本 | -| corethreads | corethreads | int | 可选 | 200 | 性能调优 | 线程池核心线程大小 | 2.0.5以上版本 | -| iothreads | threads | int | 可选 | cpu个数+1 | 性能调优 | io线程池大小(固定大小) | 2.0.5以上版本 | -| accepts | accepts | int | 可选 | 0 | 性能调优 | 服务提供方最大可接受连接数 | 2.0.5以上版本 | -| payload | payload | int | 可选 | 8388608(=8M) | 性能调优 | 请求及响应数据包大小限制,单位:字节 | 2.0.5以上版本 | -| codec | codec | string | 可选 | dubbo | 性能调优 | 协议编码方式 | 2.0.5以上版本 | -| serialization | serialization | string | 可选 | dubbo协议缺省为hessian2,rmi协议缺省为java,http协议缺省为json | 性能调优 | 协议序列化方式,当协议支持多种序列化方式时使用,比如:dubbo协议的dubbo,hessian2,java,compactedjava,以及http协议的json等 | 2.0.5以上版本 | -| accesslog | accesslog | string/boolean | 可选 | | 服务治理 | 设为true,将向logger中输出访问日志,也可填写访问日志文件路径,直接把访问日志输出到指定文件 | 2.0.5以上版本 | -| path | <path> | string | 可选 | | 服务发现 | 提供者上下文路径,为服务path的前缀 | 2.0.5以上版本 | -| transporter | transporter | string | 可选 | dubbo协议缺省为netty | 性能调优 | 协议的服务端和客户端实现类型,比如:dubbo协议的mina,netty等,可以分拆为server和client配置 | 2.0.5以上版本 | -| server | server | string | 可选 | dubbo协议缺省为netty,http协议缺省为servlet | 性能调优 | 协议的服务器端实现类型,比如:dubbo协议的mina,netty等,http协议的jetty,servlet等 | 2.0.5以上版本 | -| client | client | string | 可选 | dubbo协议缺省为netty | 性能调优 | 协议的客户端实现类型,比如:dubbo协议的mina,netty等 | 2.0.5以上版本 | -| dispatcher | dispatcher | string | 可选 | dubbo协议缺省为all | 性能调优 | 协议的消息派发方式,用于指定线程模型,比如:dubbo协议的all, direct, message, execution, connection等 | 2.1.0以上版本 | -| queues | queues | int | 可选 | 0 | 性能调优 | 线程池队列大小,当线程池满时,排队等待执行的队列大小,建议不要设置,当线程池满时应立即失败,重试其它服务提供机器,而不是排队,除非有特殊需求。 | 2.0.5以上版本 | -| charset | charset | string | 可选 | UTF-8 | 性能调优 | 序列化编码 | 2.0.5以上版本 | -| buffer | buffer | int | 可选 | 8192 | 性能调优 | 网络读写缓冲区大小 | 2.0.5以上版本 | -| heartbeat | heartbeat | int | 可选 | 0 | 性能调优 | 心跳间隔,对于长连接,当物理层断开时,比如拔网线,TCP的FIN消息来不及发送,对方收不到断开事件,此时需要心跳来帮助检查连接是否已断开 | 2.0.10以上版本 | -| telnet | telnet | string | 可选 | | 服务治理 | 所支持的telnet命令,多个命令用逗号分隔 | 2.0.5以上版本 | -| register | register | boolean | 可选 | true | 服务治理 | 该协议的服务是否注册到注册中心 | 2.0.8以上版本 | -| contextpath | contextpath | String | 可选 | 缺省为空串 | 服务治理 | 上下文路径 | 2.0.6以上版本 | -| sslEnabled | ssl-enabled | boolean | 可选 | false | 服务治理 | 是否启用ssl | 2.7.5以上版本 | -| parameters | parameters | Map | 可选 | | 扩展参数 | 2.0.0以上版本 | - -### provider - -服务提供者缺省值配置。 - -> 对应的配置类: `org.apache.dubbo.config.ProviderConfig`。同时该标签为 `` 和 `` 标签的缺省值设置。 - -| 属性 | 对应URL参数 | 类型 | 是否必填 | 缺省值 | 作用 | 描述 | 兼容性 | -| --- | --- | ---- | --- | --- | --- | --- | --- | -| id | | string | 可选 | dubbo | 配置关联 | 协议BeanId,可以在<dubbo:service proivder="">中引用此ID | 1.0.16以上版本 | -| protocol | <protocol> | string | 可选 | dubbo | 性能调优 | 协议名称 | 1.0.16以上版本 | -| host | <host> | string | 可选 | 自动查找本机IP | 服务发现 | 服务主机名,多网卡选择或指定VIP及域名时使用,为空则自动查找本机IP,建议不要配置,让Dubbo自动获取本机IP | 1.0.16以上版本 | -| threads | threads | int | 可选 | 200 | 性能调优 | 服务线程池大小(固定大小) | 1.0.16以上版本 | -| payload | payload | int | 可选 | 8388608(=8M) | 性能调优 | 请求及响应数据包大小限制,单位:字节 | 2.0.0以上版本 | -| path | <path> | string | 可选 | | 服务发现 | 提供者上下文路径,为服务path的前缀 | 2.0.0以上版本 | -| transporter | transporter | string | 可选 | dubbo协议缺省为netty | 性能调优 | 协议的服务端和客户端实现类型,比如:dubbo协议的mina,netty等,可以分拆为server和client配置 | 2.0.5以上版本 | -| server | server | string | 可选 | dubbo协议缺省为netty,http协议缺省为servlet | 性能调优 | 协议的服务器端实现类型,比如:dubbo协议的mina,netty等,http协议的jetty,servlet等 | 2.0.0以上版本 | -| client | client | string | 可选 | dubbo协议缺省为netty | 性能调优 | 协议的客户端实现类型,比如:dubbo协议的mina,netty等 | 2.0.0以上版本 | -| dispatcher | dispatcher | string | 可选 | dubbo协议缺省为all | 性能调优 | 协议的消息派发方式,用于指定线程模型,比如:dubbo协议的all, direct, message, execution, connection等 | 2.1.0以上版本 | -| codec | codec | string | 可选 | dubbo | 性能调优 | 协议编码方式 | 2.0.0以上版本 | -| serialization | serialization | string | 可选 | dubbo协议缺省为hessian2,rmi协议缺省为java,http协议缺省为json | 性能调优 | 协议序列化方式,当协议支持多种序列化方式时使用,比如:dubbo协议的dubbo,hessian2,java,compactedjava,以及http协议的json,xml等 | 2.0.5以上版本 | -| default | | boolean | 可选 | false | 配置关联 | 是否为缺省协议,用于多协议 | 1.0.16以上版本 | -| filter | service.filter | string | 可选 | | 性能调优 | 服务提供方远程调用过程拦截器名称,多个名称用逗号分隔 | 2.0.5以上版本 | -| listener | exporter.listener | string | 可选 | | 性能调优 | 服务提供方导出服务监听器名称,多个名称用逗号分隔 | 2.0.5以上版本 | -| threadpool | threadpool | string | 可选 | fixed | 性能调优 | 线程池类型,可选:fixed/cached/limit(2.5.3以上)/eager(2.6.x以上) | 2.0.5以上版本 | -| threadname | threadname | string | 可选 | | 性能调优 | 线程池名称 | 2.7.6以上版本 | -| accepts | accepts | int | 可选 | 0 | 性能调优 | 服务提供者最大可接受连接数 | 2.0.5以上版本 | -| version | version | string | 可选 | 0.0.0 | 服务发现 | 服务版本,建议使用两位数字版本,如:1.0,通常在接口不兼容时版本号才需要升级 | 2.0.5以上版本 | -| group | group | string | 可选 | | 服务发现 | 服务分组,当一个接口有多个实现,可以用分组区分 | 2.0.5以上版本 | -| delay | delay | int | 可选 | 0 | 性能调优 | 延迟注册服务时间(毫秒)- ,设为-1时,表示延迟到Spring容器初始化完成时暴露服务 | 2.0.5以上版本 | -| timeout | default.timeout | int | 可选 | 1000 | 性能调优 | 远程服务调用超时时间(毫秒) | 2.0.5以上版本 | -| retries | default.retries | int | 可选 | 2 | 性能调优 | 远程服务调用重试次数,不包括第一次调用,不需要重试请设为0 | 2.0.5以上版本 | -| connections | default.connections | int | 可选 | 0 | 性能调优 | 对每个提供者的最大连接数,rmi、http、hessian等短连接协议表示限制连接数,dubbo等长连接协表示建立的长连接个数 | 2.0.5以上版本 | -| loadbalance | default.loadbalance | string | 可选 | random | 性能调优 | 负载均衡策略,可选值:
* random - 随机;
* roundrobin - 轮询;
* leastactive - 最少活跃调用;
* consistenthash - 哈希一致 (2.1.0以上版本);
* shortestresponse - 最短响应 (2.7.7以上版本); | 2.0.5以上版本 | -| async | default.async | boolean | 可选 | false | 性能调优 | 是否缺省异步执行,不可靠异步,只是忽略返回值,不阻塞执行线程 | 2.0.5以上版本 | -| stub | stub | boolean | 可选 | false | 服务治理 | 设为true,表示使用缺省代理类名,即:接口名 + Local后缀。 | 2.0.5以上版本 | -| mock | mock | boolean | 可选 | false | 服务治理 | 设为true,表示使用缺省Mock类名,即:接口名 + Mock后缀。 | 2.0.5以上版本 | -| token | token | boolean | 可选 | | 服务治理 | 令牌验证,为空表示不开启,如果为true,表示随机生成动态令牌 | 2.0.5以上版本 | -| registry | registry | string | 可选 | 缺省向所有registry注册 | 配置关联 | 向指定注册中心注册,在多个注册中心时使用,值为<dubbo:registry>的id属性,多个注册中心ID用逗号分隔,如果不想将该服务注册到任何registry,可将值设为N/A | 2.0.5以上版本 | -| dynamic | dynamic | boolean | 可选 | true | 服务治理 | 服务是否动态注册,如果设为false,注册后将显示后disable状态,需人工启用,并且服务提供者停止时,也不会自动取消册,需人工禁用。 | 2.0.5以上版本 | -| accesslog | accesslog | string/boolean | 可选 | false | 服务治理 | 设为true,将向logger中输出访问日志,也可填写访问日志文件路径,直接把访问日志输出到指定文件 | 2.0.5以上版本 | -| owner | owner | string | 可选 | | 服务治理 | 服务负责人,用于服务治理,请填写负责人公司邮箱前缀 | 2.0.5以上版本 | -| document | document | string | 可选 | | 服务治理 | 服务文档URL | 2.0.5以上版本 | -| weight | weight | int | 可选 | | 性能调优 | 服务权重 | 2.0.5以上版本 | -| executes | executes | int | 可选 | 0 | 性能调优 | 服务提供者每服务每方法最大可并行执行请求数 | 2.0.5以上版本 | -| actives | default.actives | int | 可选 | 0 | 性能调优 | 每服务消费者每服务每方法最大并发调用数 | 2.0.5以上版本 | -| proxy | proxy | string | 可选 | javassist | 性能调优 | 生成动态代理方式,可选:jdk/javassist | 2.0.5以上版本 | -| cluster | default.cluster | string | 可选 | failover | 性能调优 | 集群方式,可选:failover/failfast/failsafe/failback/forking | 2.0.5以上版本 | -| deprecated | deprecated | boolean | 可选 | false | 服务治理 | 服务是否过时,如果设为true,消费方引用时将打印服务过时警告error日志 | 2.0.5以上版本 | -| queues | queues | int | 可选 | 0 | 性能调优 | 线程池队列大小,当线程池满时,排队等待执行的队列大小,建议不要设置,当线程池满时应立即失败,重试其它服务提供机器,而不是排队,除非有特殊需求。 | 2.0.5以上版本 | -| charset | charset | string | 可选 | UTF-8 | 性能调优 | 序列化编码 | 2.0.5以上版本 | -| buffer | buffer | int | 可选 | 8192 | 性能调优 | 网络读写缓冲区大小 | 2.0.5以上版本 | -| iothreads | iothreads | int | 可选 | CPU + 1 | 性能调优 | IO线程池,接收网络读写中断,以及序列化和反序列化,不处理业务,业务线程池参见threads配置,此线程池和CPU相关,不建议配置。 | 2.0.5以上版本 | -| alive | alive | int | 可选 | | 服务治理 | 线程池keepAliveTime,默认单位为ms | 2.0.5以上版本 | -| telnet | telnet | string | 可选 | | 服务治理 | 所支持的telnet命令,多个命令用逗号分隔 | 2.0.5以上版本 | -| wait | wait | int | 可选 | | 服务治理 | 停服务时等待时间 | 2.0.5以上版本 | -| contextpath | contextpath | String | 可选 | 缺省为空串 | 服务治理 | 上下文路径 | 2.0.6以上版本 | -| layer | layer | string | 可选 | | 服务治理 | 服务提供者所在的分层。如:biz、dao、intl:web、china:acton。 | 2.0.7以上版本 | -| parameters | parameters | Map | 可选 | | 服务治理 | 扩展参数 | 2.0.0以上版本 | - -### consumer - -服务消费者缺省值配置。 - -> 配置类: `org.apache.dubbo.config.ConsumerConfig` 。同时该标签为 `` 标签的缺省值设置。 - -| 属性 | 对应URL参数 | 类型 | 是否必填 | 缺省值 | 作用 | 描述 | 兼容性 | -| --- | --- | ---- | --- | --- | --- | --- | --- | -| timeout | default.timeout | int | 可选 | 1000 | 性能调优 | 远程服务调用超时时间(毫秒) | 1.0.16以上版本 | -| retries | default.retries | int | 可选 | 2 | 性能调优 | 远程服务调用重试次数,不包括第一次调用,不需要重试请设为0,仅在cluster为failback/failover时有效 | 1.0.16以上版本 | -| loadbalance | default.loadbalance | string | 可选 | random | 性能调优 | 负载均衡策略,可选值:
* random - 随机;
* roundrobin - 轮询;
* leastactive - 最少活跃调用;
* consistenthash - 哈希一致 (2.1.0以上版本);
* shortestresponse - 最短响应 (2.7.7以上版本); | 1.0.16以上版本 | -| async | default.async | boolean | 可选 | false | 性能调优 | 是否缺省异步执行,不可靠异步,只是忽略返回值,不阻塞执行线程 | 2.0.0以上版本 | -| sent | default.sent | boolean | 可选 | true | 服务治理 | 异步调用时,标记sent=true时,表示网络已发出数据 | 2.0.6以上版本 | -| connections | default.connections | int | 可选 | 100 | 性能调优 | 每个服务对每个提供者的最大连接数,rmi、http、hessian等短连接协议支持此配置,dubbo协议长连接不支持此配置 | 1.0.16以上版本 | -| generic | generic | boolean | 可选 | false | 服务治理 | 是否缺省泛化接口,如果为泛化接口,将返回GenericService | 2.0.0以上版本 | -| check | check | boolean | 可选 | true | 服务治理 | 启动时检查提供者是否存在,true报错,false忽略 | 1.0.16以上版本 | -| proxy | proxy | string | 可选 | javassist | 性能调优 | 生成动态代理方式,可选:jdk/javassist | 2.0.5以上版本 | -| owner | owner | string | 可选 | | 服务治理 | 调用服务负责人,用于服务治理,请填写负责人公司邮箱前缀 | 2.0.5以上版本 | -| actives | default.actives | int | 可选 | 0 | 性能调优 | 每服务消费者每服务每方法最大并发调用数 | 2.0.5以上版本 | -| cluster | default.cluster | string | 可选 | failover | 性能调优 | 集群方式,可选:failover/failfast/failsafe/failback/forking/available/mergeable(2.1.0以上版本)/broadcast(2.1.0以上版本)/zone-aware(2.7.5以上版本) | 2.0.5以上版本 | -| filter | reference.filter | string | 可选 | | 性能调优 | 服务消费方远程调用过程拦截器名称,多个名称用逗号分隔 | 2.0.5以上版本 | -| listener | invoker.listener | string | 可选 | | 性能调优 | 服务消费方引用服务监听器名称,多个名称用逗号分隔 | 2.0.5以上版本 | -| registry | | string | 可选 | 缺省向所有registry注册 | 配置关联 | 向指定注册中心注册,在多个注册中心时使用,值为<dubbo:registry>的id属性,多个注册中心ID用逗号分隔,如果不想将该服务注册到任何registry,可将值设为N/A | 2.0.5以上版本 | -| layer | layer | string | 可选 | | 服务治理 | 服务调用者所在的分层。如:biz、dao、intl:web、china:acton。 | 2.0.7以上版本 | -| init | init | boolean | 可选 | false | 性能调优 | 是否在afterPropertiesSet()时饥饿初始化引用,否则等到有人注入或引用该实例时再初始化。 | 2.0.10以上版本 | -| cache | cache | string/boolean | 可选 | | 服务治理 | 以调用参数为key,缓存返回结果,可选:lru, threadlocal, jcache等 | 2.1.0及其以上版本支持 | -| validation | validation | boolean | 可选 | | 服务治理 | 是否启用JSR303标准注解验证,如果启用,将对方法参数上的注解进行校验 | 2.1.0及其以上版本支持 | -| version | version | string | 可选 | | 服务治理 | 在 Dubbo 中为同一个服务配置多个版本 | 2.2.0及其以上版本支持 | -| client | client | string | 可选 | dubbo协议缺省为netty | 性能调优 | 协议的客户端实现类型,比如:dubbo协议的mina,netty等 | 2.0.0以上版本 | -| threadpool | threadpool | string | 可选 | fixed | 性能调优 | 线程池类型,可选:fixed/cached/limit(2.5.3以上)/eager(2.6.x以上) | 2.0.5以上版本 | -| corethreads | corethreads | int | 可选 | 200 | 性能调优 | 线程池核心线程大小 | 2.0.5以上版本 | -| threads | threads | int | 可选 | 200 | 性能调优 | 服务线程池大小(固定大小) | 2.0.5以上版本 | -| queues | queues | int | 可选 | 0 | 性能调优 | 线程池队列大小,当线程池满时,排队等待执行的队列大小,建议不要设置,当线程池满时应立即失败,重试其它服务提供机器,而不是排队,除非有特殊需求。 | 2.0.5以上版本 | -| shareconnections | shareconnections | int | 可选 | 1 | 性能调优| 共享连接数。当connection参数设置为0时,会启用共享方式连接,默认只有一个连接。仅支持dubbo协议 | 2.7.0以上版本 | -| referThreadNum | | int | 可选 | | 性能优化 | 异步调用线程池大小 | 3.0.0以上版本 | -| meshEnable | mesh-enable| boolean | 可选 | false | Service Mesh | Dubbo Mesh模式的开关。开启后,可适配SideCar模式,将Dubbo服务调用转换为K8S标准调用。仅支持Triple协议,兼容GRPC。设置为true后,原生对接K8S,无需第三方注册中心,设置dubbo.registry.address=N/A即可 | 3.1.0以上版本 | -| parameters | parameters | Map | 可选 | | 服务治理 | 扩展参数 | 2.0.0以上版本 | - -### metrics - -指标配置。 - -> 配置类: `org.apache.dubbo.config.MetricsConfig` - -| 属性 | 对应URL参数 | 类型 | 是否必填 | 缺省值 | 作用 | 描述 | 兼容性 | -| --- | --- | ---- | --- | --- | --- | --- | --- | -| protocol | protocol | string | 可选 | prometheus | 性能调优 | 协议名称,默认使用prometheus | 3.0.0以上版本 | -| prometheus | | PrometheusConfig | 可选 | | 配置关联 | prometheus相关配置 | 3.0.0以上版本 | -| aggregation | | AggregationConfig | 可选 | | 配置关联 | 指标聚合相关配置 | 3.0.0以上版本 | - -- PrometheusConfig 对应类:`org.apache.dubbo.config.nested.PrometheusConfig` - -| 属性 | 类型 | 是否必填 | 缺省值 | 描述 | -| --- | --- | ---- | --- | --- | -| exporter.enabled | boolean | 可选 | | 是否启用prometheus exporter | -| exporter.enableHttpServiceDiscovery | boolean | 可选 | | 是否启用http服务发现 | -| exporter.httpServiceDiscoveryUrl | string | 可选 | | http服务发现地址 | -| exporter.metricsPort | int | 可选 | | 当使用pull方法时,暴露的端口号 | -| exporter.metricsPath | string | 可选 | | 当使用pull方法时,暴露指标的路径 | -| pushgateway.enabled | boolean | 可选 | | 是否可以通过prometheus的Pushgateway发布指标 | -| pushgateway.baseUrl | string | 可选 | | Pushgateway地址 | -| pushgateway.username | string | 可选 | | Pushgateway用户名 | -| pushgateway.password | string | 可选 | | Pushgateway密码 | -| pushgateway.pushInterval | int | 可选 | | 推送指标间隔时间 | - -- AggregationConfig 对应类:`org.apache.dubbo.config.nested.AggregationConfig` - -| 属性 | 类型 | 是否必填 | 缺省值 | 描述 | -| --- | --- | ---- | --- | --- | -| enabled | boolean | 可选 | | 是否开启本地指标聚合功能 | -| bucketNum | int | 可选 | | 时间窗口存储桶个数 | -| timeWindowSeconds | int | 可选 | | 时间窗口时长(s) | - -### tracing - -指标配置。 - -> 配置类: `org.apache.dubbo.config.TracingConfig` - -| 属性 | 对应URL参数 | 类型 | 是否必填 | 缺省值 | 作用 | 描述 | 兼容性 | -| --- | --- | ---- | --- | --- | --- | --- | --- | -| enabled | | boolean | 可选 | false | 服务治理 | 是否开启tracing相关功能 | 3.2.3以上版本 | -| sampling | | SamplingConfig | 可选 | | 性能调优 | tracing 采样相关配置 | 3.2.3以上版本 | -| propagation | | PropagationConfig | 可选 | | 服务治理 | tracing 传播协议相关配置 | 3.2.3以上版本 | -| tracingExporter | | ExporterConfig | 可选 | | 服务治理 | tracing 信息导出相关配置 | 3.2.3以上版本 | - -- SamplingConfig 对应类:`org.apache.dubbo.config.nested.SamplingConfig` - -| 属性 | 类型 | 是否必填 | 缺省值 | 描述 | -| --- | --- | ---- | --- | --- | -| probability | float | 可选 | 0.1 | 采样率 | - -- PropagationConfig 对应类:`org.apache.dubbo.config.nested.PropagationConfig` - -| 属性 | 类型 | 是否必填 | 缺省值 | 描述 | -| --- | --- | ---- | --- | --- | -| type | string | 可选 | W3C | 可选 B3/W3C | - -- ExporterConfig 对应类:`org.apache.dubbo.config.nested.ExporterConfig` - -| 属性 | 类型 | 是否必填 | 缺省值 | 描述 | -| --- | --- | ---- | --- | --- | -| zipkinConfig | ZipkinConfig | 可选 | | zipkin 作为 exporter 的配置信息 | -| otlpConfig | OtlpConfig | 可选 | | OTlp Colletcor 作为exporter的配置信息 | - -- ZipkinConfig 对应类:`org.apache.dubbo.config.nested.ExporterConfig.ZipkinConfig` - -| 属性 | 类型 | 是否必填 | 缺省值 | 描述 | -| --- | --- | ---- | --- | --- | -| endpoint | string | 可选 | | zipkin server 地址 | -| connectTimeout | duration | 可选 | 10s | 连接到 zipkin server 的超时时间 | -| readTimeout | duration | 可选 | 10s | zipkin server 读取超时时间 | - -- OtlpConfig 对应类:`org.apache.dubbo.config.nested.ExporterConfig.OtlpConfig` - -| 属性 | 类型 | 是否必填 | 缺省值 | 描述 | -| --- | --- | ---- | --- | --- | -| endpoint | string | 可选 | | zipkin server 地址 | -| timeout | duration | 可选 | 10s | 等待收集器处理导出的一批 spans 的最大时间 | -| compressionMethod | string | 可选 | none | 用于传输中压缩 tracing 信息的方法,支持 gzip/none | -| headers | Map | 可选 | | 向 OTlp Collector 上报信息时,添加自定义的 header 头 | - -### ssl - -TLS认证配置。 - -> 配置类: `org.apache.dubbo.config.SslConfig` - -| 属性 | 对应URL参数 | 类型 | 是否必填 | 缺省值 | 作用 | 描述 | 兼容性 | -| --- | --- | ---- | --- | --- | --- | --- | --- | -| serverKeyCertChainPath | server-key-cert-chain-path | string | 可选 | | 安全配置 | 服务端签名证书路径 | 2.7.5以上版本 | -| serverPrivateKeyPath | server-private-key-path | string | 可选 | | 安全配置 | 服务端私钥路径 | 2.7.5以上版本 | -| serverKeyPassword | server-key-password | string | 可选 | | 安全配置 | 服务端密钥密码 | 2.7.5以上版本 | -| serverTrustCertCollectionPath | server-trust-cert-collection-path | string | 可选 | | 安全配置 | 服务端信任证书路径 | 2.7.5以上版本 | -| clientKeyCertChainPath | client-key-cert-chain-path | string | 可选 | | 安全配置 | 客户端签名证书路径 | 2.7.5以上版本 | -| clientPrivateKeyPath | client-private-key-path | string | 可选 | | 安全配置 | 客户端私钥路径 | 2.7.5以上版本 | -| clientKeyPassword | client-key-password | string | 可选 | | 安全配置 | 客户端密钥密码 | 2.7.5以上版本 | -| clientTrustCertCollectionPath | client-trust-cert-collection-path | string | 可选 | | 安全配置 | 客户端信任证书路径 | 2.7.5以上版本 | - -### module - -模块信息配置。 - -> 对应的配置类 `org.apache.dubbo.config.ModuleConfig` - -| 属性 | 对应URL参数 | 类型 | 是否必填 | 缺省值 | 作用 | 描述 | 兼容性 | -| --- | --- | ---- | --- | --- | --- | --- | --- | -| name | module | string | 必填 | | 服务治理 | 当前模块名称,用于注册中心计算模块间依赖关系 | 2.2.0以上版本 | -| version | module.version | string | 可选 | | 服务治理 | 当前模块的版本 | 2.2.0以上版本 | -| owner | module.owner | string | 可选 | | 服务治理 | 模块负责人,用于服务治理,请填写负责人公司邮箱前缀 | 2.2.0以上版本 | -| organization | module.organization | string | 可选 | | 服务治理 | 组织名称(BU或部门),用于注册中心区分服务来源,此配置项建议不要使用autoconfig,直接写死在配置中,比如china,intl,itu,crm,asc,dw,aliexpress等 | 2.2.0以上版本 | -| background | background | boolean | 可选 | | 性能调优 | 是否开启后台启动模式。如果开启,无需等待spring ContextRefreshedEvent事件完成 | 3.0.0以上版本 | -| referAsync | referAsync | boolean | 可选 | | 性能调优 | 消费端是否开启异步调用 | 3.0.0以上版本 | -| referThreadNum | referThreadNum | int | 可选 | | 性能调优 | 异步调用线程池大小 | 3.0.0以上版本 | -| exportAsync | exportAsync | boolean | 可选 | | 性能调优 | 服务端是否开启导出 | 3.0.0以上版本 | -| exportThreadNum | exportThreadNum | int | 可选 | | 异步导出线程池大小 | | 3.0.0以上版本 | - -### monitor - -监控中心配置。 - -> 对应的配置类: `org.apache.dubbo.config.MonitorConfig` - -| 属性 | 对应URL参数 | 类型 | 是否必填 | 缺省值 | 作用 | 描述 | 兼容性 | -| --- | --- | ---- | --- | --- | --- | --- | --- | -| protocol | protocol | string | 可选 | dubbo | 服务治理 | 监控中心协议,如果为protocol="registry",表示从注册中心发现监控中心地址,否则直连监控中心。 | 2.0.9以上版本 | -| address | <url> | string | 可选 | | 服务治理 | 直连监控中心服务器地址,address="10.20.130.230:12080" | 1.0.16以上版本 | -| username | username | string | 可选 | | 服务治理 | 监控中心用户名 | 2.0.9以上版本 | -| password | password | string | 可选 | | 服务治理 | 监控中心密码 | 2.0.9以上版本 | -| group | group | string | 可选 | | 服务治理 | 分组 | 2.0.9以上版本 | -| version | version | string | 可选 | | 服务治理 | 版本号 | 2.0.9以上版本 | -| interval | interval | string | 可选 | | 服务治理 | 间隔时间 | 2.0.9以上版本 | -| parameters | parameters | Map | 可选 | | 自定义参数 | 2.0.0以上版本 | - ### method 方法级配置。 @@ -516,7 +741,7 @@ TLS认证配置。 | name | | string | 必填 | | 标识 | 方法名 | 1.0.8以上版本 | | timeout | <methodName>.timeout | int | 可选 | 缺省为的timeout | 性能调优 | 方法调用超时时间(毫秒) | 1.0.8以上版本 | | retries | <methodName>.retries | int | 可选 | 缺省为<dubbo:reference>的retries | 性能调优 | 远程服务调用重试次数,不包括第一次调用,不需要重试请设为0 | 2.0.0以上版本 | -| loadbalance | <methodName>.loadbalance | string | 可选 | 缺省为的loadbalance | 性能调优 | 负载均衡策略,可选值:
* random - 随机;
* roundrobin - 轮询;
* leastactive - 最少活跃调用;
* consistenthash - 哈希一致 (2.1.0以上版本);
* shortestresponse - 最短响应 (2.7.7以上版本); | 2.0.0以上版本 | +| loadbalance | <methodName>.loadbalance | string | 可选 | 缺省为的loadbalance | 性能调优 | 负载均衡策略,可选值:

* random - 随机;

* roundrobin - 轮询;

* leastactive - 最少活跃调用;

* consistenthash - 哈希一致 (2.1.0以上版本);

* shortestresponse - 最短响应 (2.7.7以上版本); | 2.0.0以上版本 | | async | <methodName>.async | boolean | 可选 | 缺省为<dubbo:reference>的async | 性能调优 | 是否异步执行,不可靠异步,只是忽略返回值,不阻塞执行线程 | 1.0.9以上版本 | | sent | <methodName>.sent | boolean | 可选 | true | 性能调优 | 异步调用时,标记sent=true时,表示网络已发出数据 | 2.0.6以上版本 | | actives | <methodName>.actives | int | 可选 | 0 | 性能调优 | 每服务消费者最大并发调用限制 | 2.0.5以上版本 | @@ -576,72 +801,4 @@ TLS认证配置。 | key | key | string | 必填 | | 服务治理 | 路由参数键 | 2.0.0以上版本 | | value | value | string | 必填 | | 服务治理 | 路由参数值 | 2.0.0以上版本 | -### environment variable -支持的 key 有以下两个: - -1. `dubbo.labels`,指定一些列配置到 URL 中的键值对,通常通过 JVM -D 或系统环境变量指定。 - -增加以下配置: -```properties -# JVM --Ddubbo.labels = "tag1=value1; tag2=value2" - -# 环境变量 -DUBBO_LABELS = "tag1=value1; tag2=value2" -``` - - 最终生成的 URL 会包含 tag1、tag2 两个 key: `dubbo://xxx?tag1=value1&tag2=value2` - -2. `dubbo.env.keys`,指定环境变量 key 值,Dubbo 会尝试从环境变量加载每个 key - -```properties -# JVM --Ddubbo.env.keys = "DUBBO_TAG1, DUBBO_TAG2" - -# 环境变量 -DUBBO_ENV_KEYS = "DUBBO_TAG1, DUBBO_TAG2" -``` - - 最终生成的 URL 会包含 DUBBO_TAG1、DUBBO_TAG2 两个 key: `dubbo://xxx?DUBBO_TAG1=value1&DUBBO_TAG2=value2` - -## 其他配置 -### config-mode -**背景** - -在每个dubbo应用中某些种类的配置类实例只能出现一次(比如`ApplicationConfig`、`MonitorConfig`、`MetricsConfig`、`SslConfig`、`ModuleConfig`),有些能出现多次(比如`RegistryConfig`、`ProtocolConfig`等)。 - -如果应用程序意外的扫描到了多个唯一配置类实例(比如用户在一个dubbo应用中错误了配置了两个`ApplicationConfig`),应该以哪种策略来处理这种情况呢?是直接抛异常?是保留前者忽略后者?是忽略前者保留后者?还是允许某一种形式的并存(比如后者的属性覆盖到前者上)? - -目前dubbo中的唯一配置类类型和以及某唯一配置类型找到多个实例允许的配置模式/策略如下。 - -**唯一配置类类型** - -`ApplicationConfig`、`MonitorConfig`、`MetricsConfig`、`SslConfig`、`ModuleConfig`。 - -前四个属于应用级别的,最后一个属于模块级别的。 - -**配置模式** - -- `strict`:严格模式。直接抛异常。 -- `override`:覆盖模式。忽略前者保留后者。 -- `ignore`:忽略模式。忽略后者保留前者。 -- `override_all`:属性覆盖模式。不管前者的属性值是否为空,都将后者的属性覆盖/设置到前者上。 -- `override_if_absent`:若不存在则属性覆盖模式。只有前者对应属性值为空,才将后者的属性覆盖/设置到前者上。 - -注:后两种还影响配置实例的属性覆盖。因为dubbo有多种配置方式,即存在多个配置源,配置源也有优先级。比如通过xml方式配置了一个`ServiceConfig`且指定属性`version=1.0.0`,同时我们又在外部配置(配置中心)中配置了`dubbo.service.{interface}.version=2.0.0`,在没有引入`config-mode`配置项之前,按照原有的配置源优先级,最终实例的`version=2.0.0`。但是引入了`config-mode`配置项之后,配置优先级规则也不再那么严格,即如果指定`config-mode为override_all`则为`version=2.0.0`,如果`config-mode为override_if_absent`则为`version=1.0.0`,`config-mode`为其他值则遵循原有配置优先级进行属性设值/覆盖。 - -**配置方式** - -配置的key为`dubbo.config.mode`,配置的值为如上描述的几种,默认的策略值为`strict`。下面展示了配置示例 - -```properties -# JVM -D --Ddubbo.config.mode=strict - -# 环境变量 -DUBBO_CONFIG_MODE=strict - -# 外部配置(配置中心)、Spring应用的Environment、dubbo.properties -dubbo.config.mode=strict -``` diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/config/properties3.md.bak b/content/zh-cn/overview/mannual/java-sdk/reference-manual/config/properties3.md.bak new file mode 100644 index 000000000000..dffc97376eb1 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/config/properties3.md.bak @@ -0,0 +1,578 @@ +--- +aliases: + - /zh/docs3-v2/java-sdk/reference-manual/config/properties/ + - /zh-cn/docs3-v2/java-sdk/reference-manual/config/properties/ +description: 包含 Dubbo 支持的所有配置组件及每个配置组件支持的所有配置项 +linkTitle: 配置项手册 +title: 配置项参考手册 +type: docs +weight: 6 +--- + + +## JVM(-D) 参数 + +## 环境变量 + +## 配置项手册 +### application + +每个应用必须要有且只有一个 application 配置 + +> 对应的配置类:`org.apache.dubbo.config.ApplicationConfig` + +| 属性 | 对应URL参数 | 类型 | 是否必填 | 缺省值 | 作用 | 描述 | 兼容性 | +| --- | --- | ---- | --- | --- | --- | --- | --- | +| name | application | string | 必填 | | 服务治理 | 当前应用名称,用于注册中心计算应用间依赖关系,注意:消费者和提供者应用名不要一样,此参数不是匹配条件,你当前项目叫什么名字就填什么,和提供者消费者角色无关,比如:kylin应用调用了morgan应用的服务,则kylin项目配成kylin,morgan项目配成morgan,可能kylin也提供其它服务给别人使用,但kylin项目永远配成kylin,这样注册中心将显示kylin依赖于morgan | 2.7.0以上版本 | +| compiler | compiler | string | 可选 | javassist | 性能优化 | Java字节码编译器,用于动态类的生成,可选:jdk或javassist | 2.7.0以上版本 | +| logger | logger | string | 可选 | slf4j | 性能优化 | 日志输出方式,可选:slf4j,jcl,log4j,log4j2,jdk | 2.7.0以上版本 | +| owner | owner | string | 可选 | | 服务治理 | 应用负责人,用于服务治理,请填写负责人公司邮箱前缀 | 2.0.5以上版本 | +| organization | organization | string | 可选 | | 服务治理 | 组织名称(BU或部门),用于注册中心区分服务来源,此配置项建议不要使用autoconfig,直接写死在配置中,比如china,intl,itu,crm,asc,dw,aliexpress等 | 2.0.0以上版本 | +| architecture
| architecture
| string | 可选 | | 服务治理 | 用于服务分层对应的架构。如,intl、china。不同的架构使用不同的分层。 | 2.0.7以上版本 | +| environment | environment | string | 可选 | | 服务治理 | 应用环境,如:develop/test/product,不同环境使用不同的缺省值,以及作为只用于开发测试功能的限制条件 | 2.0.0以上版本 | +| version | application.version | string | 可选 | | 服务治理 | 当前应用的版本 | 2.7.0以上版本 | +| dumpDirectory | dump.directory | string | 可选 | | 服务治理 | 当进程出问题如线程池满时,框架自动dump文件的存储路径 | 2.7.0以上版本 | +| qosEnable | qos.enable | boolean | 可选 | | 服务治理 | 是否启用 qos 运维端口 | 2.7.0以上版本 | +| qosHost | qos.host | string | 可选 | | 服务治理 | 监听的网络接口地址,默认 0.0.0.0 | 2.7.3以上版本 | +| qosPort | qos.port | int | 可选 | | 服务治理 | 监听的网络端口 | 2.7.0以上版本 | +| qosAcceptForeignIp | qos.accept.foreign.ip | boolean | 可选 | | 服务治理 | 安全配置,是否接收除localhost本机访问之外的外部请求 | 2.7.0以上版本 | +| shutwait | dubbo.service.shutdown.wait | string | 可选 | | 服务治理 | 优雅停机时 shutdown 的等待时间(ms) | 2.7.0以上版本 | +| hostname | | string | 可选 | 本机主机名 | 服务治理 | 主机名 | 2.7.5以上版本 | +| registerConsumer | registerConsumer | boolean | 可选 | true | 服务治理 | 是否注册实例到注册中心。当时实例为纯消费者时才设置为`false` | 2.7.5以上版本 | +| repository | application.version | string | 可选 | | 服务治理 | 当前应用的版本 | 2.7.6以上版本 | +| enableFileCache | file.cache | boolean | 可选 | true | 服务治理 | 是否开启本地缓存 | 3.0.0以上版本 | +| protocol | | string | 可选 | dubbo | 服务治理 | 首选协议,适用于无法确定首选协议的时候 | 3.0.0以上版本 | +| metadataType | metadata-type |String| 可选 | local | 服务治理 | 应用级服务发现 metadata 传递方式,是以 Provider 视角而言的,Consumer 侧配置无效,可选值有:
* remote - Provider 把 metadata 放到远端注册中心,Consumer 从注册中心获取;
* local - Provider 把 metadata 放在本地,Consumer 从 Provider 处直接获取;| 2.7.5以上版本 | +| metadataServiceProtocol | metadata-service-protocol | string | 可选 | dubbo | 服务治理 | 如 metadataType 配置为 local,则该属性设置 MetadataService 服务所用的通信协议,默认为 dubbo| 3.0.0以上版本 | +| metadataServicePort | metadata-service-port | int | 可选 | | 服务治理 | 如 metadataType 配置为 local,则该属性设置 MetadataService 服务所用的端口号| 2.7.9以上版本 | +| livenessProbe | liveness-probe | string | 可选 | | 服务治理 | 概念和格式对应 k8s 体系 liveness probe | 3.0.0以上版本 | +| readinessProbe | readiness-probe | string | 可选 | | 服务治理 | 概念和格式对应 k8s 体系 readiness probe | 3.0.0以上版本 | +| startupProbe | startup-probe | string | 可选 | | 服务治理 | 概念和格式对应 k8s 体系 startup probe | 3.0.0以上版本 | +| registerMode | register-mode | string | 可选 | all | 服务治理 | 控制地址注册行为,应用级服务发现迁移用。
* instance 只注册应用级地址;
* interface 只注册接口级地址;
* all(默认) 同时注册应用级和接口级地址; | 3.0.0以上版本 | +| enableEmptyProtection | enable-empty-protection | boolean | 可选 | true | 服务治理 | 是否全局启用消费端的空地址列表保护,开启后注册中心的空地址推送将被忽略,默认 true | 3.0.0以上版本 | +| parameters | 无 | Map | 可选 | | 服务治理 | 扩展预留,可扩展定义任意参数,所有扩展参数都将原样反映在 URL 配置上 | 2.7.0以上版本 | + + +### service + +服务提供者暴露服务配置。 + +> 对应的配置类:`org.apache.dubbo.config.ServiceConfig` + +| 属性 | 对应URL参数 | 类型 | 是否必填 | 缺省值 | 作用 | 描述 | 兼容性 | +| --- | --- | ---- | --- | --- | --- | --- | --- | +| interface | | class | 必填 | | 服务发现 | 服务接口名 | 1.0.0以上版本 | +| ref | | object | 必填 | | 服务发现 | 服务对象实现引用 | 1.0.0以上版本 | +| version | version | string | 可选 | 0.0.0 | 服务发现 | 服务版本,建议使用两位数字版本,如:1.0,通常在接口不兼容时版本号才需要升级 | 1.0.0以上版本 | +| group | group | string | 可选 | | 服务发现 | 服务分组,当一个接口有多个实现,可以用分组区分 | 1.0.7以上版本 | +| path | <path> | string | 可选 | 缺省为接口名 | 服务发现 | 服务路径 (注意:1.0不支持自定义路径,总是使用接口名,如果有1.0调2.0,配置服务路径可能不兼容) | 1.0.12以上版本 | +| delay | delay | int | 可选 | 0 | 性能调优 | 延迟注册服务时间(毫秒) ,设为-1时,表示延迟到Spring容器初始化完成时暴露服务 | 1.0.14以上版本 | +| timeout | timeout | int | 可选 | 1000 | 性能调优 | 远程服务调用超时时间(毫秒) | 2.0.0以上版本 | +| retries | retries | int | 可选 | 2 | 性能调优 | 远程服务调用重试次数,不包括第一次调用,不需要重试请设为0 | 2.0.0以上版本 | +| connections | connections | int | 可选 | 100 | 性能调优 | 对每个提供者的最大连接数,rmi、http、hessian等短连接协议表示限制连接数,dubbo等长连接协表示建立的长连接个数 | 2.0.0以上版本 | +| loadbalance | loadbalance | string | 可选 | random | 性能调优 | 负载均衡策略,可选值:
* random - 随机;
* roundrobin - 轮询;
* leastactive - 最少活跃调用;
* consistenthash - 哈希一致 (2.1.0以上版本);
* shortestresponse - 最短响应 (2.7.7以上版本);| 2.0.0以上版本 | +| async | async | boolean | 可选 | false | 性能调优 | 是否缺省异步执行,不可靠异步,只是忽略返回值,不阻塞执行线程 | 2.0.0以上版本 | +| local | local | class/boolean | 可选 | false | 服务治理 | 设为true,表示使用缺省代理类名,即:接口名 + Local后缀,已废弃,请使用stub| 2.0.0以上版本 | +| stub | stub | class/boolean | 可选 | false | 服务治理 | 设为true,表示使用缺省代理类名,即:接口名 + Stub后缀,服务接口客户端本地代理类名,用于在客户端执行本地逻辑,如本地缓存等,该本地代理类的构造函数必须允许传入远程代理对象,构造函数如:public XxxServiceStub(XxxService xxxService) | 2.0.0以上版本 | +| mock | mock | class/boolean | 可选 | false | 服务治理 | 设为true,表示使用缺省Mock类名,即:接口名 + Mock后缀,服务接口调用失败Mock实现类,该Mock类必须有一个无参构造函数,与Local的区别在于,Local总是被执行,而Mock只在出现非业务异常(比如超时,网络异常等)时执行,Local在远程调用之前执行,Mock在远程调用后执行。 | 2.0.0以上版本 | +| token | token | string/boolean | 可选 | | 服务治理 | 令牌验证,为空表示不开启,如果为true,表示随机生成动态令牌,否则使用静态令牌,令牌的作用是防止消费者绕过注册中心直接访问,保证注册中心的授权功能有效,如果使用点对点调用,需关闭令牌功能 | 2.0.0以上版本 | +| registry | | string | 可选 | 缺省向所有registry注册 | 配置关联 | 向指定注册中心注册,在多个注册中心时使用,值为<dubbo:registry>的id属性,多个注册中心ID用逗号分隔,如果不想将该服务注册到任何registry,可将值设为N/A | 2.0.0以上版本 | +| provider | | string | 可选 | 缺省使用第一个provider配置 | 配置关联 | 指定provider,值为<dubbo:provider>的id属性 | 2.0.0以上版本 | +| deprecated | deprecated | boolean | 可选 | false | 服务治理 | 服务是否过时,如果设为true,消费方引用时将打印服务过时警告error日志 | 2.0.5以上版本 | +| dynamic | dynamic | boolean | 可选 | true | 服务治理 | 服务是否动态注册,如果设为false,注册后将显示后disable状态,需人工启用,并且服务提供者停止时,也不会自动取消册,需人工禁用。 | 2.0.5以上版本 | +| accesslog | accesslog | string/boolean | 可选 | false | 服务治理 | 设为true,将向logger中输出访问日志,也可填写访问日志文件路径,直接把访问日志输出到指定文件 | 2.0.5以上版本 | +| owner | owner | string | 可选 | | 服务治理 | 服务负责人,用于服务治理,请填写负责人公司邮箱前缀 | 2.0.5以上版本 | +| document | document | string | 可选 | | 服务治理 | 服务文档URL | 2.0.5以上版本 | +| weight | weight | int | 可选 | | 性能调优 | 服务权重 | 2.0.5以上版本 | +| executes | executes | int | 可选 | 0 | 性能调优 | 服务提供者每服务每方法最大可并行执行请求数 | 2.0.5以上版本 | +| actives | actives | int | 可选 | 0 | 性能调优 | 每服务消费者每服务每方法最大并发调用数 | 2.0.5以上版本 | +| proxy | proxy | string | 可选 | javassist | 性能调优 | 生成动态代理方式,可选:jdk/javassist | 2.0.5以上版本 | +| cluster | cluster | string | 可选 | failover | 性能调优 | 集群方式,可选:failover/failfast/failsafe/failback/forking/available/mergeable(2.1.0以上版本)/broadcast(2.1.0以上版本)/zone-aware(2.7.5以上版本) | 2.0.5以上版本 | +| filter | service.filter | string | 可选 | default | 性能调优 | 服务提供方远程调用过程拦截器名称,多个名称用逗号分隔 | 2.0.5以上版本 | +| listener | exporter.listener | string | 可选 | default | 性能调优 | 服务提供方导出服务监听器名称,多个名称用逗号分隔 | | +| protocol | | string | 可选 | | 配置关联 | 使用指定的协议暴露服务,在多协议时使用,值为<dubbo:protocol>的id属性,多个协议ID用逗号分隔 | 2.0.5以上版本 | +| layer | layer | string | 可选 | | 服务治理 | 服务提供者所在的分层。如:biz、dao、intl:web、china:acton。 | 2.0.7以上版本 | +| register | register | boolean | 可选 | true | 服务治理 | 该协议的服务是否注册到注册中心 | 2.0.8以上版本 | +| validation | validation | string | 可选 | | 服务治理 | 是否启用JSR303标准注解验证,如果启用,将对方法参数上的注解进行校验 | 2.7.0以上版本 | +| parameters | 无 | Map | 可选 | | 服务治理 | 扩展预留,可扩展定义任意参数,所有扩展参数都将原样反映在 URL 配置上 | 2.0.0以上版本 | + +### reference + + +服务消费者引用服务配置。 + +> 对应的配置类: `org.apache.dubbo.config.ReferenceConfig` + +| 属性 | 对应URL参数 | 类型 | 是否必填 | 缺省值 | 作用 | 描述 | 兼容性 | +| --- | --- | ---- | --- | --- | --- | --- | --- | +| id | | string | 必填 | | 配置关联 | 服务引用BeanId | 1.0.0以上版本 | +| interface | | class | 必填 | | 服务发现 | 服务接口名 | 1.0.0以上版本 | +| version | version | string | 可选 | | 服务发现 | 服务版本,与服务提供者的版本一致 | 1.0.0以上版本 | +| group | group | string | 可选 | | 服务发现 | 服务分组,当一个接口有多个实现,可以用分组区分,必需和服务提供方一致 | 1.0.7以上版本 | +| timeout | timeout | long | 可选 | 缺省使用<dubbo:consumer>的timeout | 性能调优 | 服务方法调用超时时间(毫秒) | 1.0.5以上版本 | +| retries | retries | int | 可选 | 缺省使用<dubbo:consumer>的retries | 性能调优 | 远程服务调用重试次数,不包括第一次调用,不需要重试请设为0 | 2.0.0以上版本 | +| connections | connections | int | 可选 | 缺省使用<dubbo:consumer>的connections | 性能调优 | 对每个提供者的最大连接数,rmi、http、hessian等短连接协议表示限制连接数,dubbo等长连接协表示建立的长连接个数 | 2.0.0以上版本 | +| loadbalance | loadbalance | string | 可选 | 缺省使用<dubbo:consumer>的loadbalance | 性能调优 | 负载均衡策略,可选值:
* random - 随机;
* roundrobin - 轮询;
* leastactive - 最少活跃调用;
* consistenthash - 哈希一致 (2.1.0以上版本);
* shortestresponse - 最短响应 (2.7.7以上版本); | 2.0.0以上版本 | +| async | async | boolean | 可选 | 缺省使用<dubbo:consumer>的async | 性能调优 | 是否异步执行,不可靠异步,只是忽略返回值,不阻塞执行线程 | 2.0.0以上版本 | +| generic | generic | boolean | 可选 | 缺省使用<dubbo:consumer>的generic | 服务治理 | 是否缺省泛化接口,如果为泛化接口,将返回GenericService | 2.0.0以上版本 | +| check | check | boolean | 可选 | 缺省使用<dubbo:consumer>的check | 服务治理 | 启动时检查提供者是否存在,true报错,false忽略 | 2.0.0以上版本 | +| url | url | string | 可选 | | 服务治理 | 点对点直连服务提供者地址,将绕过注册中心 | 1.0.6以上版本 | +| stub | stub | class/boolean | 可选 | | 服务治理 | 服务接口客户端本地代理类名,用于在客户端执行本地逻辑,如本地缓存等,该本地代理类的构造函数必须允许传入远程代理对象,构造函数如:public XxxServiceLocal(XxxService xxxService) | 2.0.0以上版本 | +| mock | mock | class/boolean | 可选 | | 服务治理 | 服务接口调用失败Mock实现类名,该Mock类必须有一个无参构造函数,与Local的区别在于,Local总是被执行,而Mock只在出现非业务异常(比如超时,网络异常等)时执行,Local在远程调用之前执行,Mock在远程调用后执行。 | Dubbo1.0.13及其以上版本支持 | +| cache | cache | string/boolean | 可选 | | 服务治理 | 以调用参数为key,缓存返回结果,可选:lru, threadlocal, jcache等 | Dubbo2.1.0及其以上版本支持 | +| validation | validation | boolean | 可选 | | 服务治理 | 是否启用JSR303标准注解验证,如果启用,将对方法参数上的注解进行校验 | Dubbo2.1.0及其以上版本支持 | +| proxy | proxy | boolean | 可选 | javassist | 性能调优 | 选择动态代理实现策略,可选:javassist, jdk | 2.0.2以上版本 | +| client | client | string | 可选 | | 性能调优 | 客户端传输类型设置,如Dubbo协议的netty或mina。 | Dubbo2.0.0以上版本支持 | +| registry | | string | 可选 | 缺省将从所有注册中心获服务列表后合并结果 | 配置关联 | 从指定注册中心注册获取服务列表,在多个注册中心时使用,值为<dubbo:registry>的id属性,多个注册中心ID用逗号分隔 | 2.0.0以上版本 | +| owner | owner | string | 可选 | | 服务治理 | 调用服务负责人,用于服务治理,请填写负责人公司邮箱前缀 | 2.0.5以上版本 | +| actives | actives | int | 可选 | 0 | 性能调优 | 每服务消费者每服务每方法最大并发调用数 | 2.0.5以上版本 | +| cluster | cluster | string | 可选 | failover | 性能调优 | 集群方式,可选:failover/failfast/failsafe/failback/forking/available/mergeable(2.1.0以上版本)/broadcast(2.1.0以上版本)/zone-aware(2.7.5以上版本) | 2.0.5以上版本 | +| connections | connections | int | 可选 | 100 | 性能调优 | 对每个提供者的最大连接数,rmi、http、hessian等短连接协议表示限制连接数,dubbo等长连接协表示建立的长连接个数 | 2.0.0以上版本 | +| filter | reference.filter | string | 可选 | default | 性能调优 | 服务消费方远程调用过程拦截器名称,多个名称用逗号分隔 | 2.0.5以上版本 | +| listener | invoker.listener | string | 可选 | default | 性能调优 | 服务消费方引用服务监听器名称,多个名称用逗号分隔 | 2.0.5以上版本 | +| layer | layer | string | 可选 | | 服务治理 | 服务调用者所在的分层。如:biz、dao、intl:web、china:acton。 | 2.0.7以上版本 | +| init | init | boolean | 可选 | false | 性能调优 | 是否在afterPropertiesSet()时饥饿初始化引用,否则等到有人注入或引用该实例时再初始化。 | 2.0.10以上版本 | +| protocol | protocol | string | 可选 | | 服务治理 | 只调用指定协议的服务提供方,其它协议忽略。 | 2.7.0以上版本 | +| client | client | string | 可选 | dubbo协议缺省为netty | 服务发现 | 协议的客户端实现类型,比如:dubbo协议的mina,netty等 | 2.7.0以上版本 | +| providerPort | provider-port | int | 可选 | | Service Mesh | 当dubbo.consumer.meshEnable=true,Dubbo默认会将请求转换成K8S标准格式,结合VirtualService和DestinationRule进行流量治理,此时consumer端可以感知到provider。如果不想使用VirtualService和DestinationRule,请设置providerPort,使consumer端感知provider暴露的服务端口 | 3.1.0以上版本 | +| unloadClusterRelated | unloadClusterRelated | boolean | 可选 | false | Service Mesh | 当dubbo.consumer.meshEnable=true,在Service Mesh模式下,设置为true,可在当前调用中卸载与Cluster相关的Directory、Router和Load Balance,将重试、负载平衡、超时和其他流量管理功能下放至Sidecar,使用VirtualService和DestinationRule进行流量治理 | 3.1.0以上版本 | +| parameters | 无 | Map | 可选 | | 服务治理 | 扩展预留,可扩展定义任意参数,所有扩展参数都将原样反映在 URL 配置上 | 2.0.0以上版本 | +| providedBy | provided-by | string | 可选 | | Service Mesh | 当dubbo.consumer.meshEnable=true,Dubbo默认会将请求转换成K8S标准格式,结合VirtualService和DestinationRule进行流量治理,此时consumer端可以感知到provider。该值应当与声明的`k8s service`一致 | 3.1.0以上版本 | +| providerNamespace | provider-namespace | string | 可选 | | Service Mesh | 当dubbo.consumer.meshEnable=true,Dubbo默认会将请求转换成K8S标准格式,结合VirtualService和DestinationRule进行流量治理,此时consumer端可以感知到provider。请设置providerNamespace,使consumer端按照此配置寻址provider dns,默认`default` | 3.1.2以上版本 | + + +### registry + +注册中心配置。 + +> 对应的配置类: `org.apache.dubbo.config.RegistryConfig`。同时如果有多个不同的注册中心,可以声明多个 `` 标签,并在 `` 或 `` 的 `registry` 属性指定使用的注册中心。 + +| 属性 | 对应URL参数 | 类型 | 是否必填 | 缺省值 | 作用 | 描述 | 兼容性 | +| --- | --- | ---- | --- | --- | --- | --- | --- | +| id | | string | 可选 | | 配置关联 | 注册中心引用BeanId,可以在<dubbo:service registry="">或<dubbo:reference registry="">中引用此ID | 1.0.16以上版本 | +| address | <host:port> | string | 必填 | | 服务发现 | 注册中心服务器地址,如果地址没有端口缺省为9090,同一集群内的多个地址用逗号分隔,如:ip:port,ip:port,不同集群的注册中心,请配置多个<dubbo:registry>标签 | 1.0.16以上版本 | +| protocol | <protocol> | string | 可选 | dubbo | 服务发现 | 注册中心地址协议,支持`dubbo`, `multicast`, `zookeeper`, `redis`, `consul(2.7.1)`, `sofa(2.7.2)`, `etcd(2.7.2)`, `nacos(2.7.2)`等协议 | 2.0.0以上版本 | +| port | <port> | int | 可选 | 9090 | 服务发现 | 注册中心缺省端口,当address没有带端口时使用此端口做为缺省值 | 2.0.0以上版本 | +| username | <username> | string | 可选 | | 服务治理 | 登录注册中心用户名,如果注册中心不需要验证可不填 | 2.0.0以上版本 | +| password | <password> | string | 可选 | | 服务治理 | 登录注册中心密码,如果注册中心不需要验证可不填 | 2.0.0以上版本 | +| transport | registry.transporter | string | 可选 | netty | 性能调优 | 网络传输方式,可选mina,netty | 2.0.0以上版本 | +| timeout | registry.timeout | int | 可选 | 5000 | 性能调优 | 注册中心请求超时时间(毫秒) | 2.0.0以上版本 | +| session | registry.session | int | 可选 | 60000 | 性能调优 | 注册中心会话超时时间(毫秒),用于检测提供者非正常断线后的脏数据,比如用心跳检测的实现,此时间就是心跳间隔,不同注册中心实现不一样。 | 2.1.0以上版本 | +| zone | zone | string | 可选 | | 服务治理 | 注册表所属区域,通常用于流量隔离 | 2.7.5以上版本 +| file | registry.file | string | 可选 | | 服务治理 | 使用文件缓存注册中心地址列表及服务提供者列表,应用重启时将基于此文件恢复,注意:两个注册中心不能使用同一文件存储 | 2.0.0以上版本 | +| wait | registry.wait | int | 可选 | 0 | 性能调优 | 停止时等待通知完成时间(毫秒) | 2.0.0以上版本 | +| check | check | boolean | 可选 | true | 服务治理 | 注册中心不存在时,是否报错 | 2.0.0以上版本 | +| register | register | boolean | 可选 | true | 服务治理 | 是否向此注册中心注册服务,如果设为false,将只订阅,不注册 | 2.0.5以上版本 | +| subscribe | subscribe | boolean | 可选 | true | 服务治理 | 是否向此注册中心订阅服务,如果设为false,将只注册,不订阅 | 2.0.5以上版本 | +| dynamic | dynamic | boolean | 可选 | true | 服务治理 | 服务是否动态注册,如果设为false,注册后将显示为disable状态,需人工启用,并且服务提供者停止时,也不会自动取消注册,需人工禁用。 | 2.0.5以上版本 | +| group | group | string | 可选 | dubbo | 服务治理 | 服务注册分组,跨组的服务不会相互影响,也无法相互调用,适用于环境隔离。 | 2.0.5以上版本 | +| version | version | string | 可选 | | 服务发现 | 服务版本 | 1.0.0以上版本 | +| simplified | simplified | boolean | 可选 | false | 服务治理 | 注册到注册中心的URL是否采用精简模式的(与低版本兼容) | 2.7.0以上版本 | +| extra-keys | extraKeys | string | 可选 | | 服务治理 | 在simplified=true时,extraKeys允许你在默认参数外将额外的key放到URL中,格式:"interface,key1,key2"。 | 2.7.0以上版本 | +| useAsConfigCenter | | boolean | 可选 | | 服务治理 | 该注册中心是否作为配置中心使用 | 2.7.5以上版本 | +| useAsMetadataCenter | | boolean | 可选 | | 服务治理 | 该注册中心是否作为元数据中心使用 | 2.7.5以上版本 | +| accepts | accepts | string | 可选 | | 服务治理 | 该注册中心接收rpc协议列表,多协议用逗号隔开,例如dubbo,rest | 2.7.5以上版本 | +| preferred | preferred | boolean | 可选 | | 服务治理 | 是否作为首选注册中心。当订阅多注册中心时,如果设为true,该注册中心作为首选 | 2.7.5以上版本 | +| weight | weight | int | 可选 | | 性能调优 | 注册流量权重。使用多注册中心时,可通过该值调整注册流量的分布,当设置首选注册中心时该值不生效 | 2.7.5以上版本 | +| registerMode | register-mode | string | 可选 | all | 服务治理 | 控制地址注册行为,应用级服务发现迁移用。
* instance 只注册应用级地址;
* interface 只注册接口级地址;
* all(默认) 同时注册应用级和接口级地址; | 3.0.0以上版本 | +| enableEmptyProtection | enable-empty-protection | boolean | 可选 | true | 服务治理 | 是否全局启用消费端的空地址列表保护,开启后注册中心的空地址推送将被忽略,默认 true | 3.0.0以上版本 | +| parameters | 无 | Map | 可选 | | 服务治理 | 扩展预留,可扩展定义任意参数,所有扩展参数都将原样反映在 URL 配置上 | 2.0.0以上版本 | + +### config-center + +配置中心。 + +> 对应的配置类:`org.apache.dubbo.config.ConfigCenterConfig` + +| 属性 | 对应URL参数 | 类型 | 是否必填 | 缺省值 | 描述 | 兼容性 | +| ---------------- | ---------------------- | ------------------- | -------- | ---------------- | ------------------------------------------------------------ | ------ | +| protocol | protocol | string | 可选 | zookeeper | 使用哪个配置中心:apollo、zookeeper、nacos等。
以zookeeper为例
1. 指定protocol,则address可以简化为`127.0.0.1:2181`;
2. 不指定protocol,则address取值为`zookeeper://127.0.0.1:2181` | 2.7.0以上版本 | +| address | address | string | 必填 | | 配置中心地址。
取值参见protocol说明 | 2.7.0以上版本 | +| highestPriority | highest-priority| boolean | 可选 | true | 来自配置中心的配置项具有最高优先级,即会覆盖本地配置项。 | 2.7.0以上版本 | +| namespace | namespace | string | 可选 | dubbo | 通常用于多租户隔离,实际含义视具体配置中心而不同。
如:
zookeeper - 环境隔离,默认值`dubbo`;
apollo - 区分不同领域的配置集合,默认使用`dubbo`和`application` | 2.7.0以上版本 | +| cluster | cluster | string | 可选 | | 含义视所选定的配置中心而不同。
如Apollo中用来区分不同的配置集群 | 2.7.0以上版本 | +| group | group | string | 可选 | dubbo | 含义视所选定的配置中心而不同。
nacos - 隔离不同配置集
zookeeper - 隔离不同配置集 | 2.7.0以上版本 | +| check | check | boolean | 可选 | true | 当配置中心连接失败时,是否终止应用启动。 | 2.7.0以上版本 | +| configFile | config-file | string | 可选 | dubbo.properties | 全局级配置文件所映射到的key
zookeeper - 默认路径/dubbo/config/dubbo/dubbo.properties
apollo - dubbo namespace中的dubbo.properties键 | 2.7.0以上版本 | +| appConfigFile | app-config-file | string | 可选 | | “configFile”是全局级共享的。此项仅限于此应用程序配置的属性 | 2.7.0以上版本 | +| timeout | timeout | int | 可选 | 3000ms | 获取配置的超时时间 | 2.7.0以上版本 | +| username | username | string | 可选 | | 如果配置中心需要做校验,用户名
Apollo暂未启用 | 2.7.0以上版本 | +| password | password | string | 可选 | | 如果配置中心需要做校验,密码
Apollo暂未启用 | 2.7.0以上版本 | +| parameters | parameters | Map | 可选 | | 扩展参数,用来支持不同配置中心的定制化配置参数 | 2.7.0以上版本 | +| includeSpringEnv |include-spring-env| boolean | 可选 | false | 使用Spring框架时支持,为true时,会自动从Spring Environment中读取配置。
默认依次读取
key为dubbo.properties的配置
key为dubbo.properties的PropertySource | 2.7.0以上版本 | + +### metadata-report-config + +元数据中心。 + +> 对应的配置类:`org.apache.dubbo.config.MetadataReportConfig` + +| 属性 | 对应URL参数 | 类型 | 是否必填 | 缺省值 | 描述 | 兼容性 | +| --------------- | --------- | ------ | -------- | --------- | ------------------------------------------------------------ | ------ | +| address | address | string | 必填 | | 元数据中心地址。 | 2.7.0以上版本 | +| protocol | protocol | string | 可选 | zookeeper | 元数据中心协议:zookeeper、nacos、redis等。
以zookeeper为例
1. 指定protocol,则address可以简化为`127.0.0.1:2181`;
2. 不指定protocol,则address取值为`zookeeper://127.0.0.1:2181` | 2.7.13以上版本 | +| port | port | int | 可选 | | 元数据中心端口号。指定port,则address可简化,不用配置端口号 | 2.7.13以上版本 | +| username | username | string | 可选 | | 元数据中心需要做校验,用户名
Apollo暂未启用 | 2.7.0以上版本 | +| password | password | string | 可选 | | 元数据中心需要做校验,密码
Apollo暂未启用 | 2.7.0以上版本 | +| timeout | timeout | int | 可选 | | 获取元数据超时时间(ms) | 2.7.0以上版本 | +| group | group | string | 可选 | dubbo | 元数据分组,适用于环境隔离。与注册中心group意义相同 | 2.7.0以上版本 | +| retryTimes | retry-times| int | 可选 | 100 | 重试次数 | 2.7.0以上版本 | +| retryPeriod | retry-period | int | 可选 | 3000ms | 重试间隔时间(ms) | 2.7.0以上版本 | +| cycleReport | cycle-report | boolean| 可选 | true | 是否每天更新完整元数据 | 2.7.0以上版本 | +| syncReport | sync-report | boolean| 可选 | false | 是否同步更新元数据,默认为异步 | 2.7.0以上版本 | +| cluster | cluster | string | 可选 | | 含义视所选定的元数据中心而不同。
如Apollo中用来区分不同的配置集群 | 2.7.0以上版本 | +| file | file | string | 可选 | | 使用文件缓存元数据中心列表,应用重启时将基于此文件恢复,注意:两个元数据中心不能使用同一文件存储 | 2.7.0以上版本 | +| check | check | boolean | 可选 | true | 当元数据中心连接失败时,是否终止应用启动。 | 3.0.0以上版本 | +| reportMetadata | report-metadata | boolean | 可选 | false | 是否上报地址发现中的接口配置报元数据,`dubbo.application.metadata-type=remote` 该配置不起作用即一定会上报,`dubbo.application.metadata-type=local` 时是否上报由该配置值决定 | 3.0.0以上版本 | +| reportDefinition | report-definition | boolean | 可选 | true | 是否上报服务运维用元数据 | 3.0.0以上版本 | +| reportConsumerDefinition | report-consumer-definition | boolean | 可选 | true | 是否在消费端上报服务运维用元数据 | 3.0.0以上版本 | +| parameters | parameters | Map | 可选 | | 扩展参数,用来支持不同元数据中心的定制化配置参数 | 2.7.0以上版本 | + +### protocol + +服务提供者协议配置。 + +> 对应的配置类: `org.apache.dubbo.config.ProtocolConfig`。同时,如果需要支持多协议,可以声明多个 `` 标签,并在 `` 中通过 `protocol` 属性指定使用的协议。 + +| 属性 | 对应URL参数 | 类型 | 是否必填 | 缺省值 | 作用 | 描述 | 兼容性 | +| --- | --- | ---- | --- | --- | --- | --- | --- | +| id | | string | 可选 | dubbo | 配置关联 | 协议BeanId,可以在<dubbo:service protocol="">中引用此ID,如果ID不填,缺省和name属性值一样,重复则在name后加序号。 | 2.0.5以上版本 | +| name | <protocol> | string | 必填 | dubbo | 性能调优 | 协议名称 | 2.0.5以上版本 | +| port | <port> | int | 可选 | dubbo协议缺省端口为20880,rmi协议缺省端口为1099,http和hessian协议缺省端口为80;如果没有配置port,则自动采用默认端口,如果配置为-1,则会分配一个没有被占用的端口。Dubbo 2.4.0+,分配的端口在协议缺省端口的基础上增长,确保端口段可控。 | 服务发现 | 服务端口 | 2.0.5以上版本 | +| host | <host> | string | 可选 | 自动查找本机IP | 服务发现 | -服务主机名,多网卡选择或指定VIP及域名时使用,为空则自动查找本机IP,-建议不要配置,让Dubbo自动获取本机IP | 2.0.5以上版本 | +| threadpool | threadpool | string | 可选 | fixed | 性能调优 | 线程池类型,可选:fixed/cached/limit(2.5.3以上)/eager(2.6.x以上) | 2.0.5以上版本 | +| threadname | threadname | string | 可选 | | 性能调优 | 线程池名称 | 2.7.6以上版本 | +| threads | threads | int | 可选 | 200 | 性能调优 | 服务线程池大小(固定大小) | 2.0.5以上版本 | +| corethreads | corethreads | int | 可选 | 200 | 性能调优 | 线程池核心线程大小 | 2.0.5以上版本 | +| iothreads | threads | int | 可选 | cpu个数+1 | 性能调优 | io线程池大小(固定大小) | 2.0.5以上版本 | +| accepts | accepts | int | 可选 | 0 | 性能调优 | 服务提供方最大可接受连接数 | 2.0.5以上版本 | +| payload | payload | int | 可选 | 8388608(=8M) | 性能调优 | 请求及响应数据包大小限制,单位:字节 | 2.0.5以上版本 | +| codec | codec | string | 可选 | dubbo | 性能调优 | 协议编码方式 | 2.0.5以上版本 | +| serialization | serialization | string | 可选 | dubbo协议缺省为hessian2,rmi协议缺省为java,http协议缺省为json | 性能调优 | 协议序列化方式,当协议支持多种序列化方式时使用,比如:dubbo协议的dubbo,hessian2,java,compactedjava,以及http协议的json等 | 2.0.5以上版本 | +| accesslog | accesslog | string/boolean | 可选 | | 服务治理 | 设为true,将向logger中输出访问日志,也可填写访问日志文件路径,直接把访问日志输出到指定文件 | 2.0.5以上版本 | +| path | <path> | string | 可选 | | 服务发现 | 提供者上下文路径,为服务path的前缀 | 2.0.5以上版本 | +| transporter | transporter | string | 可选 | dubbo协议缺省为netty | 性能调优 | 协议的服务端和客户端实现类型,比如:dubbo协议的mina,netty等,可以分拆为server和client配置 | 2.0.5以上版本 | +| server | server | string | 可选 | dubbo协议缺省为netty,http协议缺省为servlet | 性能调优 | 协议的服务器端实现类型,比如:dubbo协议的mina,netty等,http协议的jetty,servlet等 | 2.0.5以上版本 | +| client | client | string | 可选 | dubbo协议缺省为netty | 性能调优 | 协议的客户端实现类型,比如:dubbo协议的mina,netty等 | 2.0.5以上版本 | +| dispatcher | dispatcher | string | 可选 | dubbo协议缺省为all | 性能调优 | 协议的消息派发方式,用于指定线程模型,比如:dubbo协议的all, direct, message, execution, connection等 | 2.1.0以上版本 | +| queues | queues | int | 可选 | 0 | 性能调优 | 线程池队列大小,当线程池满时,排队等待执行的队列大小,建议不要设置,当线程池满时应立即失败,重试其它服务提供机器,而不是排队,除非有特殊需求。 | 2.0.5以上版本 | +| charset | charset | string | 可选 | UTF-8 | 性能调优 | 序列化编码 | 2.0.5以上版本 | +| buffer | buffer | int | 可选 | 8192 | 性能调优 | 网络读写缓冲区大小 | 2.0.5以上版本 | +| heartbeat | heartbeat | int | 可选 | 0 | 性能调优 | 心跳间隔,对于长连接,当物理层断开时,比如拔网线,TCP的FIN消息来不及发送,对方收不到断开事件,此时需要心跳来帮助检查连接是否已断开 | 2.0.10以上版本 | +| telnet | telnet | string | 可选 | | 服务治理 | 所支持的telnet命令,多个命令用逗号分隔 | 2.0.5以上版本 | +| register | register | boolean | 可选 | true | 服务治理 | 该协议的服务是否注册到注册中心 | 2.0.8以上版本 | +| contextpath | contextpath | String | 可选 | 缺省为空串 | 服务治理 | 上下文路径 | 2.0.6以上版本 | +| sslEnabled | ssl-enabled | boolean | 可选 | false | 服务治理 | 是否启用ssl | 2.7.5以上版本 | +| parameters | parameters | Map | 可选 | | 扩展参数 | 2.0.0以上版本 | + +### provider + +服务提供者缺省值配置。 + +> 对应的配置类: `org.apache.dubbo.config.ProviderConfig`。同时该标签为 `` 和 `` 标签的缺省值设置。 + +| 属性 | 对应URL参数 | 类型 | 是否必填 | 缺省值 | 作用 | 描述 | 兼容性 | +| --- | --- | ---- | --- | --- | --- | --- | --- | +| id | | string | 可选 | dubbo | 配置关联 | 协议BeanId,可以在<dubbo:service proivder="">中引用此ID | 1.0.16以上版本 | +| protocol | <protocol> | string | 可选 | dubbo | 性能调优 | 协议名称 | 1.0.16以上版本 | +| host | <host> | string | 可选 | 自动查找本机IP | 服务发现 | 服务主机名,多网卡选择或指定VIP及域名时使用,为空则自动查找本机IP,建议不要配置,让Dubbo自动获取本机IP | 1.0.16以上版本 | +| threads | threads | int | 可选 | 200 | 性能调优 | 服务线程池大小(固定大小) | 1.0.16以上版本 | +| payload | payload | int | 可选 | 8388608(=8M) | 性能调优 | 请求及响应数据包大小限制,单位:字节 | 2.0.0以上版本 | +| path | <path> | string | 可选 | | 服务发现 | 提供者上下文路径,为服务path的前缀 | 2.0.0以上版本 | +| transporter | transporter | string | 可选 | dubbo协议缺省为netty | 性能调优 | 协议的服务端和客户端实现类型,比如:dubbo协议的mina,netty等,可以分拆为server和client配置 | 2.0.5以上版本 | +| server | server | string | 可选 | dubbo协议缺省为netty,http协议缺省为servlet | 性能调优 | 协议的服务器端实现类型,比如:dubbo协议的mina,netty等,http协议的jetty,servlet等 | 2.0.0以上版本 | +| client | client | string | 可选 | dubbo协议缺省为netty | 性能调优 | 协议的客户端实现类型,比如:dubbo协议的mina,netty等 | 2.0.0以上版本 | +| dispatcher | dispatcher | string | 可选 | dubbo协议缺省为all | 性能调优 | 协议的消息派发方式,用于指定线程模型,比如:dubbo协议的all, direct, message, execution, connection等 | 2.1.0以上版本 | +| codec | codec | string | 可选 | dubbo | 性能调优 | 协议编码方式 | 2.0.0以上版本 | +| serialization | serialization | string | 可选 | dubbo协议缺省为hessian2,rmi协议缺省为java,http协议缺省为json | 性能调优 | 协议序列化方式,当协议支持多种序列化方式时使用,比如:dubbo协议的dubbo,hessian2,java,compactedjava,以及http协议的json,xml等 | 2.0.5以上版本 | +| default | | boolean | 可选 | false | 配置关联 | 是否为缺省协议,用于多协议 | 1.0.16以上版本 | +| filter | service.filter | string | 可选 | | 性能调优 | 服务提供方远程调用过程拦截器名称,多个名称用逗号分隔 | 2.0.5以上版本 | +| listener | exporter.listener | string | 可选 | | 性能调优 | 服务提供方导出服务监听器名称,多个名称用逗号分隔 | 2.0.5以上版本 | +| threadpool | threadpool | string | 可选 | fixed | 性能调优 | 线程池类型,可选:fixed/cached/limit(2.5.3以上)/eager(2.6.x以上) | 2.0.5以上版本 | +| threadname | threadname | string | 可选 | | 性能调优 | 线程池名称 | 2.7.6以上版本 | +| accepts | accepts | int | 可选 | 0 | 性能调优 | 服务提供者最大可接受连接数 | 2.0.5以上版本 | +| version | version | string | 可选 | 0.0.0 | 服务发现 | 服务版本,建议使用两位数字版本,如:1.0,通常在接口不兼容时版本号才需要升级 | 2.0.5以上版本 | +| group | group | string | 可选 | | 服务发现 | 服务分组,当一个接口有多个实现,可以用分组区分 | 2.0.5以上版本 | +| delay | delay | int | 可选 | 0 | 性能调优 | 延迟注册服务时间(毫秒)- ,设为-1时,表示延迟到Spring容器初始化完成时暴露服务 | 2.0.5以上版本 | +| timeout | default.timeout | int | 可选 | 1000 | 性能调优 | 远程服务调用超时时间(毫秒) | 2.0.5以上版本 | +| retries | default.retries | int | 可选 | 2 | 性能调优 | 远程服务调用重试次数,不包括第一次调用,不需要重试请设为0 | 2.0.5以上版本 | +| connections | default.connections | int | 可选 | 0 | 性能调优 | 对每个提供者的最大连接数,rmi、http、hessian等短连接协议表示限制连接数,dubbo等长连接协表示建立的长连接个数 | 2.0.5以上版本 | +| loadbalance | default.loadbalance | string | 可选 | random | 性能调优 | 负载均衡策略,可选值:
* random - 随机;
* roundrobin - 轮询;
* leastactive - 最少活跃调用;
* consistenthash - 哈希一致 (2.1.0以上版本);
* shortestresponse - 最短响应 (2.7.7以上版本); | 2.0.5以上版本 | +| async | default.async | boolean | 可选 | false | 性能调优 | 是否缺省异步执行,不可靠异步,只是忽略返回值,不阻塞执行线程 | 2.0.5以上版本 | +| stub | stub | boolean | 可选 | false | 服务治理 | 设为true,表示使用缺省代理类名,即:接口名 + Local后缀。 | 2.0.5以上版本 | +| mock | mock | boolean | 可选 | false | 服务治理 | 设为true,表示使用缺省Mock类名,即:接口名 + Mock后缀。 | 2.0.5以上版本 | +| token | token | boolean | 可选 | | 服务治理 | 令牌验证,为空表示不开启,如果为true,表示随机生成动态令牌 | 2.0.5以上版本 | +| registry | registry | string | 可选 | 缺省向所有registry注册 | 配置关联 | 向指定注册中心注册,在多个注册中心时使用,值为<dubbo:registry>的id属性,多个注册中心ID用逗号分隔,如果不想将该服务注册到任何registry,可将值设为N/A | 2.0.5以上版本 | +| dynamic | dynamic | boolean | 可选 | true | 服务治理 | 服务是否动态注册,如果设为false,注册后将显示后disable状态,需人工启用,并且服务提供者停止时,也不会自动取消册,需人工禁用。 | 2.0.5以上版本 | +| accesslog | accesslog | string/boolean | 可选 | false | 服务治理 | 设为true,将向logger中输出访问日志,也可填写访问日志文件路径,直接把访问日志输出到指定文件 | 2.0.5以上版本 | +| owner | owner | string | 可选 | | 服务治理 | 服务负责人,用于服务治理,请填写负责人公司邮箱前缀 | 2.0.5以上版本 | +| document | document | string | 可选 | | 服务治理 | 服务文档URL | 2.0.5以上版本 | +| weight | weight | int | 可选 | | 性能调优 | 服务权重 | 2.0.5以上版本 | +| executes | executes | int | 可选 | 0 | 性能调优 | 服务提供者每服务每方法最大可并行执行请求数 | 2.0.5以上版本 | +| actives | default.actives | int | 可选 | 0 | 性能调优 | 每服务消费者每服务每方法最大并发调用数 | 2.0.5以上版本 | +| proxy | proxy | string | 可选 | javassist | 性能调优 | 生成动态代理方式,可选:jdk/javassist | 2.0.5以上版本 | +| cluster | default.cluster | string | 可选 | failover | 性能调优 | 集群方式,可选:failover/failfast/failsafe/failback/forking | 2.0.5以上版本 | +| deprecated | deprecated | boolean | 可选 | false | 服务治理 | 服务是否过时,如果设为true,消费方引用时将打印服务过时警告error日志 | 2.0.5以上版本 | +| queues | queues | int | 可选 | 0 | 性能调优 | 线程池队列大小,当线程池满时,排队等待执行的队列大小,建议不要设置,当线程池满时应立即失败,重试其它服务提供机器,而不是排队,除非有特殊需求。 | 2.0.5以上版本 | +| charset | charset | string | 可选 | UTF-8 | 性能调优 | 序列化编码 | 2.0.5以上版本 | +| buffer | buffer | int | 可选 | 8192 | 性能调优 | 网络读写缓冲区大小 | 2.0.5以上版本 | +| iothreads | iothreads | int | 可选 | CPU + 1 | 性能调优 | IO线程池,接收网络读写中断,以及序列化和反序列化,不处理业务,业务线程池参见threads配置,此线程池和CPU相关,不建议配置。 | 2.0.5以上版本 | +| alive | alive | int | 可选 | | 服务治理 | 线程池keepAliveTime,默认单位为ms | 2.0.5以上版本 | +| telnet | telnet | string | 可选 | | 服务治理 | 所支持的telnet命令,多个命令用逗号分隔 | 2.0.5以上版本 | +| wait | wait | int | 可选 | | 服务治理 | 停服务时等待时间 | 2.0.5以上版本 | +| contextpath | contextpath | String | 可选 | 缺省为空串 | 服务治理 | 上下文路径 | 2.0.6以上版本 | +| layer | layer | string | 可选 | | 服务治理 | 服务提供者所在的分层。如:biz、dao、intl:web、china:acton。 | 2.0.7以上版本 | +| parameters | parameters | Map | 可选 | | 服务治理 | 扩展参数 | 2.0.0以上版本 | + +### consumer + +服务消费者缺省值配置。 + +> 配置类: `org.apache.dubbo.config.ConsumerConfig` 。同时该标签为 `` 标签的缺省值设置。 + +| 属性 | 对应URL参数 | 类型 | 是否必填 | 缺省值 | 作用 | 描述 | 兼容性 | +| --- | --- | ---- | --- | --- | --- | --- | --- | +| timeout | default.timeout | int | 可选 | 1000 | 性能调优 | 远程服务调用超时时间(毫秒) | 1.0.16以上版本 | +| retries | default.retries | int | 可选 | 2 | 性能调优 | 远程服务调用重试次数,不包括第一次调用,不需要重试请设为0,仅在cluster为failback/failover时有效 | 1.0.16以上版本 | +| loadbalance | default.loadbalance | string | 可选 | random | 性能调优 | 负载均衡策略,可选值:
* random - 随机;
* roundrobin - 轮询;
* leastactive - 最少活跃调用;
* consistenthash - 哈希一致 (2.1.0以上版本);
* shortestresponse - 最短响应 (2.7.7以上版本); | 1.0.16以上版本 | +| async | default.async | boolean | 可选 | false | 性能调优 | 是否缺省异步执行,不可靠异步,只是忽略返回值,不阻塞执行线程 | 2.0.0以上版本 | +| sent | default.sent | boolean | 可选 | true | 服务治理 | 异步调用时,标记sent=true时,表示网络已发出数据 | 2.0.6以上版本 | +| connections | default.connections | int | 可选 | 100 | 性能调优 | 每个服务对每个提供者的最大连接数,rmi、http、hessian等短连接协议支持此配置,dubbo协议长连接不支持此配置 | 1.0.16以上版本 | +| generic | generic | boolean | 可选 | false | 服务治理 | 是否缺省泛化接口,如果为泛化接口,将返回GenericService | 2.0.0以上版本 | +| check | check | boolean | 可选 | true | 服务治理 | 启动时检查提供者是否存在,true报错,false忽略 | 1.0.16以上版本 | +| proxy | proxy | string | 可选 | javassist | 性能调优 | 生成动态代理方式,可选:jdk/javassist | 2.0.5以上版本 | +| owner | owner | string | 可选 | | 服务治理 | 调用服务负责人,用于服务治理,请填写负责人公司邮箱前缀 | 2.0.5以上版本 | +| actives | default.actives | int | 可选 | 0 | 性能调优 | 每服务消费者每服务每方法最大并发调用数 | 2.0.5以上版本 | +| cluster | default.cluster | string | 可选 | failover | 性能调优 | 集群方式,可选:failover/failfast/failsafe/failback/forking/available/mergeable(2.1.0以上版本)/broadcast(2.1.0以上版本)/zone-aware(2.7.5以上版本) | 2.0.5以上版本 | +| filter | reference.filter | string | 可选 | | 性能调优 | 服务消费方远程调用过程拦截器名称,多个名称用逗号分隔 | 2.0.5以上版本 | +| listener | invoker.listener | string | 可选 | | 性能调优 | 服务消费方引用服务监听器名称,多个名称用逗号分隔 | 2.0.5以上版本 | +| registry | | string | 可选 | 缺省向所有registry注册 | 配置关联 | 向指定注册中心注册,在多个注册中心时使用,值为<dubbo:registry>的id属性,多个注册中心ID用逗号分隔,如果不想将该服务注册到任何registry,可将值设为N/A | 2.0.5以上版本 | +| layer | layer | string | 可选 | | 服务治理 | 服务调用者所在的分层。如:biz、dao、intl:web、china:acton。 | 2.0.7以上版本 | +| init | init | boolean | 可选 | false | 性能调优 | 是否在afterPropertiesSet()时饥饿初始化引用,否则等到有人注入或引用该实例时再初始化。 | 2.0.10以上版本 | +| cache | cache | string/boolean | 可选 | | 服务治理 | 以调用参数为key,缓存返回结果,可选:lru, threadlocal, jcache等 | 2.1.0及其以上版本支持 | +| validation | validation | boolean | 可选 | | 服务治理 | 是否启用JSR303标准注解验证,如果启用,将对方法参数上的注解进行校验 | 2.1.0及其以上版本支持 | +| version | version | string | 可选 | | 服务治理 | 在 Dubbo 中为同一个服务配置多个版本 | 2.2.0及其以上版本支持 | +| client | client | string | 可选 | dubbo协议缺省为netty | 性能调优 | 协议的客户端实现类型,比如:dubbo协议的mina,netty等 | 2.0.0以上版本 | +| threadpool | threadpool | string | 可选 | fixed | 性能调优 | 线程池类型,可选:fixed/cached/limit(2.5.3以上)/eager(2.6.x以上) | 2.0.5以上版本 | +| corethreads | corethreads | int | 可选 | 200 | 性能调优 | 线程池核心线程大小 | 2.0.5以上版本 | +| threads | threads | int | 可选 | 200 | 性能调优 | 服务线程池大小(固定大小) | 2.0.5以上版本 | +| queues | queues | int | 可选 | 0 | 性能调优 | 线程池队列大小,当线程池满时,排队等待执行的队列大小,建议不要设置,当线程池满时应立即失败,重试其它服务提供机器,而不是排队,除非有特殊需求。 | 2.0.5以上版本 | +| shareconnections | shareconnections | int | 可选 | 1 | 性能调优| 共享连接数。当connection参数设置为0时,会启用共享方式连接,默认只有一个连接。仅支持dubbo协议 | 2.7.0以上版本 | +| referThreadNum | | int | 可选 | | 性能优化 | 异步调用线程池大小 | 3.0.0以上版本 | +| meshEnable | mesh-enable| boolean | 可选 | false | Service Mesh | Dubbo Mesh模式的开关。开启后,可适配SideCar模式,将Dubbo服务调用转换为K8S标准调用。仅支持Triple协议,兼容GRPC。设置为true后,原生对接K8S,无需第三方注册中心,设置dubbo.registry.address=N/A即可 | 3.1.0以上版本 | +| parameters | parameters | Map | 可选 | | 服务治理 | 扩展参数 | 2.0.0以上版本 | + +### metrics + +指标配置。 + +> 配置类: `org.apache.dubbo.config.MetricsConfig` + +| 属性 | 对应URL参数 | 类型 | 是否必填 | 缺省值 | 作用 | 描述 | 兼容性 | +| --- | --- | ---- | --- | --- | --- | --- | --- | +| protocol | protocol | string | 可选 | prometheus | 性能调优 | 协议名称,默认使用prometheus | 3.0.0以上版本 | +| prometheus | | PrometheusConfig | 可选 | | 配置关联 | prometheus相关配置 | 3.0.0以上版本 | +| aggregation | | AggregationConfig | 可选 | | 配置关联 | 指标聚合相关配置 | 3.0.0以上版本 | + +- PrometheusConfig 对应类:`org.apache.dubbo.config.nested.PrometheusConfig` + +| 属性 | 类型 | 是否必填 | 缺省值 | 描述 | +| --- | --- | ---- | --- | --- | +| exporter.enabled | boolean | 可选 | | 是否启用prometheus exporter | +| exporter.enableHttpServiceDiscovery | boolean | 可选 | | 是否启用http服务发现 | +| exporter.httpServiceDiscoveryUrl | string | 可选 | | http服务发现地址 | +| exporter.metricsPort | int | 可选 | | 当使用pull方法时,暴露的端口号 | +| exporter.metricsPath | string | 可选 | | 当使用pull方法时,暴露指标的路径 | +| pushgateway.enabled | boolean | 可选 | | 是否可以通过prometheus的Pushgateway发布指标 | +| pushgateway.baseUrl | string | 可选 | | Pushgateway地址 | +| pushgateway.username | string | 可选 | | Pushgateway用户名 | +| pushgateway.password | string | 可选 | | Pushgateway密码 | +| pushgateway.pushInterval | int | 可选 | | 推送指标间隔时间 | + +- AggregationConfig 对应类:`org.apache.dubbo.config.nested.AggregationConfig` + +| 属性 | 类型 | 是否必填 | 缺省值 | 描述 | +| --- | --- | ---- | --- | --- | +| enabled | boolean | 可选 | | 是否开启本地指标聚合功能 | +| bucketNum | int | 可选 | | 时间窗口存储桶个数 | +| timeWindowSeconds | int | 可选 | | 时间窗口时长(s) | + +### tracing + +指标配置。 + +> 配置类: `org.apache.dubbo.config.TracingConfig` + +| 属性 | 对应URL参数 | 类型 | 是否必填 | 缺省值 | 作用 | 描述 | 兼容性 | +| --- | --- | ---- | --- | --- | --- | --- | --- | +| enabled | | boolean | 可选 | false | 服务治理 | 是否开启tracing相关功能 | 3.2.3以上版本 | +| sampling | | SamplingConfig | 可选 | | 性能调优 | tracing 采样相关配置 | 3.2.3以上版本 | +| propagation | | PropagationConfig | 可选 | | 服务治理 | tracing 传播协议相关配置 | 3.2.3以上版本 | +| tracingExporter | | ExporterConfig | 可选 | | 服务治理 | tracing 信息导出相关配置 | 3.2.3以上版本 | + +- SamplingConfig 对应类:`org.apache.dubbo.config.nested.SamplingConfig` + +| 属性 | 类型 | 是否必填 | 缺省值 | 描述 | +| --- | --- | ---- | --- | --- | +| probability | float | 可选 | 0.1 | 采样率 | + +- PropagationConfig 对应类:`org.apache.dubbo.config.nested.PropagationConfig` + +| 属性 | 类型 | 是否必填 | 缺省值 | 描述 | +| --- | --- | ---- | --- | --- | +| type | string | 可选 | W3C | 可选 B3/W3C | + +- ExporterConfig 对应类:`org.apache.dubbo.config.nested.ExporterConfig` + +| 属性 | 类型 | 是否必填 | 缺省值 | 描述 | +| --- | --- | ---- | --- | --- | +| zipkinConfig | ZipkinConfig | 可选 | | zipkin 作为 exporter 的配置信息 | +| otlpConfig | OtlpConfig | 可选 | | OTlp Colletcor 作为exporter的配置信息 | + +- ZipkinConfig 对应类:`org.apache.dubbo.config.nested.ExporterConfig.ZipkinConfig` + +| 属性 | 类型 | 是否必填 | 缺省值 | 描述 | +| --- | --- | ---- | --- | --- | +| endpoint | string | 可选 | | zipkin server 地址 | +| connectTimeout | duration | 可选 | 10s | 连接到 zipkin server 的超时时间 | +| readTimeout | duration | 可选 | 10s | zipkin server 读取超时时间 | + +- OtlpConfig 对应类:`org.apache.dubbo.config.nested.ExporterConfig.OtlpConfig` + +| 属性 | 类型 | 是否必填 | 缺省值 | 描述 | +| --- | --- | ---- | --- | --- | +| endpoint | string | 可选 | | zipkin server 地址 | +| timeout | duration | 可选 | 10s | 等待收集器处理导出的一批 spans 的最大时间 | +| compressionMethod | string | 可选 | none | 用于传输中压缩 tracing 信息的方法,支持 gzip/none | +| headers | Map | 可选 | | 向 OTlp Collector 上报信息时,添加自定义的 header 头 | + +### ssl + +TLS认证配置。 + +> 配置类: `org.apache.dubbo.config.SslConfig` + +| 属性 | 对应URL参数 | 类型 | 是否必填 | 缺省值 | 作用 | 描述 | 兼容性 | +| --- | --- | ---- | --- | --- | --- | --- | --- | +| serverKeyCertChainPath | server-key-cert-chain-path | string | 可选 | | 安全配置 | 服务端签名证书路径 | 2.7.5以上版本 | +| serverPrivateKeyPath | server-private-key-path | string | 可选 | | 安全配置 | 服务端私钥路径 | 2.7.5以上版本 | +| serverKeyPassword | server-key-password | string | 可选 | | 安全配置 | 服务端密钥密码 | 2.7.5以上版本 | +| serverTrustCertCollectionPath | server-trust-cert-collection-path | string | 可选 | | 安全配置 | 服务端信任证书路径 | 2.7.5以上版本 | +| clientKeyCertChainPath | client-key-cert-chain-path | string | 可选 | | 安全配置 | 客户端签名证书路径 | 2.7.5以上版本 | +| clientPrivateKeyPath | client-private-key-path | string | 可选 | | 安全配置 | 客户端私钥路径 | 2.7.5以上版本 | +| clientKeyPassword | client-key-password | string | 可选 | | 安全配置 | 客户端密钥密码 | 2.7.5以上版本 | +| clientTrustCertCollectionPath | client-trust-cert-collection-path | string | 可选 | | 安全配置 | 客户端信任证书路径 | 2.7.5以上版本 | + +### module + +模块信息配置。 + +> 对应的配置类 `org.apache.dubbo.config.ModuleConfig` + +| 属性 | 对应URL参数 | 类型 | 是否必填 | 缺省值 | 作用 | 描述 | 兼容性 | +| --- | --- | ---- | --- | --- | --- | --- | --- | +| name | module | string | 必填 | | 服务治理 | 当前模块名称,用于注册中心计算模块间依赖关系 | 2.2.0以上版本 | +| version | module.version | string | 可选 | | 服务治理 | 当前模块的版本 | 2.2.0以上版本 | +| owner | module.owner | string | 可选 | | 服务治理 | 模块负责人,用于服务治理,请填写负责人公司邮箱前缀 | 2.2.0以上版本 | +| organization | module.organization | string | 可选 | | 服务治理 | 组织名称(BU或部门),用于注册中心区分服务来源,此配置项建议不要使用autoconfig,直接写死在配置中,比如china,intl,itu,crm,asc,dw,aliexpress等 | 2.2.0以上版本 | +| background | background | boolean | 可选 | | 性能调优 | 是否开启后台启动模式。如果开启,无需等待spring ContextRefreshedEvent事件完成 | 3.0.0以上版本 | +| referAsync | referAsync | boolean | 可选 | | 性能调优 | 消费端是否开启异步调用 | 3.0.0以上版本 | +| referThreadNum | referThreadNum | int | 可选 | | 性能调优 | 异步调用线程池大小 | 3.0.0以上版本 | +| exportAsync | exportAsync | boolean | 可选 | | 性能调优 | 服务端是否开启导出 | 3.0.0以上版本 | +| exportThreadNum | exportThreadNum | int | 可选 | | 异步导出线程池大小 | | 3.0.0以上版本 | + +### monitor + +监控中心配置。 + +> 对应的配置类: `org.apache.dubbo.config.MonitorConfig` + +| 属性 | 对应URL参数 | 类型 | 是否必填 | 缺省值 | 作用 | 描述 | 兼容性 | +| --- | --- | ---- | --- | --- | --- | --- | --- | +| protocol | protocol | string | 可选 | dubbo | 服务治理 | 监控中心协议,如果为protocol="registry",表示从注册中心发现监控中心地址,否则直连监控中心。 | 2.0.9以上版本 | +| address | <url> | string | 可选 | | 服务治理 | 直连监控中心服务器地址,address="10.20.130.230:12080" | 1.0.16以上版本 | +| username | username | string | 可选 | | 服务治理 | 监控中心用户名 | 2.0.9以上版本 | +| password | password | string | 可选 | | 服务治理 | 监控中心密码 | 2.0.9以上版本 | +| group | group | string | 可选 | | 服务治理 | 分组 | 2.0.9以上版本 | +| version | version | string | 可选 | | 服务治理 | 版本号 | 2.0.9以上版本 | +| interval | interval | string | 可选 | | 服务治理 | 间隔时间 | 2.0.9以上版本 | +| parameters | parameters | Map | 可选 | | 自定义参数 | 2.0.0以上版本 | + +### method + +方法级配置。 + +> 对应的配置类: `org.apache.dubbo.config.MethodConfig`。同时该标签为 `service` 或 `reference` 的子标签,用于控制到方法级。 + +比如: + +```xml + + + +``` + +| 属性 | 对应URL参数 | 类型 | 是否必填 | 缺省值 | 作用 | 描述 | 兼容性 | +| --- | --- | ---- | --- | --- | --- | --- | --- | +| name | | string | 必填 | | 标识 | 方法名 | 1.0.8以上版本 | +| timeout | <methodName>.timeout | int | 可选 | 缺省为的timeout | 性能调优 | 方法调用超时时间(毫秒) | 1.0.8以上版本 | +| retries | <methodName>.retries | int | 可选 | 缺省为<dubbo:reference>的retries | 性能调优 | 远程服务调用重试次数,不包括第一次调用,不需要重试请设为0 | 2.0.0以上版本 | +| loadbalance | <methodName>.loadbalance | string | 可选 | 缺省为的loadbalance | 性能调优 | 负载均衡策略,可选值:
* random - 随机;
* roundrobin - 轮询;
* leastactive - 最少活跃调用;
* consistenthash - 哈希一致 (2.1.0以上版本);
* shortestresponse - 最短响应 (2.7.7以上版本); | 2.0.0以上版本 | +| async | <methodName>.async | boolean | 可选 | 缺省为<dubbo:reference>的async | 性能调优 | 是否异步执行,不可靠异步,只是忽略返回值,不阻塞执行线程 | 1.0.9以上版本 | +| sent | <methodName>.sent | boolean | 可选 | true | 性能调优 | 异步调用时,标记sent=true时,表示网络已发出数据 | 2.0.6以上版本 | +| actives | <methodName>.actives | int | 可选 | 0 | 性能调优 | 每服务消费者最大并发调用限制 | 2.0.5以上版本 | +| executes | <methodName>.executes | int | 可选 | 0 | 性能调优 | 每服务每方法最大使用线程数限制- -,此属性只在<dubbo:method>作为<dubbo:service>子标签时有效 | 2.0.5以上版本 | +| deprecated | <methodName>.deprecated | boolean | 可选 | false | 服务治理 | 服务方法是否过时,此属性只在<dubbo:method>作为<dubbo:service>子标签时有效 | 2.0.5以上版本 | +| sticky | <methodName>.sticky | boolean | 可选 | false | 服务治理 | 设置true 该接口上的所有方法使用同一个provider.如果需要更复杂的规则,请使用路由 | 2.0.6以上版本 | +| return | <methodName>.return | boolean | 可选 | true | 性能调优 | 方法调用是否需要返回值,async设置为true时才生效,如果设置为true,则返回future,或回调onreturn等方法,如果设置为false,则请求发送成功后直接返回Null | 2.0.6以上版本 | +| oninvoke | attribute属性,不在URL中体现 | String | 可选 | | 性能调优 | 实例执行前拦截 | 2.0.6以上版本 | +| onreturn | attribute属性,不在URL中体现 | String | 可选 | | 性能调优 | 实例执行返回后拦截 | 2.0.6以上版本 | +| onthrow | attribute属性,不在URL中体现 | String | 可选 | | 性能调优 | 实例执行有异常拦截 | 2.0.6以上版本 | +| oninvokeMethod | attribute属性,不在URL中体现 | String | 可选 | | 性能调优 | 方法执行前拦截 | 2.0.6以上版本 | +| onreturnMethod | attribute属性,不在URL中体现 | String | 可选 | | 性能调优 | 方法执行返回后拦截 | 2.0.6以上版本 | +| onthrowMethod | attribute属性,不在URL中体现 | String | 可选 | | 性能调优 | 方法执行有异常拦截 | 2.0.6以上版本 | +| cache | <methodName>.cache | string/boolean | 可选 | | 服务治理 | 以调用参数为key,缓存返回结果,可选:lru, threadlocal, jcache等 | 2.1.0以上版本 | +| validation | <methodName>.validation | boolean | 可选 | | 服务治理 | 是否启用JSR303标准注解验证,如果启用,将对方法参数上的注解进行校验 | 2.1.0以上版本 | + +### argument + +方法参数配置。 + +> 对应的配置类: `org.apache.dubbo.config.ArgumentConfig`。该标签为 `method` 的子标签,用于方法参数的特征描述,比如 XML 格式: + +```xml + + + +``` + +| 属性 | 对应URL参数 | 类型 | 是否必填 | 缺省值 | 作用 | 描述 | 兼容性 | +| --- | --- | ---- | --- | --- | --- | --- | --- | +| index | | int | 必填 | | 标识 | 参数索引 | 2.0.6以上版本 | +| type | | String | 与index二选一 | | 标识 | 通过参数类型查找参数的index | 2.0.6以上版本 | +| callback | <metodName><index>.callback | boolean | 可选 | | 服务治理 | 参数是否为callback接口,如果为callback,服务提供方将生成反向代理,可以从服务提供方反向调用消费方,通常用于事件推送. | 2.0.6以上版本 | + +### parameter + +选项参数配置。 + +> 对应的配置类:`java.util.Map`。同时该标签为 `protocol` 或 `service` 或 `provider` 或 `reference` 或 `consumer` 或 `monitor` 或 `registry` 或 `metadata-config` 或 `config-center` 的子标签,用于配置自定义参数,该配置项将作为扩展点设置自定义参数使用。 + +比如: + +```xml + + + +``` + +或: + +```xml + +``` + +| 属性 | 对应URL参数 | 类型 | 是否必填 | 缺省值 | 作用 | 描述 | 兼容性 | +| --- | --- | ---- | --- | --- | --- | --- | --- | +| key | key | string | 必填 | | 服务治理 | 路由参数键 | 2.0.0以上版本 | +| value | value | string | 必填 | | 服务治理 | 路由参数值 | 2.0.0以上版本 | diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/config/spring/_index.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/config/spring/_index.md new file mode 100644 index 000000000000..03dc67168db4 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/config/spring/_index.md @@ -0,0 +1,10 @@ +--- +aliases: + - /zh/docs3-v2/java-sdk/reference-manual/config/ + - /zh-cn/docs3-v2/java-sdk/reference-manual/config/ +description: Dubbo 配置指南 +linkTitle: Spring +title: 配置手册 +type: docs +weight: 1 +--- diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/config/spring/spring-boot.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/config/spring/spring-boot.md new file mode 100644 index 000000000000..9558dde72565 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/config/spring/spring-boot.md @@ -0,0 +1,93 @@ +--- +aliases: + - /zh/docs3-v2/java-sdk/reference-manual/config/annotation/ + - /zh-cn/docs3-v2/java-sdk/reference-manual/config/annotation/ + - /zh-cn/overview/mannual/java-sdk/reference-manual/config/annotation/ +description: 以 Annotation、Spring Boot 开发 Dubbo 应用 +linkTitle: Spring Boot +title: Spring Boot +type: docs +weight: 3 +--- + +关于 Spring Boot 的注解、基本使用方法等请参考 [使用教程 - Spring Boot](/zh-cn/overview/mannual/java-sdk/tasks/develop/springboot/)。以下是 spring boot 支持的配置详情与 starter 列表。 + +## application.yaml + +以下是 Dubbo 框架支持的配置组件列表,可以在 Spring Boot 配置文件中指定所需配置。 + +### 配置示例 + +```yaml +dubbo: + application: + name: dubbo-springboot-demo-provider + logger: slf4j + protocol: + name: dubbo + port: 50052 + registry: + address: nacos://${nacos.address:127.0.0.1}:8848?username=nacos&password=nacos +``` + +### dubbo +* [**dubbo.application** - `org.apache.dubbo.config.ApplicationConfig`](../../properties#dubboapplication) +* [**dubbo.config-center** - `org.apache.dubbo.config.ConfigCenterConfig`](../../properties#dubboconfig-center) +* [**dubbo.consumer** - `org.apache.dubbo.config.ConsumerConfig`](../../properties#dubboconsumer) +* [**dubbo.metadata-report** - `org.apache.dubbo.config.MetadataReportConfig`](../../properties#dubbometadata-report) +* [**dubbo.protocol** - `org.apache.dubbo.config.ProtocolConfig`](../../properties#dubboprotocol) +* [**dubbo.provider** - `org.apache.dubbo.config.ProviderConfig`](../../properties#dubboprovider) +* [**dubbo.registry** - `org.apache.dubbo.config.RegistryConfig`](../../properties#dubboregistry) +* [**dubbo.metrics** - `org.apache.dubbo.config.MetricsConfig`](../../properties#dubbometrics) +* [**dubbo.tracing** - `org.apache.dubbo.config.TracingConfig`](../../properties#dubbotracing) +* [**dubbo.ssl** - `org.apache.dubbo.config.SslConfig`](../../properties#dubbossl) +* ~~[**dubbo.monitor** - `org.apache.dubbo.config.MonitorConfig`](../../properties#dubbomonitor)~~ +* ~~[**dubbo.module** - `org.apache.dubbo.config.ModuleConfig`](../../properties#dubbomodule)~~ + +### dubbo.metrics +* [**dubbo.metrics.aggregation** - `org.apache.dubbo.config.nested.AggregationConfig`](../../properties#dubbometricsaggregation) +* [**dubbo.metrics.histogram** - `org.apache.dubbo.config.nested.HistogramConfig`](../../properties#dubbometricshistogram) +* [**dubbo.metrics.prometheus** - `org.apache.dubbo.config.nested.PrometheusConfig`](../../properties#dubbometricsprometheus) +* [**dubbo.metrics.prometheus.exporter** - `org.apache.dubbo.config.nested.PrometheusConfig$Exporter`](../../properties#dubbometricsprometheusexporter) +* [**dubbo.metrics.prometheus.pushgateway** - `org.apache.dubbo.config.nested.PrometheusConfig$Pushgateway`](../../properties#dubbometricsprometheuspushgateway) + +### dubbo.tracing +* [**dubbo.tracing.baggage.correlation** - `org.apache.dubbo.config.nested.BaggageConfig$Correlation`](../../properties#dubbotracingbaggage.correlation) +* [**dubbo.tracing.tracing-exporter.otlp-config** - `org.apache.dubbo.config.nested.ExporterConfig$OtlpConfig`](../../properties#dubbotracingtracing-exporterotlp-config) +* [**dubbo.tracing.tracing-exporter.zipkin-config** - `org.apache.dubbo.config.nested.ExporterConfig$ZipkinConfig`](../../properties#dubbotracingtracing-exporterzipkin-config) +* [**dubbo.tracing.baggage** - `org.apache.dubbo.config.nested.BaggageConfig`](../../properties#dubbotracingbaggage) +* [**dubbo.tracing.propagation** - `org.apache.dubbo.config.nested.PropagationConfig`](../../properties#dubbotracingpropagation) +* [**dubbo.tracing.sampling** - `org.apache.dubbo.config.nested.SamplingConfig`](../../properties#dubbotracingsampling) +* [**dubbo.tracing.tracing-exporter** - `org.apache.dubbo.config.nested.ExporterConfig`](../../properties#dubbotracingtracing-exporter) + +## starter列表 + +### dubbo-spring-boot-starter +以下是一些 dubbo-spring-boot-starter 版本对应的 SpringBoot、JDK 依赖: + +| 版本 | 兼容 Spring Boot 范围 | +|-------|---------------| +| 3.3.x | [1.x ~ 3.x) | +| 3.2.x | [1.x ~ 3.x) | +| 3.1.x | [1.x ~ 2.x) | +| 2.7.x | [1.x ~ 2.x) | + +### 其他组件starter + +以下是 Dubbo 官方社区提供的 starter 列表(3.3.0+ 版本),方便在 Spring Boot 应用中快速使用: +* `dubbo-spring-boot-starter`,管理 dubbo 核心依赖,用于识别 application.properties 或 application.yml 中 `dubbo.` 开头的配置项,扫描 @DubboService 等注解。 +* `dubbo-spring-boot-starter3`,管理 dubbo 核心依赖,与 dubbo-spring-boot-starter 相同,支持 spring boot 3.2 版本。 +* `dubbo-nacos-spring-boot-starter`,管理 nacos-client 等依赖,使用 Nacos 作为注册中心、配置中心时引入。 +* `dubbo-zookeeper-spring-boot-starter`,管理 zookeeper、curator 等依赖,使用 Zookeeper 作为注册中心、配置中心时引入(Zookeeper server 3.4 及以下版本使用)。 +* `dubbo-zookeeper-curator5-spring-boot-starter`,管理 zookeeper、curator5 等依赖,使用 Zookeeper 作为注册中心、配置中心时引入。 +* `dubbo-sentinel-spring-boot-starter`,管理 sentinel 等依赖,使用 Sentinel 进行限流降级时引入。 +* `dubbo-seata-spring-boot-starter`,管理 seata 等依赖,使用 Seata 作为分布式事务解决方案时引入。 +* `dubbo-observability-spring-boot-starter`,加入该依赖将自动开启 Dubbo 内置的 metrics 采集,可用于后续的 Prometheus、Grafana 等监控系统。 +* `dubbo-tracing-brave-spring-boot-starter`,管理 brave/zipkin、micrometer 等相关相关依赖,使用 Brave/Zipkin 作为 Tracer,将 Trace 信息 export 到 Zipkin。 +* `dubbo-tracing-otel-otlp-spring-boot-starter`,管理 brave/zipkin、micrometer 等相关相关依赖,使用 OpenTelemetry 作为 Tracer,将 Trace 信息 export 到 OTlp Collector。 +* `dubbo-tracing-otel-zipkin-spring-boot-starter`,管理 brave/zipkin、micrometer 等相关相关依赖,使用 OpenTelemetry 作为 Tracer,将 Trace 信息 export 到 Zipkin。 + +{{% alert title="注意" color="info" %}} +* 关于每个 starter 适配的第三方组件版本,请查看 [组件版本映射表](/zh-cn/overview/mannual/java-sdk/versions/#版本说明)。 +* 每个 starter 都有对应的 application.yml 配置项,请跟随上文 [配置项列表](./#配置示例) 了解使用细节。 +{{% /alert %}} diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/config/spring/xml.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/config/spring/xml.md new file mode 100644 index 000000000000..1296a303ccae --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/config/spring/xml.md @@ -0,0 +1,199 @@ +--- +aliases: + - /zh/docs3-v2/java-sdk/reference-manual/config/xml/ + - /zh-cn/docs3-v2/java-sdk/reference-manual/config/xml/ + - /zh-cn/overview/mannual/java-sdk/reference-manual/config/xml/ +description: 以 Spring XML 开发 Dubbo 应用 +linkTitle: XML 配置 +title: XML 配置 +type: docs +weight: 4 +--- + + +Dubbo 有基于 Spring Schema 扩展的自定义配置组件,XML 支持的配置项与 [配置参考手册](../properties) 中描述的一一对。本文使用的示例请参考 [dubbo-samples-spring-xml](https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-spring-xml) + +## XML完整示例 +### 服务提供者 + +#### 定义服务接口 + +DemoService.java: + +```java +package org.apache.dubbo.demo; + +public interface DemoService { + String sayHello(String name); +} +``` + +#### 在服务提供方实现接口 + +DemoServiceImpl.java: + +```java +package org.apache.dubbo.demo.provider; +import org.apache.dubbo.demo.DemoService; + +public class DemoServiceImpl implements DemoService { + public String sayHello(String name) { + return "Hello " + name; + } +} +``` + +#### 用 Spring 配置声明暴露服务 + +```xml + + + + + + + + + + + + + + + +``` + +#### 加载 Spring 配置 + +```java +public class Application { + public static void main(String[] args) throws InterruptedException { + ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring/dubbo-demo-provider.xml"); + context.start(); + + System.out.println("dubbo service started"); + // to hang up main thread + new CountDownLatch(1).await(); + } +} +``` + +### 服务消费者 + +#### 通过 Spring 配置引用远程服务 + +```xml + + + + + + + + + + + +``` + +#### 加载 Spring 配置,并调用远程服务 + +```java +public class Application { + public static void main(String[] args) throws IOException { + ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring/dubbo-demo-consumer.xml"); + context.start(); + GreetingsService greetingsService = (GreetingsService) context.getBean("greetingsService"); + + String message = greetingsService.sayHi("dubbo"); + System.out.println("Receive result ======> " + message); + System.in.read(); + System.exit(0); + } +} +``` + +## 更多示例 + +### 版本与分组 + +```xml + + +``` + +### 集群容错 +配置 failover 重试次数: + +```xml + + + + + +``` + +### 多协议 + +```xml + + + + + + + + + +``` + +### 多注册中心 +```xml + + + + + + + + + + + +``` + +### 全局默认值 +指定全局默认超时时间,多所有服务生效: + +```xml + + +``` + +基于分组的默认值: + +```xml + + + + + + + + + +``` + + + diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/config/xml.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/config/xml.md deleted file mode 100644 index 5ceb8a8e389a..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/config/xml.md +++ /dev/null @@ -1,123 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/reference-manual/config/xml/ - - /zh-cn/docs3-v2/java-sdk/reference-manual/config/xml/ -description: 以 Spring XML 开发 Dubbo 应用 -linkTitle: XML 配置 -title: XML 配置 -type: docs -weight: 4 ---- - - - - - - -Dubbo 有基于 Spring Schema 扩展的自定义配置组件,使用 XML 能达到的配置能力总体与 [配置参考手册](../properties) 对等。 - - -> [dubbo-samples](https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-spring-xml) - -## 服务提供者 - - -### 定义服务接口 - -DemoService.java: - -```java -package org.apache.dubbo.demo; - -public interface DemoService { - String sayHello(String name); -} -``` - -### 在服务提供方实现接口 - -DemoServiceImpl.java: - -```java -package org.apache.dubbo.demo.provider; -import org.apache.dubbo.demo.DemoService; - -public class DemoServiceImpl implements DemoService { - public String sayHello(String name) { - return "Hello " + name; - } -} -``` - -### 用 Spring 配置声明暴露服务 - -```xml - - - - - - - - - - - - - - - -``` - -### 加载 Spring 配置 - -```java -public class DemoServiceImpl implements DemoService { - @Override - public String sayHello(String name) { - System.out.println("[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "] Hello " + name + - ", request from consumer: " + RpcContext.getContext().getRemoteAddress()); - return "Hello " + name + ", response from provider: " + RpcContext.getContext().getLocalAddress(); - } -} -``` - -## 服务消费者 - -### 通过 Spring 配置引用远程服务 - -```xml - - - - - - - - - - - -``` - -### 加载 Spring 配置,并调用远程服务 - -```java -public class BasicConsumer { - public static void main(String[] args) { - ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring/dubbo-demo-consumer.xml"); - context.start(); - DemoService demoService = (DemoService) context.getBean("demoService"); - String hello = demoService.sayHello("world"); - System.out.println(hello); - } -} -``` diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/1.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/1.md new file mode 100644 index 000000000000..b071c05bcc50 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/1.md @@ -0,0 +1,29 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/0/1/ +- /zh-cn/docs3-v2/java-sdk/faq/0/1/ +- /zh-cn/overview/mannual/java-sdk/faq/0/1/ +description: 0-1 - 线程池资源枯竭 +linkTitle: 0-1 - 线程池资源枯竭 +title: 0-1 - 线程池资源枯竭 +type: docs +weight: 1 +--- + + +服务端的线程资源耗尽了。 +默认情况下,Dubbo 服务端的业务线程数是 200 个。如果多个并发请求量超过了 200,就会拒绝新的请求,抛出此错误。 + +### 可能的原因 +1. Consumer 的并发请求量太大,导致 Provider 端创建的线程数量超限。 +2. 可能 Provider 端在执行业务的时候,由于业务调用外部应用接口,导致线程出现阻塞,从而导致线程池回收不了线程。 + +### 排查和解决步骤 +* 开启 Dubbo 的访问日志功能,排查是否有短时间内大量调用 RPC 服务的情况。 +* 通过 `jps` 和 `jstack` 指令检查线程池中各个线程的状态,看下是否有业务调用外部应用接口造成阻塞。 +* 如果是 Consumer 的并发请求量太大,那么调整 Provider 端的 `dubbo.provider.threads` 参数,将 Dubbo 的线程池的数目调大。 +* 如果 Provider 业务的 QPS 实在太大,目前的服务器数目处理不完,那么增加 Provider 端服务器的数量,让更多的服务器分担压力。 + + +> 这个错误码的 FAQ 页面参考了空冥同学的 [《Dubbo 常见错误及解决方法》](https://github.com/StabilityMan/StabilityGuide/blob/master/docs/diagnosis/plugin/rpc/%E7%B3%BB%E7%BB%9F%E7%A8%B3%E5%AE%9A%E6%80%A7%E2%80%94%E2%80%94Dubbo%E5%B8%B8%E8%A7%81%E9%94%99%E8%AF%AF%E5%8F%8A%E8%A7%A3%E5%86%B3%E6%96%B9%E6%B3%95.md) 。 +所引文章通过 [CC-BY-4.0](http://creativecommons.org/licenses/by/4.0/) 协议赋予了汇编的权利。在此向原作者表示感谢。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/10.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/10.md new file mode 100644 index 000000000000..fa3c0a1e2f19 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/10.md @@ -0,0 +1,25 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/0/10/ +- /zh-cn/docs3-v2/java-sdk/faq/0/10/ +- /zh-cn/overview/mannual/java-sdk/faq/0/10/ +description: 0-10 - 当前调用不在支持 +linkTitle: 0-10 - 当前调用不在支持 +title: 0-10 - 当前调用不在支持 +type: docs +weight: 10 +--- + + + + + + + +### 可能的原因 + +当前调用的方法可能已经被弃用或声明了 `@Deprecated`,不影响执行结果。 + +### 排查和解决步骤 + +请使用其它可替代的 API 方法。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/11.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/11.md new file mode 100644 index 000000000000..2f34f5bb4c8c --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/11.md @@ -0,0 +1,25 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/0/11/ +- /zh-cn/docs3-v2/java-sdk/faq/0/11/ +- /zh-cn/overview/mannual/java-sdk/faq/0/11/ +description: 0-11 - 服务停止失败 +linkTitle: 0-11 - 服务停止失败 +title: 0-11 - 服务停止失败 +type: docs +weight: 11 +--- + + + + + + + +### 可能的原因 + +连接没有及时关闭或内存不足,导致服务在停止时会出现一些异常。 + +### 排查和解决步骤 + +在响应内容完成后进行关闭连接。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/12.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/12.md new file mode 100644 index 000000000000..d698476b0604 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/12.md @@ -0,0 +1,25 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/0/12/ +- /zh-cn/docs3-v2/java-sdk/faq/0/12/ +- /zh-cn/overview/mannual/java-sdk/faq/0/12/ +description: 0-12 - 未知异常 +linkTitle: 0-12 - 未知异常 +title: 0-12 - 未知异常 +type: docs +weight: 12 +--- + + + + + +未知异常,一般为API使用或配置异常 + +### 可能的原因 + +转码异常、不支持的加解密方法等等 + +### 排查和解决步骤 + +可根据堆栈信息,进行业务代码行定位。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/13.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/13.md new file mode 100644 index 000000000000..2fee987fd875 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/13.md @@ -0,0 +1,25 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/0/13/ +- /zh-cn/docs3-v2/java-sdk/faq/0/13/ +- /zh-cn/overview/mannual/java-sdk/faq/0/13/ +description: 0-13 - 指标收集器发生异常 +linkTitle: 0-13 - 指标收集器发生异常 +title: 0-13 - 指标收集器发生异常 +type: docs +weight: 13 +--- + + + + + + + +### 可能的原因 + +指标数据在推送过程中发生错误,推送的服务器连接不上或一些配置错误,目前支持 Prometheus。 + +### 排查和解决步骤 + +请参考配置项参考手册[配置项参考手册](/zh-cn/overview/mannual/java-sdk/reference-manual/config/properties/)。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/14.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/14.md new file mode 100644 index 000000000000..c673e002ce44 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/14.md @@ -0,0 +1,27 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/0/14/ +- /zh-cn/docs3-v2/java-sdk/faq/0/14/ +- /zh-cn/overview/mannual/java-sdk/faq/0/14/ +description: 0-14 - 监控异常 +linkTitle: 0-14 - 监控异常 +title: 0-14 - 监控异常 +type: docs +weight: 14 +--- + + + + + +用来统计 RPC 调用次数和调用耗时时间,扩展接口为 MonitorFactory,对应的实现类为 DubboMonitorFactroy。 + + +### 可能的原因 + +用户可以实现该层的 MonitorFactory 扩展接口,实现自定义监控统计策略。 +在自定义监控统计策略的实现类,发生了业务运行时异常。 + +### 排查和解决步骤 + +检查 `org.apache.dubbo.monitor.MonitorFactory` 接口的业务类,实现方法可能存在代码逻辑错误。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/15.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/15.md new file mode 100644 index 000000000000..17c75ddd70d6 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/15.md @@ -0,0 +1,29 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/0/15/ +- /zh-cn/docs3-v2/java-sdk/faq/0/15/ +- /zh-cn/overview/mannual/java-sdk/faq/0/15/ +description: 0-15 - 加载扩展类时发生异常 +linkTitle: 0-15 - 加载扩展类时发生异常 +title: 0-15 - 加载扩展类时发生异常 +type: docs +weight: 15 +--- + + + + + + + +### 可能的原因 + +1. `clazz` 类并没有实现当前扩展点的接口类。 +2. 扩展名可能是个接口或者不存在。 + +### 排查和解决步骤 + +1. 检查扩展类声明,并没有与之相匹配的扩展实现类。 +2. 扩展实现类需实现扩展点接口类以及方法。 + +

diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/16.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/16.md new file mode 100644 index 000000000000..3ac1e2167b59 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/16.md @@ -0,0 +1,27 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/0/16/ +- /zh-cn/docs3-v2/java-sdk/faq/0/16/ +- /zh-cn/overview/mannual/java-sdk/faq/0/16/ +description: 0-16 - 没有可用的执行器 +linkTitle: 0-16 - 没有可用的执行器 +title: 0-16 - 没有可用的执行器 +type: docs +weight: 16 +--- + + + + + + + +### 可能的原因 + +内部执行器不可用,此时返回空。 + +### 排查和解决步骤 + +不需要进行干预,dubbo 内部会执行`createExecutorIfAbsent` 方法构建一个新的执行器。 + +

diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/17.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/17.md new file mode 100644 index 000000000000..8d4887f156e4 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/17.md @@ -0,0 +1,25 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/0/17/ +- /zh-cn/docs3-v2/java-sdk/faq/0/17/ +- /zh-cn/overview/mannual/java-sdk/faq/0/17/ +description: 0-17 - 执行器在关闭时发生未知异常 +linkTitle: 0-17 - 执行器在关闭时发生未知异常 +title: 0-17 - 执行器在关闭时发生未知异常 +type: docs +weight: 17 +--- + + + + + + + +### 可能的原因 + +可能使用了自定义的执行器,在编写销毁方法时,产生了异常。 + +### 排查和解决步骤 + +检查是否自定义实现 `org.apache.dubbo.common.threadpool.manager.ExecutorRepository`,检查自定义的 `shutdown` 方法。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/18.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/18.md new file mode 100644 index 000000000000..846e60e60923 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/18.md @@ -0,0 +1,25 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/0/18/ +- /zh-cn/docs3-v2/java-sdk/faq/0/18/ +- /zh-cn/overview/mannual/java-sdk/faq/0/18/ +description: 0-18 - 线程池执行器被错误使用 +linkTitle: 0-18 - 线程池执行器被错误使用 +title: 0-18 - 线程池执行器被错误使用 +type: docs +weight: 18 +--- + + + + + + + +### 可能的原因 + +自定义设置了线程数量,系统内部发生了未知异常。 + +### 排查和解决步骤 + +可通过一些第三方的工具或者 `jstack [PID] > jstack.log` 分析堆栈信息,进行定位。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/19.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/19.md new file mode 100644 index 000000000000..aa8fe7ef0b1f --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/19.md @@ -0,0 +1,25 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/0/19/ +- /zh-cn/docs3-v2/java-sdk/faq/0/19/ +- /zh-cn/overview/mannual/java-sdk/faq/0/19/ +description: 0-19 - 处理任务时发生异常 +linkTitle: 0-19 - 处理任务时发生异常 +title: 0-19 - 处理任务时发生异常 +type: docs +weight: 19 +--- + + + + + + + +### 可能的原因 + +自定义业务类处理逻辑不当。 + +### 排查和解决步骤 + +可通过一些第三方的工具或者 `jstack [PID] > jstack.log` 分析堆栈信息,进行定位。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/2.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/2.md new file mode 100644 index 000000000000..f3ce40d87e52 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/2.md @@ -0,0 +1,18 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/0/2/ +- /zh-cn/docs3-v2/java-sdk/faq/0/2/ +- /zh-cn/overview/mannual/java-sdk/faq/0/2/ +description: 0-2 - 非法属性值 +linkTitle: 0-2 - 非法属性值 +title: 0-2 - 非法属性值 +type: docs +weight: 2 +--- + + +### 可能的原因 +这个提示是指用户配置的值与属性本身所需的数据类型并不匹配。比如 `dubbo.comsumer.threads` 属性只能接受数值属性,但是用户所输入的值混入了字母。 + +### 排查和解决步骤 +根据[配置项参考手册](/zh-cn/overview/mannual/java-sdk/reference-manual/config/properties/),查找出错的配置项,检查该项指定的类型,检查是否出现类型不一致的情况。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/20.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/20.md new file mode 100644 index 000000000000..e9c985b73a82 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/20.md @@ -0,0 +1,27 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/0/20/ +- /zh-cn/docs3-v2/java-sdk/faq/0/20/ +- /zh-cn/overview/mannual/java-sdk/faq/0/20/ +description: 0-20 - 存储堆栈信息时发生异常 +linkTitle: 0-20 - 存储堆栈信息时发生异常 +title: 0-20 - 存储堆栈信息时发生异常 +type: docs +weight: 20 +--- + + + + + + + +### 可能的原因 + +1. JVM设置了参数 `-XX:+DisableAttachMechanism` +2. 设置了系统不存在的堆栈转储路径,不存在情况,系统会尝试进行创建,创建时发生了 `SecurityException`, 可能是没有权限。 + +### 排查和解决步骤 + +1. 检查 JVM 是否设置了如上参数。 +2. 检查当前启动服务的账号,是否有权限进行创建文件夹。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/21.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/21.md new file mode 100644 index 000000000000..918053167e85 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/21.md @@ -0,0 +1,24 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/0/21/ +- /zh-cn/docs3-v2/java-sdk/faq/0/21/ +- /zh-cn/overview/mannual/java-sdk/faq/0/21/ +description: 0-21 - 构建的实例过多 +linkTitle: 0-21 - 构建的实例过多 +title: 0-21 - 构建的实例过多 +type: docs +weight: 21 +--- + + + + + + +### 可能的原因 + +一般指 `org.apache.dubbo.common.timer.HashedWheelTimer` 创建的实例过多。 + +### 排查和解决步骤 + +不影响实例的构建,可能存在内存泄露的风险。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/22.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/22.md new file mode 100644 index 000000000000..5067b58c45b5 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/22.md @@ -0,0 +1,31 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/0/22/ +- /zh-cn/docs3-v2/java-sdk/faq/0/22/ +- /zh-cn/overview/mannual/java-sdk/faq/0/22/ +description: 0-22 - 输入输出流异常 +linkTitle: 0-22 - 输入输出流异常 +title: 0-22 - 输入输出流异常 +type: docs +weight: 22 +--- + + + + + + + +### 可能的原因 + +1. 读取不再可用的本地文件。 +2. 尝试读取/写入文件但没有权限。 +3. 尝试写入文件但磁盘空间不再可用。 + +### 排查和解决步骤 + +1. 检查本地文件是否存在。 +2. 检查文件权限。 +3. 检查磁盘空间。 + +可通过一些第三方的工具或者 `jstack [PID] > jstack.log` 分析堆栈信息,进行定位。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/23.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/23.md new file mode 100644 index 000000000000..1f3ed674cbb5 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/23.md @@ -0,0 +1,29 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/0/23/ +- /zh-cn/docs3-v2/java-sdk/faq/0/23/ +- /zh-cn/overview/mannual/java-sdk/faq/0/23/ +description: 0-23 - 序列化数据转换异常 +linkTitle: 0-23 - 序列化数据转换异常 +title: 0-23 - 序列化数据转换异常 +type: docs +weight: 23 +--- + + + + + + + +### 可能的原因 + +1. 待序列化数据中存在循环引用,导致堆栈溢出。 +2. 引用的 jar 包版本低或存在兼容性问题。 + +### 排查和解决步骤 + +1. 如使用 FastJson,去掉 `SerializerFeature.DisableCircularReferenceDetec` +2. 检查下或升级版本进行尝试。 + +可通过一些第三方的工具或者 `jstack [PID] > jstack.log` 分析堆栈信息,进行定位。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/24.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/24.md new file mode 100644 index 000000000000..95cbc29440cf --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/24.md @@ -0,0 +1,27 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/0/24/ +- /zh-cn/docs3-v2/java-sdk/faq/0/24/ +- /zh-cn/overview/mannual/java-sdk/faq/0/24/ +description: 0-24 - 覆盖字段值异常 +linkTitle: 0-24 - 覆盖字段值异常 +title: 0-24 - 覆盖字段值异常 +type: docs +weight: 24 +--- + + + + + + + +### 可能的原因 + +1. 实体类未设置 setter/getter 方法。 +2. 可能存在嵌套的属性。 + +### 排查和解决步骤 + +1. 检查实体类并设置 setter/getter 方法。 +2. 根据堆栈信息,检查是否使用嵌套注解。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/25.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/25.md new file mode 100644 index 000000000000..6c7fb5aa52da --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/25.md @@ -0,0 +1,26 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/0/25/ +- /zh-cn/docs3-v2/java-sdk/faq/0/25/ +- /zh-cn/overview/mannual/java-sdk/faq/0/25/ +description: 0-25 - 加载映射错误 +linkTitle: 0-25 - 加载映射错误 +title: 0-25 - 加载映射错误 +type: docs +weight: 25 +--- + + + + + + + +### 可能的原因 + +文件访问权限不足 + +### 排查和解决步骤 + +检查文件权限。 +可通过一些第三方的工具或者 `jstack [PID] > jstack.log` 分析堆栈信息,进行定位。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/26.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/26.md new file mode 100644 index 000000000000..55d6d86991cd --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/26.md @@ -0,0 +1,24 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/0/26/ +- /zh-cn/docs3-v2/java-sdk/faq/0/26/ +- /zh-cn/overview/mannual/java-sdk/faq/0/26/ +description: 0-26 - 元数据发布服务时的警告信息 +linkTitle: 0-26 - 元数据发布服务时的警告信息 +title: 0-26 - 元数据发布服务时的警告信息 +type: docs +weight: 26 +--- + + + + + + +### 可能的原因 + +元数据在存储接口与应用的映射关系时,显示的提醒类消息。 + +### 排查和解决步骤 + +一般可根据堆栈信息进行分析,也可不处理。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/27.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/27.md new file mode 100644 index 000000000000..35e39155f99e --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/27.md @@ -0,0 +1,24 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/0/27/ +- /zh-cn/docs3-v2/java-sdk/faq/0/27/ +- /zh-cn/overview/mannual/java-sdk/faq/0/27/ +description: 0-27 - 线程池隔离配置异常 +linkTitle: 0-27 - 线程池隔离配置异常 +title: 0-27 - 线程池隔离配置异常 +type: docs +weight: 27 +--- + + + + + + +### 可能的原因 + +未开启应用的线程池隔离能力,但是却在 `ServiceConfig` 中配置了隔离的线程池信息。 + +### 排查和解决步骤 + +配置开启应用的线程池隔离能力:`dubbo.application.executor-management-mode=isolation` diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/28.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/28.md new file mode 100644 index 000000000000..1755794dd97e --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/28.md @@ -0,0 +1,25 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/0/28/ +- /zh-cn/docs3-v2/java-sdk/faq/0/28/ +- /zh-cn/overview/mannual/java-sdk/faq/0/28/ +description: 0-28 - 操作了可能会引起危险的行为 +linkTitle: 0-28 - 危险的行为 +title: 0-28 - 操作了可能会引起危险的行为 +type: docs +weight: 28 +--- + + + + + + +### 可能的原因 + +你执行了以下操作之一: +* 尝试或已经调整了 accesslog 的输出位置 + +### 排查和解决步骤 + +请检查应用配置中的 `accesslog.fixed.path=true` 开关是否处于开启状态,如未开启则可忽略;如果当前是开启状态,则请确认是否 acesslog 路径切换的行为是否为可信任的人所执行,以避免可能的安全风险。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/29.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/29.md new file mode 100644 index 000000000000..8ccd185b72a0 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/29.md @@ -0,0 +1,39 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/0/29/ +- /zh-cn/docs3-v2/java-sdk/faq/0/29/ +- /zh-cn/overview/mannual/java-sdk/faq/0/29/ +description: 0-29 - 未找到Tracer依赖 +linkTitle: 0-29 - 未找到Tracer依赖 +title: 0-29 - 未找到Tracer依赖 +type: docs +weight: 29 +--- + +### 可能的原因 + +你已在配置文件中开启了tracing,但未找到Tracer依赖。 + +目前Tracer支持两种,OpenTelemetry和Brave。 + +### 排查和解决步骤 + +选择一个Tracer依赖到你的项目中: + +```xml + + + io.micrometer + micrometer-tracing-bridge-otel + true + +``` + +```xml + + + io.micrometer + micrometer-tracing-bridge-brave + true + +``` diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/3.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/3.md new file mode 100644 index 000000000000..9ef6a66efdec --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/3.md @@ -0,0 +1,41 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/0/3/ +- /zh-cn/docs3-v2/java-sdk/faq/0/3/ +- /zh-cn/overview/mannual/java-sdk/faq/0/3/ +description: 0-3 - 无法访问缓存路径 +linkTitle: 0-3 - 无法访问缓存路径 +title: 0-3 - 无法访问缓存路径 +type: docs +weight: 3 +--- + + + + + + +其它模块复用了 Common 层的基于文件的缓存机制(目前是元数据模块),而 Common 层的文件缓存机制无法访问它指定的目录。 + +``` +2022-08-29 00:35:00,189 ERROR [org.apache.dubbo.common.cache.FileCacheStoreFactory:?] - [DUBBO] Cache store path can't be created: , dubbo version: , current host: 10.0.1.1, error code: 0-3. This may be caused by inaccessible of cache path, go to https://dubbo.apache.org/faq/0/3 to find instructions. +java.nio.file.FileAlreadyExistsException: [Path] + at java.base/sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:87) + at java.base/sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:103) + at java.base/sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:108) + at java.base/sun.nio.fs.WindowsFileSystemProvider.createDirectory(WindowsFileSystemProvider.java:521) + at java.base/java.nio.file.Files.createDirectory(Files.java:700) + at java.base/java.nio.file.Files.createAndCheckIsDirectory(Files.java:807) + at java.base/java.nio.file.Files.createDirectories(Files.java:753) + at org.apache.dubbo.common.cache.FileCacheStoreFactory.getInstance(FileCacheStoreFactory.java:90) + ... +``` + +### 可能的原因 +1. 多个 Dubbo 进程(或其他 Java 进程)使用了同一个缓存文件。 +2. 由于缓存文件所在目录的文件系统权限问题,导致读写失败。 + +### 排查和解决步骤 +1. 根据下面显示的实际异常找到访问不了的目录,确定下它的文件访问权限。 +2. 确定下是否有别的 Dubbo 实例正在访问这个路径。 +3. 尝试配置 **Java System Property(用 -D 配置的 Java 系统属性)** `dubbo.meta.cache.filePath` 和 `dubbo.mapping.cache.filePath`,将它指定成一个当前用户能够完全控制的目录下。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/4.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/4.md new file mode 100644 index 000000000000..81d308067bb2 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/4.md @@ -0,0 +1,58 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/0/4/ +- /zh-cn/docs3-v2/java-sdk/faq/0/4/ +- /zh-cn/overview/mannual/java-sdk/faq/0/4/ +description: 0-4 - 缓存条目超限 +linkTitle: 0-4 - 缓存条目超限 +title: 0-4 - 缓存条目超限 +type: docs +weight: 4 +--- + + + + + +其它模块复用了 Common 层的基于文件的缓存机制(目前是元数据模块),而 Common 层的文件缓存机制 “发觉” 条目超限。 + + +### 可能的原因 +用户不合理地配置了 **Java System Property** (用 -D 配置的 Java 系统属性) `dubbo.mapping.cache.entrySize` 或者 `dubbo.meta.cache.entrySize` + +**默认值** + + + + + + + + + + + + +
dubbo.mapping.cache.entrySizedubbo.meta.cache.entrySize
10000100
+ +### 排查和解决步骤 +1. 尝试重新配置上述 **Java System Property(用 -D 配置的 Java 系统属性)**。 +2. 如果确实没有配置这些 **System Property**,请到 [GitHub Issue Tracker](https://github.com/apache/dubbo/issues) 下发 Issue。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/5.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/5.md new file mode 100644 index 000000000000..61e8bf0472bd --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/5.md @@ -0,0 +1,33 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/0/5/ +- /zh-cn/docs3-v2/java-sdk/faq/0/5/ +- /zh-cn/overview/mannual/java-sdk/faq/0/5/ +description: 0-5 - 缓存文件大小超限 +linkTitle: 0-5 - 缓存文件大小超限 +title: 0-5 - 缓存文件大小超限 +type: docs +weight: 5 +--- + + + + + +其它模块复用了 Common 层的基于文件的缓存机制(目前是元数据模块),而 Common 层的文件缓存机制 “发觉” 文件大小超限。 + + +### 可能的原因 +1. 用户不合理地配置了 Java System Property (用 -D 配置的 Java 系统属性) `dubbo.mapping.cache.maxFileSize` 或者 `dubbo.meta.cache.maxFileSize` +2. 缓存文件因文件系统或磁盘错误而被破坏。 + + +> `dubbo.mapping.cache.maxFileSize` 和 `dubbo.meta.cache.maxFileSize` 没有显示默认值, +而根据 `org.apache.dubbo.common.cache.FileCacheStore.LimitedLengthBufferedWriter` 的逻辑而查到的最大文件大小的默认值为:`Long.MAX_VALUE` ( 263-1 ) 。 + + + +### 排查和解决步骤 +1. 尝试重新配置上述 **Java System Property(用 -D 配置的 Java 系统属性)**。 +2. 删除缓存文件夹重启 **Provider** 和 **Consumer** (缓存文件夹的位置一般在 `~/.dubbo`。如果配置了 `dubbo.meta.cache.filePath` 和 `dubbo.mapping.cache.filePath` 则为该路径)。 +3. 如果确实没有配置这些 **System Property**,请到 [GitHub Issue Tracker](https://github.com/apache/dubbo/issues) 下发 Issue。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/6.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/6.md new file mode 100644 index 000000000000..a96fca69ec2c --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/6.md @@ -0,0 +1,26 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/0/6/ +- /zh-cn/docs3-v2/java-sdk/faq/0/6/ +- /zh-cn/overview/mannual/java-sdk/faq/0/6/ +description: 0-6 - 线程中断异常 +linkTitle: 0-6 - 线程中断异常 +title: 0-6 - 线程中断异常 +type: docs +weight: 6 +--- + + + + + + + +### 可能的原因 + +运行中的线程在处于 `wait、sleep、join` 时,被显示调用 `interrupt()` + +### 排查和解决步骤 + +正常运行的线程在调用了 `interrupt()` 方法后,将对当前线程中断状态设置为 true,但线程的执行并不会受到影响。 +可根据实际情况进行操作或检查业务代码有无被错误使用。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/7.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/7.md new file mode 100644 index 000000000000..22fa36806e0a --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/7.md @@ -0,0 +1,27 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/0/7/ +- /zh-cn/docs3-v2/java-sdk/faq/0/7/ +- /zh-cn/overview/mannual/java-sdk/faq/0/7/ +description: 0-7 - 未找到反射类 +linkTitle: 0-7 - 未找到反射类 +title: 0-7 - 未找到反射类 +type: docs +weight: 7 +--- + + + + + + + +### 可能的原因 + +1. 一般是 `Class.forName(className)` 执行此方法时,找不到 `className` 当前类。 +2. 业务代码上显示排除了当前 `className` 类,导致加载时未找到。 + +### 排查和解决步骤 + +1. 检查 `Class.forName(className)` 中,`className` 是否存在。 +2. 排查业务代码,有没有使用配置或扫描注解 `exclude` 排除了一些类或包。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/8.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/8.md new file mode 100644 index 000000000000..0d2d78d8056e --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/8.md @@ -0,0 +1,25 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/0/8/ +- /zh-cn/docs3-v2/java-sdk/faq/0/8/ +- /zh-cn/overview/mannual/java-sdk/faq/0/8/ +description: 0-8 - 反射失败 +linkTitle: 0-8 - 反射失败 +title: 0-8 - 反射失败 +type: docs +weight: 8 +--- + + + + + + + +### 可能的原因 + +在反射调用某方法时,未对当前方法设置正确的参数类型值,也就是参数类型不匹配。 + +### 排查和解决步骤 + +检查是否存在未正确设置相匹配的类型值。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/9.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/9.md new file mode 100644 index 000000000000..9746c1eb4a44 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/9.md @@ -0,0 +1,25 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/0/9/ +- /zh-cn/docs3-v2/java-sdk/faq/0/9/ +- /zh-cn/overview/mannual/java-sdk/faq/0/9/ +description: 0-9 - 通知事件失败 +linkTitle: 0-9 - 通知事件失败 +title: 0-9 - 通知事件失败 +type: docs +weight: 9 +--- + + + + + + + +### 可能的原因 + +自定义的监听器,在处理上产生了运行时异常。 + +### 排查和解决步骤 + +检查实现 `org.apache.dubbo.rpc.ExporterListener` 接口的业务类,实现方法可能存在代码逻辑错误。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/99.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/99.md new file mode 100644 index 000000000000..6c97fb8ef714 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/99.md @@ -0,0 +1,24 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/0/99/ +- /zh-cn/docs3-v2/java-sdk/faq/0/99/ +- /zh-cn/overview/mannual/java-sdk/faq/0/99/ +description: 0-99 - 调用了过时 (Deprecated) 的方法 +linkTitle: 0-99 - 调用了过时 (Deprecated) 的方法 +title: 0-99 - 调用了过时 (Deprecated) 的方法 +type: docs +weight: 99 +--- + + + + + + +### 可能的原因 + +用户调用了过时 (Deprecated) 的方法。 + +### 排查和解决步骤 + +检查用户代码有没有调用了什么在目前所用的版本声明为 @Deprecated 的方法,如果有则按照其对应方法替代,如无则忽略即可。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/_index.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/_index.md new file mode 100644 index 000000000000..47f4da13de72 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/0/_index.md @@ -0,0 +1,18 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/0/ +- /zh-cn/docs3-v2/java-sdk/faq/0/ +- /zh-cn/overview/mannual/java-sdk/faq/0/_index/ +description: 0 - Common 层 +linkTitle: 0 - Common 层 +title: 0 - Common 层 +type: docs +weight: 1 +--- + + + + + + +这里主要是用于表示各个层通用的组件上所发生的错误。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/1.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/1.md new file mode 100644 index 000000000000..1008ca725924 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/1.md @@ -0,0 +1,25 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/1/1/ +- /zh-cn/docs3-v2/java-sdk/faq/1/1/ +- /zh-cn/overview/mannual/java-sdk/faq/1/1/ +description: 1-1 - 地址非法 +linkTitle: 1-1 - 地址非法 +title: 1-1 - 地址非法 +type: docs +weight: 1 +--- + + + + + + +此日志可以忽略,服务版本或分组不匹配。仅出现在 zookeeper 注册中心中,在 3.1.7 版本中已经取消此检查。 + +### 可能的原因 +1. Provider 端配置的 `service.group` 和 Consumer 端配置的 `reference.group` (即服务分组的配置)不匹配。 +2. Provider 端配置的 `service.version` 和 Consumer 端配置的 `reference.version` (即服务版本的配置)不匹配。 + +### 排查和解决步骤 +可以忽略,在 3.1.7 版本中已经取消此检查。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/10.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/10.md new file mode 100644 index 000000000000..569d0035c0b6 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/10.md @@ -0,0 +1,26 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/1/10/ +- /zh-cn/docs3-v2/java-sdk/faq/1/10/ +- /zh-cn/overview/mannual/java-sdk/faq/1/10/ +description: 1-10 - 读写注册中心服务缓存失败 +linkTitle: 1-10 - 读写注册中心服务缓存失败 +title: 1-10 - 读写注册中心服务缓存失败 +type: docs +weight: 10 +--- + + + + + + +### 可能的原因 +1. 多个 Dubbo 进程使用了同一个缓存文件。 +2. 在多注册中心的情况下,指定了多个注册中心使用同一文件存储。 + +### 排查和解决步骤 +该错误常与 1-9 错误共同出现。检查是否有多个 Dubbo 进程使用了同一个缓存文件或者是否指定多个注册中心使用同一缓存文件。 + +> 另请参阅 +[注册中心的配置项参考手册](/zh-cn/overview/mannual/java-sdk/reference-manual/config/properties/#registry) diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/11.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/11.md new file mode 100644 index 000000000000..27ac6ef07c89 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/11.md @@ -0,0 +1,24 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/1/11/ +- /zh-cn/docs3-v2/java-sdk/faq/1/11/ +- /zh-cn/overview/mannual/java-sdk/faq/1/11/ +description: 1-11 - 注册服务实例创建失败 +linkTitle: 1-11 - 注册服务实例创建失败 +title: 1-11 - 注册服务实例创建失败 +type: docs +weight: 11 +--- + + + + + + +### 可能的原因 +可能是 Registry 的 SPI/IOC 配置出错导致。 +### 排查和解决步骤 +该错误为 Dubbo 内部错误,如果您遇到可以在 github 创建 Issue 并提供错误信息以及复现步骤,我们将协助您解决问题。 + +> 另请参阅 +[Dubbo社区](https://github.com/apache/dubbo) diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/12.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/12.md new file mode 100644 index 000000000000..7063e0382144 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/12.md @@ -0,0 +1,25 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/1/12/ +- /zh-cn/docs3-v2/java-sdk/faq/1/12/ +- /zh-cn/overview/mannual/java-sdk/faq/1/12/ +description: 1-12 - “注册服务” 的实例均已销毁 +linkTitle: 1-12 - “注册服务” 的实例均已销毁 +title: 1-12 - “注册服务” 的实例均已销毁 +type: docs +weight: 12 +--- + + + + + + +### 可能的原因 +在 Dubbo 优雅停机的过程中,通过调用 `AbstractRegistryFactory` 的 `destroyAll` 进行解注册。 + +销毁 `Registryprotocol` 的 `unexport` 的过程中,会通过 `AbstractRegistryFactory` 的 `getRegistry` 来试图获得已经被销毁的 registry ,这导致了 “注册服务” 的实例均已销毁。 + +### 排查和解决步骤 +> 另请参阅 +[配置项参考手册](/zh-cn/overview/mannual/java-sdk/reference-manual/config/properties/) diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/13.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/13.md new file mode 100644 index 000000000000..40a20e7f6206 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/13.md @@ -0,0 +1,24 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/1/13/ +- /zh-cn/docs3-v2/java-sdk/faq/1/13/ +- /zh-cn/overview/mannual/java-sdk/faq/1/13/ +description: 1-13 - 执行重试任务失败 +linkTitle: 1-13 - 执行重试任务失败 +title: 1-13 - 执行重试任务失败 +type: docs +weight: 13 +--- + + + + + + +### 可能的原因 +1. 注册中心离线。 + +### 排查和解决步骤 + +1. 检查注册中心是否正常工作。 +2. 检查注册中心所在服务器及其网络是否正常工作。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/14.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/14.md new file mode 100644 index 000000000000..44c9cdeba35f --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/14.md @@ -0,0 +1,25 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/1/14/ +- /zh-cn/docs3-v2/java-sdk/faq/1/14/ +- /zh-cn/overview/mannual/java-sdk/faq/1/14/ +description: 1-14 - 动态配置识别失败 +linkTitle: 1-14 - 动态配置识别失败 +title: 1-14 - 动态配置识别失败 +type: docs +weight: 14 +--- + + + + + + +### 可能的原因 + 在使用 dubbo admin 的服务治理功能进行动态配置时,配置文件的内容或者格式不正确会导致无法解析动态配置的内容,产生 1-14 错误。 +### 排查和解决步骤 + 请检查动态配置文件的内容或者格式是否正确。 + + +### 另请参阅 +> [配置项参考手册](/zh-cn/overview/mannual/java-sdk/reference-manual/config/properties/) diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/15.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/15.md new file mode 100644 index 000000000000..fd7cb427f5e5 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/15.md @@ -0,0 +1,25 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/1/15/ +- /zh-cn/docs3-v2/java-sdk/faq/1/15/ +- /zh-cn/overview/mannual/java-sdk/faq/1/15/ +description: 1-15 - 销毁服务失败 +linkTitle: 1-15 - 销毁服务失败 +title: 1-15 - 销毁服务失败 +type: docs +weight: 15 +--- + + + + + + +### 可能的原因 + 在 RegistryDirectory 中销毁所有的 invoker 时抛出异常则可能触发 1-15 错误。 + +### 排查和解决步骤 +该错误为 Dubbo 内部错误,如果您遇到可以在 github 创建 Issue 并提供错误信息以及复现步骤,我们将协助您解决问题。 + + +> 另请参阅 [Dubbo 社区](https://github.com/apache/dubbo) diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/16.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/16.md new file mode 100644 index 000000000000..de182f9073f5 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/16.md @@ -0,0 +1,27 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/1/16/ +- /zh-cn/docs3-v2/java-sdk/faq/1/16/ +- /zh-cn/overview/mannual/java-sdk/faq/1/16/ +description: 1-16 - 存在不支持的类别 +linkTitle: 1-16 - 存在不支持的类别 +title: 1-16 - 存在不支持的类别 +type: docs +weight: 16 +--- + + + + + + +### 可能的原因 + 当注册中心的发生变化时,会 notify 对应的 listener。在 notify 的时候如果 category 非法,则会产生存在不支持的类别。 + + +### 排查和解决步骤 + 该错误为 Dubbo 内部错误,如果您遇到可以在 github 创建 Issue 并提供错误信息以及复现步骤,我们将协助您解决问题。 + + +> 另请参阅 +[Dubbo社区](https://github.com/apache/dubbo) diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/17.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/17.md new file mode 100644 index 000000000000..5b11decd5c40 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/17.md @@ -0,0 +1,26 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/1/17/ +- /zh-cn/docs3-v2/java-sdk/faq/1/17/ +- /zh-cn/overview/mannual/java-sdk/faq/1/17/ +description: 1-17 - metadata Server 失效 +linkTitle: 1-17 - metadata Server 失效 +title: 1-17 - metadata Server 失效 +type: docs +weight: 17 +--- + + + + + + +### 可能的原因 +可能是 metadata 的相关参数配置出现问题,特别是 `metadataServiceProtocol` 和 `metadataServicePort`. + +### 排查和解决步骤 +1. 查看是否和未提供 metadata service 端口同时出现,如果同时出现优先尝试解决未提供 metadata service 端口。**(1-18 FAQ)** +2. 排查 `metadataServicePort` 端口号是否存在冲突问题。Provider 和 Consumer 所配置端口同时存在冲突,会产生 metadata Server 失效。 + +> 另请参阅 +[配置项参考手册](/zh-cn/overview/mannual/java-sdk/reference-manual/config/properties/) diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/18.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/18.md new file mode 100644 index 000000000000..74223b62c157 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/18.md @@ -0,0 +1,26 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/1/18/ +- /zh-cn/docs3-v2/java-sdk/faq/1/18/ +- /zh-cn/overview/mannual/java-sdk/faq/1/18/ +description: 1-18 - 未提供 metadata service 端口 +linkTitle: 1-18 - 未提供 metadata service 端口 +title: 1-18 - 未提供 metadata service 端口 +type: docs +weight: 18 +--- + + + + + + +### 可能的原因 +可能是由于`metadataType`为 local 模式,且 `metadataServicePort` 配置出错。 + +### 排查和解决步骤 +1.检查 Provider 侧的 `metadataType` 属性值。 +2.检查 Provider 侧的 `metadataServicePort` 配置是否正确,特别注意是否和其他应用端口存在冲突。 + +> 另请参阅 +[配置项参考手册](/zh-cn/overview/mannual/java-sdk/reference-manual/config/properties/) diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/19.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/19.md new file mode 100644 index 000000000000..0fc37b8b4270 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/19.md @@ -0,0 +1,26 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/1/19/ +- /zh-cn/docs3-v2/java-sdk/faq/1/19/ +- /zh-cn/overview/mannual/java-sdk/faq/1/19/ +description: 1-19 - K8S监听异常 +linkTitle: 1-19 - K8S监听异常 +title: 1-19 - K8S监听异常 +type: docs +weight: 19 +--- + + + + + + +### 可能的原因 + +1. K8S 自定义的资源类型,配置被修改或已被容器移除。 +2. K8S 容器与服务已断开连接。 + +### 排查和解决步骤 + +1. 检查自定义的资源类型,配置是否正确。语法或可请参考 K8S 的官方文档。 +2. 检查网络是否正常或端口映射是否正确。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/20.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/20.md new file mode 100644 index 000000000000..e7ceded9d8ef --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/20.md @@ -0,0 +1,24 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/1/20/ +- /zh-cn/docs3-v2/java-sdk/faq/1/20/ +- /zh-cn/overview/mannual/java-sdk/faq/1/20/ +description: 1-20 - K8S Pod不存在 +linkTitle: 1-20 - K8S Pod不存在 +title: 1-20 - K8S Pod不存在 +type: docs +weight: 20 +--- + + + + + + +### 可能的原因 +1. 控制器 Pending +2. Pod 可能不存在或已被容器移除。 + +### 排查和解决步骤 + +可通过一些第三方的工具或者 `jstack [PID] > jstack.log` 分析堆栈信息,进行定位。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/21.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/21.md new file mode 100644 index 000000000000..db786def449a --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/21.md @@ -0,0 +1,25 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/1/21/ +- /zh-cn/docs3-v2/java-sdk/faq/1/21/ +- /zh-cn/overview/mannual/java-sdk/faq/1/21/ +description: 1-21 - K8S 无可用服务 +linkTitle: 1-21 - K8S 无可用服务 +title: 1-21 - K8S 无可用服务 +type: docs +weight: 21 +--- + + + + + + +### 可能的原因 + +1. 当前服务未正确加载。 +2. 配置的Pod确实不存在当前实例服务。 + +### 排查和解决步骤 + +可通过一些第三方的工具或者 `jstack [PID] > jstack.log` 分析堆栈信息,进行定位。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/22.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/22.md new file mode 100644 index 000000000000..a40dcae5873a --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/22.md @@ -0,0 +1,24 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/1/22/ +- /zh-cn/docs3-v2/java-sdk/faq/1/22/ +- /zh-cn/overview/mannual/java-sdk/faq/1/22/ +description: 1-22 - K8S 配置地址错误 +linkTitle: 1-22 - K8S 配置地址错误 +title: 1-22 - K8S 配置地址错误 +type: docs +weight: 22 +--- + + + + + + +### 可能的原因 + +K8S url 配置错误,无法正常访问。 + +### 排查和解决步骤 + +检查 K8S url 配置信息,确保端口映射也可正常访问。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/26.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/26.md new file mode 100644 index 000000000000..b1d6cfcdd05c --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/26.md @@ -0,0 +1,24 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/1/26/ +- /zh-cn/docs3-v2/java-sdk/faq/1/26/ +- /zh-cn/overview/mannual/java-sdk/faq/1/26/ +description: 1-26 - xDS 证书生成失败 +linkTitle: 1-26 - xDS 证书生成失败 +title: 1-26 - xDS 证书生成失败 +type: docs +weight: 26 +--- + + + + + + +### 可能的原因 + +系统可能不支持算法 `secp256r1` 和 `RSA` 生成证书。 + +### 排查和解决步骤 + +检测操作系统是否支持 `secp256r1` 和 `RSA` 算法。需下载对于的 dll 文件或 lib diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/27.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/27.md new file mode 100644 index 000000000000..55f37967e2c2 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/27.md @@ -0,0 +1,24 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/1/27/ +- /zh-cn/docs3-v2/java-sdk/faq/1/27/ +- /zh-cn/overview/mannual/java-sdk/faq/1/27/ +description: 1-27 - K8S监听异常 +linkTitle: 1-27 - K8S监听异常 +title: 1-27 - K8S监听异常 +type: docs +weight: 27 +--- + + + + + + +### 可能的原因 + +系统可能不支持算法 `secp256r1` 和 `RSA` 生成证书。 + +### 排查和解决步骤 + +检测操作系统是否支持 `secp256r1` 和 `RSA` 算法。需下载对于的 dll 文件或 lib diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/28.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/28.md new file mode 100644 index 000000000000..a3eeaf89dd2e --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/28.md @@ -0,0 +1,24 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/1/28/ +- /zh-cn/docs3-v2/java-sdk/faq/1/28/ +- /zh-cn/overview/mannual/java-sdk/faq/1/28/ +description: 1-28 - xDS 存根错误 +linkTitle: 1-28 - xDS 存根错误 +title: 1-28 - xDS 存根错误 +type: docs +weight: 28 +--- + + + + + + +### 可能的原因 + +当前 pod 或已宕机。 + +### 排查和解决步骤 + +可通过一些第三方的工具或者 `jstack [PID] > jstack.log` 分析堆栈信息,进行定位。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/29.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/29.md new file mode 100644 index 000000000000..802658d09e25 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/29.md @@ -0,0 +1,25 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/1/29/ +- /zh-cn/docs3-v2/java-sdk/faq/1/29/ +- /zh-cn/overview/mannual/java-sdk/faq/1/29/ +description: 1-29 - xDS 读取文件失败 +linkTitle: 1-29 - xDS 读取文件失败 +title: 1-29 - xDS 读取文件失败 +type: docs +weight: 29 +--- + + + + + + +### 可能的原因 + +网络断开或目标文件此时已损坏。 + +### 排查和解决步骤 + +1. 网络是否正常。 +2. 可通过一些第三方的工具或者 `jstack [PID] > jstack.log` 分析堆栈信息,进行定位。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/3.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/3.md new file mode 100644 index 000000000000..05d05db1d85b --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/3.md @@ -0,0 +1,23 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/1/3/ +- /zh-cn/docs3-v2/java-sdk/faq/1/3/ +- /zh-cn/overview/mannual/java-sdk/faq/1/3/ +description: 1-3 - URL 销毁失败 +linkTitle: 1-3 - URL 销毁失败 +title: 1-3 - URL 销毁失败 +type: docs +weight: 3 +--- + + + + + + +### 可能的原因 +当`FrameworkExecutorRepository`被销毁以后,调用`CacheableFailbackRegistry.evictURLCache`会导致销毁失败,产生错误码。 + +### 排查和解决步骤 + +> 另请参阅 [配置项参考手册](/zh-cn/overview/mannual/java-sdk/reference-manual/config/properties/) diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/30.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/30.md new file mode 100644 index 000000000000..c2e83cc52d07 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/30.md @@ -0,0 +1,28 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/1/30/ +- /zh-cn/docs3-v2/java-sdk/faq/1/30/ +- /zh-cn/overview/mannual/java-sdk/faq/1/30/ +description: 1-30 - xDS 请求失败 +linkTitle: 1-30 - xDS 请求失败 +title: 1-30 - xDS 请求失败 +type: docs +weight: 30 +--- + + + + + + +### 可能的原因 + +1. 版本可能不一致或不兼容。 +2. 读取数据时超时。 +3. 参数配置有问题。 + +### 排查和解决步骤 + +1. 可根据第三方官网介绍进行适配。 +2. 确认是否是超时时间设置过短或服务端存在问题。 +3. 检测端口的映射关系是否正确。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/31.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/31.md new file mode 100644 index 000000000000..59cd265f6ae2 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/31.md @@ -0,0 +1,26 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/1/31/ +- /zh-cn/docs3-v2/java-sdk/faq/1/31/ +- /zh-cn/overview/mannual/java-sdk/faq/1/31/ +description: 1-31 - xDS 响应失败 +linkTitle: 1-31 - xDS 响应失败 +title: 1-31 - xDS 响应失败 +type: docs +weight: 31 +--- + + + + + + +### 可能的原因 + +1. 客户端服务已断开与服务端的连接。 +2. 服务端不可用或已脱机。 + +### 排查和解决步骤 + +1. 排查服务端是否已脱机或客户端的网络断开。 +2. 排查服务端服务是否正常,并可通过网络进行接口请求。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/32.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/32.md new file mode 100644 index 000000000000..0c2ab9d7cb20 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/32.md @@ -0,0 +1,28 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/1/32/ +- /zh-cn/docs3-v2/java-sdk/faq/1/32/ +- /zh-cn/overview/mannual/java-sdk/faq/1/32/ +description: 1-32 - xDS Channel 初始化失败 +linkTitle: 1-32 - xDS Channel 初始化失败 +title: 1-32 - xDS Channel 初始化失败 +type: docs +weight: 32 +--- + + + + + + +### 可能的原因 + +1. 版本可能不一致或不兼容。 +2. 读取数据时超时。 +3. 参数配置有问题。 + +### 排查和解决步骤 + +1. 可根据第三方官网介绍进行适配。 +2. 确认是否是超时时间设置过短或服务端存在问题。 +3. 检测端口的映射关系是否正确。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/33.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/33.md new file mode 100644 index 000000000000..06ee64f207fc --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/33.md @@ -0,0 +1,26 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/1/33/ +- /zh-cn/docs3-v2/java-sdk/faq/1/33/ +- /zh-cn/overview/mannual/java-sdk/faq/1/33/ +description: 1-33 - xDS 服务发现初始化失败 +linkTitle: 1-33 - xDS 服务发现初始化失败 +title: 1-33 - xDS 服务发现初始化失败 +type: docs +weight: 33 +--- + + + + + + +### 可能的原因 + +1. xDS 模式下的注册中心,地址配置错误。 +2. 防火墙及第三方防护软件,导致无法对外提供连接。 + +### 排查和解决步骤 + +1. 检查 xDS 配置是否正确,检查 Istio 状态是否正常。 +2. 检查防火墙配置或使用 cmd 的 `ping` 命令进行基本检测。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/34.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/34.md new file mode 100644 index 000000000000..12a92898a06a --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/34.md @@ -0,0 +1,24 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/1/34/ +- /zh-cn/docs3-v2/java-sdk/faq/1/34/ +- /zh-cn/overview/mannual/java-sdk/faq/1/34/ +description: 1-34 - xDS 解析发生错误 +linkTitle: 1-34 - xDS 解析发生错误 +title: 1-34 - xDS 解析发生错误 +type: docs +weight: 34 +--- + + + + + + +### 可能的原因 + +xDS 协议内容存在错误。 + +### 排查和解决步骤 + +可根据堆栈打印的 Endpoints List 进行原因定位。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/35.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/35.md new file mode 100644 index 000000000000..b44713ebfc1d --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/35.md @@ -0,0 +1,26 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/1/35/ +- /zh-cn/docs3-v2/java-sdk/faq/1/35/ +- /zh-cn/overview/mannual/java-sdk/faq/1/35/ +description: 1-35 - ZK 异常 +linkTitle: 1-35 - ZK 异常 +title: 1-35 - ZK 异常 +type: docs +weight: 35 +--- + + + + + + +### 可能的原因 + +1. ZK 无法连接里或连接超时。 +2. ZNode 在创建时已存在。 + +### 排查和解决步骤 + +1. 检查 ZK 配置 IP 和 端口号是否正确。可使用第三方工具 ZooInspector 进行连接测试。 +2. 根据堆栈提醒 ZNode 信息进行判断,是否可清理当前节点。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/36.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/36.md new file mode 100644 index 000000000000..e6c865194246 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/36.md @@ -0,0 +1,22 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/1/36/ +- /zh-cn/docs3-v2/java-sdk/faq/1/36/ +- /zh-cn/overview/mannual/java-sdk/faq/1/36/ +description: 1-36 - 未知异常 +linkTitle: 1-36 - 未知异常 +title: 1-36 - 未知异常 +type: docs +weight: 36 +--- + + + + + + +### 可能的原因 +该错误码的意义已经调整。对于 Dubbo 3.1.4、3.2.0-beta.3 及其之前的版本的该错误码的出错,请参考错误码 [99-0](/zh-cn/overview/mannual/java-sdk/faq/99/0/)。 + +### 排查和解决步骤 +(该错误码目前空缺) diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/37.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/37.md new file mode 100644 index 000000000000..7251ac02312e --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/37.md @@ -0,0 +1,24 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/1/37/ +- /zh-cn/docs3-v2/java-sdk/faq/1/37/ +- /zh-cn/overview/mannual/java-sdk/faq/1/37/ +description: 1-37 - Nacos 异常 +linkTitle: 1-37 - Nacos 异常 +title: 1-37 - Nacos 异常 +type: docs +weight: 37 +--- + + + + + + +### 可能的原因 + +Nacos 配置信息未正确配置。 + +### 排查和解决步骤 + +检查配置 Nacos 的 ip 和端口号是否正确,如果开启了 Nacos 的安全认证,检查用户名和密码配置是否正确。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/38.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/38.md new file mode 100644 index 000000000000..39140dc17469 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/38.md @@ -0,0 +1,25 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/1/38/ +- /zh-cn/docs3-v2/java-sdk/faq/1/38/ +- /zh-cn/overview/mannual/java-sdk/faq/1/38/ +description: 1-38 - Socket 连接异常 +linkTitle: 1-38 - Socket 连接异常 +title: 1-38 - Socket 连接异常 +type: docs +weight: 38 +--- + + + + + + +### 可能的原因 + +1. 连接被拒绝。 +2. 连接已经关闭。 + +### 排查和解决步骤 + +可通过一些第三方的工具或者 `jstack [PID] > jstack.log` 分析堆栈信息,进行定位。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/39.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/39.md new file mode 100644 index 000000000000..ec4c03a808e4 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/39.md @@ -0,0 +1,26 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/1/39/ +- /zh-cn/docs3-v2/java-sdk/faq/1/39/ +- /zh-cn/overview/mannual/java-sdk/faq/1/39/ +description: 1-39 - 获取元数据失败 +linkTitle: 1-39 - 获取元数据失败 +title: 1-39 - 获取元数据失败 +type: docs +weight: 39 +--- + + + + + + +### 可能的原因 + +1. 元数据中心已与应用服务断开连接。 +2. 元数据中心的数据或已被修改。 + +### 排查和解决步骤 + +1. 检查网络通信是否正常,可使用一些简单的 cmd 命令进行检测,如 `ping` 等。 +2. 通过第三方工具进行连接,以及内容的查看。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/4.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/4.md new file mode 100644 index 000000000000..7ff6c3c87f59 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/4.md @@ -0,0 +1,28 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/1/4/ +- /zh-cn/docs3-v2/java-sdk/faq/1/4/ +- /zh-cn/overview/mannual/java-sdk/faq/1/4/ +description: 1-4 - 空地址 +linkTitle: 1-4 - 空地址 +title: 1-4 - 空地址 +type: docs +weight: 4 +--- + + + + + + +### 可能的原因 +1. registry.integration.RegistryDirectory 中的1-4错误是refreshInvoker过程中invokerUrls为空导致的,可以忽略。 +2. registry.support.CacheableFailbackRegistry 中的1-4错误可能是consumer和provider不匹配,并且关闭了“空保护”所导致。 + +### 排查和解决步骤 +1. 确保 Provider 和 Consumer 端的服务分组配置相对应。 +2. 确保 Provider 和 Consumer 端的服务版本配置相对应。 +3. 检查注册中心的`enable-empty-protection`是否为true(默认为true)。 + +> 另请参阅 +[配置项参考手册](/zh-cn/overview/mannual/java-sdk/reference-manual/config/properties/) diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/40.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/40.md new file mode 100644 index 000000000000..8616825fdfc4 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/40.md @@ -0,0 +1,26 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/1/40/ +- /zh-cn/docs3-v2/java-sdk/faq/1/40/ +- /zh-cn/overview/mannual/java-sdk/faq/1/40/ +description: 1-40 - 路由等待时间过长 +linkTitle: 1-40 - 路由等待时间过长 +title: 1-40 - 路由等待时间过长 +type: docs +weight: 40 +--- + + + + + + +### 可能的原因 + +路由计算的时间过长,导致地址通知无法等待到一个合适的时间进行地址更新。 + +### 排查和解决步骤 + +1. 检查应用 QPS,如果 QPS 非常高,这个是预期的日志 +2. 检查自定义路由的实现,排查是否有异常实现,例如死锁、死循环等 +3. 可通过一些第三方的工具或者 `jstack [PID] > jstack.log` 分析堆栈信息,进行定位。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/41.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/41.md new file mode 100644 index 000000000000..70ed5ce565e5 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/41.md @@ -0,0 +1,24 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/1/41/ +- /zh-cn/docs3-v2/java-sdk/faq/1/41/ +- /zh-cn/overview/mannual/java-sdk/faq/1/41/ +description: 1-41 - Istio 异常 +linkTitle: 1-41 - Istio 异常 +title: 1-41 - Istio 异常 +type: docs +weight: 41 +--- + + + + + + +### 可能的原因 + +获取 istio 的配置文件失败 + +### 排查和解决步骤 + +检查应用是否部署在 Kubernetes Pod 环境中,目前暂不支持 VM 部署。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/42.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/42.md new file mode 100644 index 000000000000..0ae6ae4e1c65 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/42.md @@ -0,0 +1,19 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/1/42/ +- /zh-cn/docs3-v2/java-sdk/faq/1/42/ +- /zh-cn/overview/mannual/java-sdk/faq/1/42/ +description: 1-42 - Nacos 存在低版本服务 +linkTitle: 1-42 - Nacos 存在低版本服务 +title: 1-42 - Nacos 存在低版本服务 +type: docs +weight: 42 +--- + +### 可能的原因 + +Nacos 注册中心订阅到了老版本的服务,通常是服务端 Dubbo 版本低于 2.7.3 导致的。 + +### 排查和解决步骤 + +升级服务端到最新稳定版本。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/5.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/5.md new file mode 100644 index 000000000000..0856e38ede3e --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/5.md @@ -0,0 +1,24 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/1/5/ +- /zh-cn/docs3-v2/java-sdk/faq/1/5/ +- /zh-cn/overview/mannual/java-sdk/faq/1/5/ +description: 1-5 - 接收到没有任何参数的 URL +linkTitle: 1-5 - 接收到没有任何参数的 URL +title: 1-5 - 接收到没有任何参数的 URL +type: docs +weight: 5 +--- + + + + + + +### 可能的原因 +在调用 `CacheableFailbackRegistry.toUrlsWithoutEmpty` 时,若传入的参数 `Collectionproviders` 中存在某个 provider 其没有任何参数的话,就会接收到没有任何参数的 URL。 +### 排查和解决步骤 +该错误为 Dubbo 内部错误,如果您遇到可以在 github 创建 Issue 并提供错误信息以及复现步骤,我们将协助您解决问题。 + +> 另请参阅 +[Dubbo社区](https://github.com/apache/dubbo) diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/6.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/6.md new file mode 100644 index 000000000000..c958f75f0418 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/6.md @@ -0,0 +1,25 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/1/6/ +- /zh-cn/docs3-v2/java-sdk/faq/1/6/ +- /zh-cn/overview/mannual/java-sdk/faq/1/6/ +description: 1-6 - 清空URL缓存出错 +linkTitle: 1-6 - 清空URL缓存出错 +title: 1-6 - 清空URL缓存出错 +type: docs +weight: 6 +--- + + + + + + +### 可能的原因 +在`CacheableFailbackRegistry.RemovalTask`清空 url 缓存时候出错将会触发清空 URL 缓存出错。 + +### 排查和解决步骤 +该错误为 Dubbo 内部错误,如果您遇到可以在 github 创建 **issues** 并提供错误信息以及复现步骤,我们将协助您解决问题。 + +> 另请参阅 +[Dubbo社区](https://github.com/apache/dubbo) diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/7.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/7.md new file mode 100644 index 000000000000..03355ae06d72 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/7.md @@ -0,0 +1,25 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/1/7/ +- /zh-cn/docs3-v2/java-sdk/faq/1/7/ +- /zh-cn/overview/mannual/java-sdk/faq/1/7/ +description: 1-7 - 通知注册事件失败 +linkTitle: 1-7 - 读写注册中心服务缓存失败 +title: 1-7 - 通知注册事件失败 +type: docs +weight: 7 +--- + + + + + + +### 可能的原因 + +1. 在应用于基于 xDS 协议的相关平台时,在更新元数据时,需要通知 consumer ,如果某个 consumer 离线会导致通知失败,并移除对应 consumer 的 listener。 + +### 排查和解决步骤 + +> 另请参阅 +[注册中心-配置项参考手册](/zh-cn/overview/mannual/java-sdk/reference-manual/config/properties/#registry) diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/8.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/8.md new file mode 100644 index 000000000000..cfc916611eab --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/8.md @@ -0,0 +1,28 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/1/8/ +- /zh-cn/docs3-v2/java-sdk/faq/1/8/ +- /zh-cn/overview/mannual/java-sdk/faq/1/8/ +description: 1-8 - 销毁时注销(取消订阅)地址失败 +linkTitle: 1-8 - 销毁时注销(取消订阅)地址失败 +title: 1-8 - 销毁时注销(取消订阅)地址失败 +type: docs +weight: 8 +--- + + + + + + +### 可能的原因 +1. 可能是注册中心宕机导致造成的消费者注销或者取消订阅时出现错误。 +2. 可能是对应的 provider 未能成功发布。 + +### 排查和解决步骤 +1. 排查注册中心是否在正常运行。 +2. 排查 provider 是否成功发布。 +3. 排查 provider 的注册中心相关参数比如 `registry` `config-center` `metadata-report`是否配置正确。 + +> 另请参阅 +[配置项参考手册](/zh-cn/overview/mannual/java-sdk/reference-manual/config/properties/) diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/9.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/9.md new file mode 100644 index 000000000000..8fbeab0ac0e0 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/9.md @@ -0,0 +1,35 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/1/9/ +- /zh-cn/docs3-v2/java-sdk/faq/1/9/ +- /zh-cn/overview/mannual/java-sdk/faq/1/9/ +description: 1-9 - 读写注册中心服务缓存失败 +linkTitle: 1-9 - 读写注册中心服务缓存失败 +title: 1-9 - 读写注册中心服务缓存失败 +type: docs +weight: 9 +--- + + + + + + +### 可能的原因 +1. 多个 Dubbo 进程(或其他 Java 进程)使用了同一个缓存文件。 +2. 由于缓存文件所在目录的文件系统权限问题,导致读写失败。 +3. `dubbo.registry.file` 的值输入错误。 +4. 不小心指定了两个注册中心使用同一文件存储。 + +> **提示:** +如未指定 `dubbo.registry.file`,则注册中心服务缓存路径默认为 `~/.dubbo` 目录 +(其中 `~` 为用户的 HOME 目录) + +### 排查和解决步骤 +1. 检查 `dubbo.registry.file` 的值有无拼写错误。 +2. 检查是否有其它进程使用了同一份缓存文件。 +3. 如果指定了 `dubbo.registry.file`,那么检查下它在文件系统的权限。 +4. 排查是否出现了“两个注册中心使用了同一文件存储” 这一情况,如果出现则调整。 + +> 另请参阅 +[注册中心的配置项参考手册](/zh-cn/overview/mannual/java-sdk/reference-manual/config/properties/#registry) diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/_index.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/_index.md new file mode 100755 index 000000000000..9dd655306eb2 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/1/_index.md @@ -0,0 +1,18 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/1/ +- /zh-cn/docs3-v2/java-sdk/faq/1/ +- /zh-cn/overview/mannual/java-sdk/faq/1/_index/ +description: 1 - 注册中心层 +linkTitle: 1 - 注册中心层 +title: 1 - 注册中心层 +type: docs +weight: 1 +--- + + + + + + +这里主要是用于表示注册中心层上所发生的错误。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/1.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/1.md new file mode 100644 index 000000000000..1b9d9fcdaa66 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/1.md @@ -0,0 +1,18 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/2/1/ +- /zh-cn/docs3-v2/java-sdk/faq/2/1/ +- /zh-cn/overview/mannual/java-sdk/faq/2/1/ +description: 2-1 - 路由选址执行失败 +linkTitle: 2-1 - 路由选址执行失败 +title: 2-1 - 路由选址执行失败 +type: docs +weight: 1 +--- + + + + + + +## 路由选址执行失败 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/10.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/10.md new file mode 100644 index 000000000000..3c62a2dee2d0 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/10.md @@ -0,0 +1,27 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/2/10/ +- /zh-cn/docs3-v2/java-sdk/faq/2/10/ +- /zh-cn/overview/mannual/java-sdk/faq/2/10/ +description: 2-10 - 调用服务提供方失败 +linkTitle: 2-10 - 调用服务提供方失败 +title: 2-10 - 调用服务提供方失败 +type: docs +weight: 10 +--- + + + + + + +### 可能的原因 + +* Dubbo 调用服务提供方失败,并开始重试。 +* Dubbo 重试调用服务提供方持续失败。 +* Dubbo 重试调用服务提供方达到上限。 + +### 排查和解决步骤 +1. 检查消费方提供方之间网络连接耗时等网络资源。 +2. 通过 telnet 等手段检查提供方对应端口是否能正常响应。 +3. 检查提供方程序是否运行正常。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/11.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/11.md new file mode 100644 index 000000000000..251d5ea348b0 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/11.md @@ -0,0 +1,24 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/2/11/ +- /zh-cn/docs3-v2/java-sdk/faq/2/11/ +- /zh-cn/overview/mannual/java-sdk/faq/2/11/ +description: 2-11 - 标签路由规则不合法 +linkTitle: 2-11 - 标签路由规则不合法 +title: 2-11 - 标签路由规则不合法 +type: docs +weight: 11 +--- + + + + + + +### 可能的原因 + +* 用户配置的标签路由规则不合法。 +* 用户配置的标签路由地址不合法。 + +### 排查和解决步骤 +> 参照社区标签路由配置规范,检查标签路由配置。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/12.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/12.md new file mode 100644 index 000000000000..094d23481627 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/12.md @@ -0,0 +1,23 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/2/12/ +- /zh-cn/docs3-v2/java-sdk/faq/2/12/ +- /zh-cn/overview/mannual/java-sdk/faq/2/12/ +description: 2-12 - 标签路由获取提供方应用名为空 +linkTitle: 2-12 - 标签路由获取提供方应用名为空 +title: 2-12 - 标签路由获取提供方应用名为空 +type: docs +weight: 12 +--- + + + + + + +### 可能的原因 + +* 标签路由从推送提供方地址列表中获取提供方应用名为空。 + +### 排查和解决步骤 +> 该异常为 Dubbo 框架自身异常,请在社区提 Issue ,提供环境现场信息及复现步骤。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/13.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/13.md new file mode 100644 index 000000000000..874df2431a5c --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/13.md @@ -0,0 +1,23 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/2/13/ +- /zh-cn/docs3-v2/java-sdk/faq/2/13/ +- /zh-cn/overview/mannual/java-sdk/faq/2/13/ +description: 2-13 - 接收加载mesh的路由规则失败 +linkTitle: 2-13 - 接收加载mesh的路由规则失败 +title: 2-13 - 接收加载mesh的路由规则失败 +type: docs +weight: 13 +--- + + + + + + +### 可能的原因 + +* mesh 路由配置的规则不合法,加载异常。 + +### 排查和解决步骤 +> 检查 mesh 路由规则配置。[mesh示例](/zh-cn/overview/tasks/mesh/)。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/14.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/14.md new file mode 100644 index 000000000000..8f248c5424cf --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/14.md @@ -0,0 +1,24 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/2/14/ +- /zh-cn/docs3-v2/java-sdk/faq/2/14/ +- /zh-cn/overview/mannual/java-sdk/faq/2/14/ +description: 2-14 - 脚本路由执行失败 +linkTitle: 2-14 - 脚本路由执行失败 +title: 2-14 - 脚本路由执行失败 +type: docs +weight: 14 +--- + + + + + + +### 可能的原因 + +* 脚本路由规则不合法,导致规则解析失败。 +* Dubbo 框架执行脚本失败。 + +### 排查和解决步骤 +检查脚本是否按照规范编写。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/15.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/15.md new file mode 100644 index 000000000000..1c23e9f5bbc4 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/15.md @@ -0,0 +1,23 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/2/15/ +- /zh-cn/docs3-v2/java-sdk/faq/2/15/ +- /zh-cn/overview/mannual/java-sdk/faq/2/15/ +description: 2-15 - 路由规则解析失败 +linkTitle: 2-15 - 路由规则解析失败 +title: 2-15 - 路由规则解析失败 +type: docs +weight: 15 +--- + + + + + + +### 可能的原因 + +* 用户配置的路由规则不合法。 + +### 排查和解决步骤 +排查配置的路由规则。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/16.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/16.md new file mode 100644 index 000000000000..803c1281e95b --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/16.md @@ -0,0 +1,22 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/2/16/ +- /zh-cn/docs3-v2/java-sdk/faq/2/16/ +- /zh-cn/overview/mannual/java-sdk/faq/2/16/ +description: 2-16 - 请求重试多次失败 +linkTitle: 2-16 - 请求重试多次失败 +title: 2-16 - 请求重试多次失败 +type: docs +weight: 16 +--- + + + + + + +### 可能的原因 +提供方异常,导致消费方重试多次失败。 + +### 排查和解决步骤 +排查提供方健康状况。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/17.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/17.md new file mode 100644 index 000000000000..70117de72fdc --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/17.md @@ -0,0 +1,24 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/2/17/ +- /zh-cn/docs3-v2/java-sdk/faq/2/17/ +- /zh-cn/overview/mannual/java-sdk/faq/2/17/ +description: 2-17 - mock请求失败 +linkTitle: 2-17 - mock请求失败 +title: 2-17 - mock请求失败 +type: docs +weight: 17 +--- + + + + + + +### 可能的原因 +* 配置了强制 mock,提示性日志。 +* 执行 mock 请求异常。 + +### 排查和解决步骤 +1. 检查是否配置了强制 mock。 +2. 检查 mock 响应是否正常。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/18.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/18.md new file mode 100644 index 000000000000..9a308e1d626b --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/18.md @@ -0,0 +1,23 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/2/18/ +- /zh-cn/docs3-v2/java-sdk/faq/2/18/ +- /zh-cn/overview/mannual/java-sdk/faq/2/18/ +description: 2-18 - mesh路由规则未被监听 +linkTitle: 2-18 - mesh路由规则未被监听 +title: 2-18 - mesh路由规则未被监听 +type: docs +weight: 18 +--- + + + + + + +### 可能的原因 + +mesh 下发了路由规则,但是该规则未被监听。 + +### 排查和解决步骤 +检查 mesh 路由规则配置是否符合规范。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/19.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/19.md new file mode 100644 index 000000000000..0e87796e5f84 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/19.md @@ -0,0 +1,25 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/2/19/ +- /zh-cn/docs3-v2/java-sdk/faq/2/19/ +- /zh-cn/overview/mannual/java-sdk/faq/2/19/ +description: 2-19 - 异步请求失败 +linkTitle: 2-19 - 异步请求失败 +title: 2-19 - 异步请求失败 +type: docs +weight: 19 +--- + + + + + + +### 可能的原因 + +1. 提供方异常,导致消费方异步请求失败。 +2. 网络异常,导致消费方异步请求失败。 + +### 排查和解决步骤 +1. 排查提供方健康状况。 +2. 排查网络状况。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/2.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/2.md new file mode 100644 index 000000000000..5f105ca07c43 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/2.md @@ -0,0 +1,32 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/2/2/ +- /zh-cn/docs3-v2/java-sdk/faq/2/2/ +- /zh-cn/overview/mannual/java-sdk/faq/2/2/ +description: 2-2 - 没有可用的 Provider(地址找不到) +linkTitle: 2-2 - 没有可用的 Provider(地址找不到) +title: 2-2 - 没有可用的 Provider(地址找不到) +type: docs +weight: 2 +--- + + + + + + +### 可能的原因 +* Provider 服务没启动,或者注册中心(比如 ZooKeeper,Nacos,Consul)宕机了。 +* Dubbo 的服务配置有误差,必须保证服务名,组别 (默认是 Dubbo),version 三者都正确。 +* 访问的环境有误:通常我们会有开发环境、测试环境、线上生产环境等多套环境。有时候发布的服务到了测试环境,而访问调用时却走了开发环境。 + +### 排查和解决步骤 +1. 访问注册中心的 Ops 系统,查询对应的服务是否有提供者列表;同时检查调用者应用所在服务器的日志(一般每种注册服务的客户端都会有对应的日志记录),查看是否有地址信息的推送/拉取记录。 +2. 如无,则表明发布者发布服务失败,检查发布者的应用启动是否成功。 +3. 如有服务,则检查调用者应用所连接的注册中心,确认跟预期的环境要匹配。 +4. 如上述都没有问题,检查是否配置了路由过滤的规则等。 + + +> 这个错误码的 FAQ 页面参考了空冥同学的 [《Dubbo 常见错误及解决方法》](https://github.com/StabilityMan/StabilityGuide/blob/master/docs/diagnosis/plugin/rpc/%E7%B3%BB%E7%BB%9F%E7%A8%B3%E5%AE%9A%E6%80%A7%E2%80%94%E2%80%94Dubbo%E5%B8%B8%E8%A7%81%E9%94%99%E8%AF%AF%E5%8F%8A%E8%A7%A3%E5%86%B3%E6%96%B9%E6%B3%95.md) 。 + +> 所引文章通过 [CC-BY-4.0](http://creativecommons.org/licenses/by/4.0/) 协议赋予了汇编的权利。在此向原作者表示感谢。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/20.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/20.md new file mode 100644 index 000000000000..473387bdb455 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/20.md @@ -0,0 +1,24 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/2/20/ +- /zh-cn/docs3-v2/java-sdk/faq/2/20/ +- /zh-cn/overview/mannual/java-sdk/faq/2/20/ +description: 2-20 - 获取分组结果合并时失败 +linkTitle: 2-20 - 获取分组结果合并时失败 +title: 2-20 - 获取分组结果合并时失败 +type: docs +weight: 20 +--- + + + + + + +### 可能的原因 + +获取分组结果合并时失败。 + +### 排查和解决步骤 + +返回结果时,可能出现业务逻辑上的运行时异常,可根据控制台指定的代码行数进行回溯定位。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/3.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/3.md new file mode 100644 index 000000000000..a4c092c54a1c --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/3.md @@ -0,0 +1,23 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/2/3/ +- /zh-cn/docs3-v2/java-sdk/faq/2/3/ +- /zh-cn/overview/mannual/java-sdk/faq/2/3/ +description: 2-3 - 路由关闭失败 +linkTitle: 2-3 - 路由关闭失败 +title: 2-3 - 路由关闭失败 +type: docs +weight: 3 +--- + + + + + + +### 可能的原因 + +* 用户自定义路由未按规范编写。 + +### 排查和解决步骤 +> 参照社区SPI扩展使用手册,检查用户自定义路由 [《SPI 扩展使用手册》](/zh-cn/overview/mannual/java-sdk/reference-manual/spi/)。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/4.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/4.md new file mode 100644 index 000000000000..06678cdfa875 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/4.md @@ -0,0 +1,23 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/2/4/ +- /zh-cn/docs3-v2/java-sdk/faq/2/4/ +- /zh-cn/overview/mannual/java-sdk/faq/2/4/ +description: 2-4 - Merger接口加载失败 +linkTitle: 2-4 - Merger接口加载失败 +title: 2-4 - Merger接口加载失败 +type: docs +weight: 4 +--- + + + + + + +### 可能的原因 + +* Dubbo 提供了聚合下游所有提供方响应的 SPI 扩展 Merger 接口,Dubbo 在加载用户在自定义扩展 Merger 接口时,加载配置失败。 + +### 排查和解决步骤 +> 参照社区 SPI 扩展使用手册,检查用户自定义扩展 Merger 接口实现 [《SPI 扩展使用手册》](/zh-cn/overview/mannual/java-sdk/reference-manual/spi/)。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/5.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/5.md new file mode 100644 index 000000000000..c26e667df976 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/5.md @@ -0,0 +1,25 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/2/5/ +- /zh-cn/docs3-v2/java-sdk/faq/2/5/ +- /zh-cn/overview/mannual/java-sdk/faq/2/5/ +description: 2-5 - 筛选提供方失败 +linkTitle: 2-5 - 筛选提供方失败 +title: 2-5 - 筛选提供方失败 +type: docs +weight: 5 +--- + + + + + + +### 可能的原因 + +* Dubbo 在负载均衡时会从提供方列表中最终选择一个提供方发起调用,在选择过程中提供方列表变动,发生读写冲突,导致筛选异常。 +* Dubbo 重试机制在调用提供方失败时,会重新筛选另一个提供方发起调用,重新筛选过程发生异常。 + +### 排查和解决步骤 +1. 检查注册中心提供方列表,与对应提供方可用性。 +2. 在社区提 Issue,提供环境现场信息及复现步骤。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/6.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/6.md new file mode 100644 index 000000000000..f48e4b4122c9 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/6.md @@ -0,0 +1,24 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/2/6/ +- /zh-cn/docs3-v2/java-sdk/faq/2/6/ +- /zh-cn/overview/mannual/java-sdk/faq/2/6/ +description: 2-6 - 条件路由筛选提供方列表为空 +linkTitle: 2-6 - 条件路由筛选提供方列表为空 +title: 2-6 - 条件路由筛选提供方列表为空 +type: docs +weight: 6 +--- + + + + + + +### 可能的原因 + +* 条件路由提供方过滤条件为空。 +* 条件路由在强制降级下筛选提供方列表仍为空。 + +### 排查和解决步骤 +> 参照社区请求路由示例,调整条件路由配置。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/7.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/7.md new file mode 100644 index 000000000000..84d576f3e2e8 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/7.md @@ -0,0 +1,23 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/2/7/ +- /zh-cn/docs3-v2/java-sdk/faq/2/7/ +- /zh-cn/overview/mannual/java-sdk/faq/2/7/ +description: 2-7 - 条件路由执行异常 +linkTitle: 2-7 - 条件路由执行异常 +title: 2-7 - 条件路由执行异常 +type: docs +weight: 7 +--- + + + + + + +### 可能的原因 + +* 条件路由规则未按照规范配置,导致执行条件路由筛选时执行异常。 + +## 排查和解决步骤 +> 参照社区请求路由示例。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/8.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/8.md new file mode 100644 index 000000000000..1d3b1bb140a9 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/8.md @@ -0,0 +1,24 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/2/8/ +- /zh-cn/docs3-v2/java-sdk/faq/2/8/ +- /zh-cn/overview/mannual/java-sdk/faq/2/8/ +description: 2-8 - 提供方返回异常响应 +linkTitle: 2-8 - 提供方返回异常响应 +title: 2-8 - 提供方返回异常响应 +type: docs +weight: 8 +--- + + + + + + +### 可能的原因 + +* 提供方自身处理结果抛出异常。 + +### 排查和解决步骤 + +检查提供方程序是否正常。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/9.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/9.md new file mode 100644 index 000000000000..91b910b44f39 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/9.md @@ -0,0 +1,23 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/2/9/ +- /zh-cn/docs3-v2/java-sdk/faq/2/9/ +- /zh-cn/overview/mannual/java-sdk/faq/2/9/ +description: 2-9 - 增加超时检查任务失败 +linkTitle: 2-9 - 增加超时检查任务失败 +title: 2-9 - 增加超时检查任务失败 +type: docs +weight: 9 +--- + + + + + + +### 可能的原因 + +* Dubbo 框架会对请求调用增加一个超时检查任务,增加超时检查任务失败。 + +### 排查和解决步骤 +> 该异常为 Dubbo 框架自身异常,请在社区提 Issue ,提供环境现场信息及复现步骤。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/_index.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/_index.md new file mode 100644 index 000000000000..a5266b171a98 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/2/_index.md @@ -0,0 +1,11 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/2/ +- /zh-cn/docs3-v2/java-sdk/faq/2/ +- /zh-cn/overview/mannual/java-sdk/faq/2/_index/ +description: 2 - 路由层 +linkTitle: 2 - 路由层 +title: 2 - 路由层 +type: docs +weight: 2 +--- diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/3/1.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/3/1.md new file mode 100644 index 000000000000..f9b7a9e56537 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/3/1.md @@ -0,0 +1,28 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/3/1/ +- /zh-cn/docs3-v2/java-sdk/faq/3/1/ +- /zh-cn/overview/mannual/java-sdk/faq/3/1/ +description: 3-1 - 将地址转换成 Invoker 失败 +linkTitle: 3-1 - 将地址转换成 Invoker 失败 +title: 3-1 - 将地址转换成 Invoker 失败 +type: docs +weight: 1 +--- + + + + + + +### 可能的原因 + +1. 客户端配置的协议与服务端配置的协议并不匹配。(如客户端配置的协议是 Dubbo 协议,但服务端只能提供 Rest 协议的服务) +2. 注册中心(或配置中心)不可靠,推送了并不合法的数据。 + + + +### 排查和解决步骤 + +1. 检查提供方和消费方双方的协议配置。 +2. 更新注册中心的版本。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/3/2.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/3/2.md new file mode 100644 index 000000000000..dfff87e88304 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/3/2.md @@ -0,0 +1,27 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/3/2/ +- /zh-cn/docs3-v2/java-sdk/faq/3/2/ +- /zh-cn/overview/mannual/java-sdk/faq/3/2/ +description: 3-2 - 发布或推送服务失败 +linkTitle: 3-2 - 发布或推送服务失败 +title: 3-2 - 发布或推送服务失败 +type: docs +weight: 2 +--- + + + + + + +### 可能的原因 + +1. 注册中心无法连接。 +2. 注册中心无法对外提供服务。 + +### 排查和解决步骤 + +1. 服务与注册中心网络是否正常。 +2. 注册中心是否正常启动,并可通过第三方工具进行连接。 +3. 服务引用的版本与注册中心的版本是否存在版本兼容性问题。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/3/3.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/3/3.md new file mode 100644 index 000000000000..37d9e7ed482b --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/3/3.md @@ -0,0 +1,22 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/3/3/ +- /zh-cn/docs3-v2/java-sdk/faq/3/3/ +- /zh-cn/overview/mannual/java-sdk/faq/3/3/ +description: 3-3 - 通过Javassist生成字节码失败 +linkTitle: 3-3 - 通过Javassist生成字节码失败 +title: 3-3 - 通过Javassist生成字节码失败 +type: docs +weight: 3 +--- + + + + + + +### 可能的原因 +该错误码的意义已经调整。对于 Dubbo 3.1.4、3.2.0-beta.3 及其之前的版本的该错误码的出错,请参考错误码 [3-8](/zh-cn/overview/mannual/java-sdk/faq/3/8/)。 + +### 排查和解决步骤 +(该错误码目前空缺) diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/3/4.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/3/4.md new file mode 100644 index 000000000000..2f21d8c4ad12 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/3/4.md @@ -0,0 +1,26 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/3/4/ +- /zh-cn/docs3-v2/java-sdk/faq/3/4/ +- /zh-cn/overview/mannual/java-sdk/faq/3/4/ +description: 3-4 - 客户端发送请求超时 +linkTitle: 3-4 - 客户端发送请求超时 +title: 3-4 - 客户端发送请求超时 +type: docs +weight: 4 +--- + + + + + + +### 可能的原因 + +1. 客户端连接数过高,响应较慢, 无法及时向服务端发出请求。 +2. 网络的一些原因。 + +### 排查和解决步骤 + +1. 网络是否正常。 +2. 可通过一些第三方的工具或者`jstack [PID] > jstack.log` 分析堆栈信息,进行定位。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/3/5.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/3/5.md new file mode 100644 index 000000000000..52a566957684 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/3/5.md @@ -0,0 +1,26 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/3/5/ +- /zh-cn/docs3-v2/java-sdk/faq/3/5/ +- /zh-cn/overview/mannual/java-sdk/faq/3/5/ +description: 3-5 - 异步响应出现异常 +linkTitle: 3-5 - 异步响应出现异常 +title: 3-5 - 异步响应出现异常 +type: docs +weight: 5 +--- + + + + + + +### 可能的原因 + +1. 业务逻辑确实出现运行时异常。 +2. 网络原因,连接被拒绝。 + +### 排查和解决步骤 + +1. 业务代码请根据堆栈提示行,回溯定位排查。 +2. 检查服务提供方的网络是否正常。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/3/6.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/3/6.md new file mode 100644 index 000000000000..d1f8acf060b1 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/3/6.md @@ -0,0 +1,26 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/3/6/ +- /zh-cn/docs3-v2/java-sdk/faq/3/6/ +- /zh-cn/overview/mannual/java-sdk/faq/3/6/ +description: 3-6 - 代理执行服务发生异常 +linkTitle: 3-6 - 代理执行服务发生异常 +title: 3-6 - 代理执行服务发生异常 +type: docs +weight: 6 +--- + + + + + + +### 可能的原因 + +1. 当前服务参数已显示入参 `deprecated`。 +2. 泛型声明类可能出现此提醒。 + +### 排查和解决步骤 + +1. 确认URL中是否存在显示入参 `deprecated=true` +2. 泛型声明类如果出现此错误,会试图创建没有实际接口类的代理。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/3/7.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/3/7.md new file mode 100644 index 000000000000..92a96644c68e --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/3/7.md @@ -0,0 +1,29 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/3/7/ +- /zh-cn/docs3-v2/java-sdk/faq/3/7/ +- /zh-cn/overview/mannual/java-sdk/faq/3/7/ +description: 3-7 - 服务端响应结果超时 +linkTitle: 3-7 - 服务端响应结果超时 +title: 3-7 - 服务端响应结果超时 +type: docs +weight: 7 +--- + + + + + +服务端未在客户端设定的时间内获得响应。 + +### 可能的原因 + +1. 服务端的业务处理逻辑较复杂,无法在有效时间内响应。 +2. 服务端与客户端的连接断开,网络丢包。 +3. 服务端负荷过高。 + +### 排查和解决步骤 + +1. 检查服务端的业务处理能力是否确实存在性能瓶颈。 +2. 网络是否正常。 +3. 可通过一些第三方的工具或者`jstack [PID] > jstack.log` 分析堆栈信息,进行定位。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/3/8.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/3/8.md new file mode 100644 index 000000000000..7a6a6980fc8b --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/3/8.md @@ -0,0 +1,30 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/3/8/ +- /zh-cn/docs3-v2/java-sdk/faq/3/8/ +- /zh-cn/overview/mannual/java-sdk/faq/3/8/ +description: 3-8 - 代理失败 +linkTitle: 3-8 - 代理失败 +title: 3-8 - 代理失败 +type: docs +weight: 8 +--- + + + + + + +生成动态代理失败。 + +### 可能的原因 + +1. 存在动态类加载 +2. 类格式异常 + +### 排查和解决步骤 + +1. 如果日志中提示 `Fallback to use JDK proxy success`, +则意味着 Dubbo 自动回落到 JDK 代理后成功创建动态代理了,如果程序正常运行,则可以忽略 +2. 如果日志中提示 `Fallback to use JDK proxy is also failed`, +请根据异常堆栈信息检查对应的类加载情况是否正常,可以通过 arthas 等工具辅助排查 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/3/_index.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/3/_index.md new file mode 100644 index 000000000000..80fec2c10bf4 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/3/_index.md @@ -0,0 +1,11 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/3/ +- /zh-cn/docs3-v2/java-sdk/faq/3/ +- /zh-cn/overview/mannual/java-sdk/faq/3/_index/ +description: 3 - 动态代理层 +linkTitle: 3 - 动态代理层 +title: 3 - 动态代理层 +type: docs +weight: 3 +--- diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/1.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/1.md new file mode 100644 index 000000000000..98f5bdcc6d75 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/1.md @@ -0,0 +1,28 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/4/1/ +- /zh-cn/docs3-v2/java-sdk/faq/4/1/ +- /zh-cn/overview/mannual/java-sdk/faq/4/1/ +description: 4-1 - 不支持的协议 +linkTitle: 4-1 - 不支持的协议 +title: 4-1 - 不支持的协议 +type: docs +weight: 1 +--- + + + + + + +### 可能的原因 +这种情况可能出现在自定义 Protocol 的场景下。Dubbo 的 SPI 机制找不到 URL 中所指定的 Protocol。 + + +### 排查和解决步骤 +1. 确定 Consumer 中有服务端所用到的 Protocol 的依赖。 +2. 确定 Protocol 的依赖包的 SPI 配置文件的名字没有写错。 + +> 另请参阅 +[Dubbo SPI 概述](/zh-cn/overview/mannual/java-sdk/reference-manual/spi/overview/) +[协议扩展说明](/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/protocol/) diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/10.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/10.md new file mode 100644 index 000000000000..dc740749ab94 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/10.md @@ -0,0 +1,37 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/4/10/ +- /zh-cn/docs3-v2/java-sdk/faq/4/10/ +- /zh-cn/overview/mannual/java-sdk/faq/4/10/ +description: 4-10 - Triple 序列化结果失败 +linkTitle: 4-10 - Triple 序列化结果失败 +title: 4-10 - Triple 序列化结果失败 +type: docs +weight: 10 +--- + + + + + + +### 可能的原因 + +一般为内部错误。 +见于三种log格式: +1. 在序列化并且发送数据时发生异常,日志格式为 `Serialize triple request failed, service=%s method=%s` +2. 接收到response的reset code时触发,日志格式为:`Triple Client received remote reset errorCode=xxx` +3. 处理response时有异常情况时触发,日志格式为: `Meet Exception on ClientResponseHandler, status code is:xxx` + +### 排查和解决步骤 + +针对第一种错误,是在调用{service}#{method}方法过程中出现的,具体对应到sendMessage,并且该日志与`java.util.concurrent.ExecutionException: org.apache.dubbo.rpc.StatusRpcException: INTERNAL : Serialize request failed`同时出现,排查{method}方法参数中自定义类是否实现序列化接口导致序列化失败 + +针对第二种错误,是Provider端处理发生错误,排查Provider端服务,排查方式参考第一种错误 + +针对第三种错误,仅单元测试使用到,目前用户侧不会出现 + +其次可通过一些第三方的工具或者 `jstack [PID] > jstack.log` 分析堆栈信息,进行定位。 + +> 同时请在社区提交Issue,帮助我们更好的完善Triple +> 直接点击右上角 **提交项目问题** 按钮即可快速链接至Github页面 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/11.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/11.md new file mode 100644 index 000000000000..37704d641f78 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/11.md @@ -0,0 +1,28 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/4/11/ +- /zh-cn/docs3-v2/java-sdk/faq/4/11/ +- /zh-cn/overview/mannual/java-sdk/faq/4/11/ +description: 4-11 - 发起请求失败 +linkTitle: 4-11 - 发起请求失败 +title: 4-11 - 发起请求失败 +type: docs +weight: 11 +--- + + + + + + +### 可能的原因 + +1. 服务方已关闭。 +2. 调用方的 IP 不在服务方的白名单内。 +3. 请求具体的地址服务不存在。 + +### 排查和解决步骤 + +1. 检查服务方启动运行情况。 +2. 检查或使用第三方工具,测试网络环境是否可正常连接。 +3. 根据堆栈的 serviceName, 在管理平台里查看或模拟调用,看是否正常。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/12.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/12.md new file mode 100644 index 000000000000..5eff33dc1d4c --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/12.md @@ -0,0 +1,26 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/4/12/ +- /zh-cn/docs3-v2/java-sdk/faq/4/12/ +- /zh-cn/overview/mannual/java-sdk/faq/4/12/ +description: 4-12 - 创建Triple流失败 +linkTitle: 4-12 - 创建Triple流失败 +title: 4-12 - 创建Triple流失败 +type: docs +weight: 12 +--- + + + + + + +### 可能的原因 + +一般为内部错误。 + +### 排查和解决步骤 + +可通过一些第三方的工具或者 `jstack [PID] > jstack.log` 分析堆栈信息,进行定位。 + +> 同时请在社区提交Issue。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/13.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/13.md new file mode 100644 index 000000000000..864b916ed2dc --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/13.md @@ -0,0 +1,28 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/4/13/ +- /zh-cn/docs3-v2/java-sdk/faq/4/13/ +- /zh-cn/overview/mannual/java-sdk/faq/4/13/ +description: 4-13 - 服务端超时 +linkTitle: 4-13 - 服务端超时 +title: 4-13 - 服务端超时 +type: docs +weight: 13 +--- + + + + + + +### 可能的原因 + +1. 服务端逻辑处理相对耗时。 +2. 服务端负载请求过高,无法响应。 +3. 当前的超时参数设置阈值与现实情况相差较大。 + +### 排查和解决步骤 + +1. 根据接口名称查看是否存在耗时处理情况。 +2. 可监控服务器状态,及服务端调用的服务调用情况。 +3. 尝试将超时参数调大一些。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/14.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/14.md new file mode 100644 index 000000000000..cccf9cb31405 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/14.md @@ -0,0 +1,26 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/4/14/ +- /zh-cn/docs3-v2/java-sdk/faq/4/14/ +- /zh-cn/overview/mannual/java-sdk/faq/4/14/ +description: 4-14 - 响应结果失败 +linkTitle: 4-14 - 响应结果失败 +title: 4-14 - 响应结果失败 +type: docs +weight: 14 +--- + + + + + + +### 可能的原因 + +1. 服务端管道可能因网络原因暂时断开。 +2. 当前使用版本较低或可检查当前的参数配置,是否启用 `send.reconnect=true`, 高版本默认为 true。 + +### 排查和解决步骤 + +1. 检查直连网络是否通畅,有无丢包现象。 +2. 检查上述参数值,或尝试使用高版本。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/15.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/15.md new file mode 100644 index 000000000000..c41c4bc44f63 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/15.md @@ -0,0 +1,22 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/4/15/ +- /zh-cn/docs3-v2/java-sdk/faq/4/15/ +- /zh-cn/overview/mannual/java-sdk/faq/4/15/ +description: 4-15 - 客户端流监听器 +linkTitle: 4-15 - 客户端流监听器 +title: 4-15 - 客户端流监听器 +type: docs +weight: 15 +--- + + + + + + +### 可能的原因 + +当收到服务端的响应之后,客户端流监听器会输出此信息,用于提醒。 + +### 排查和解决步骤 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/16.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/16.md new file mode 100644 index 000000000000..54cffeeac61f --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/16.md @@ -0,0 +1,24 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/4/16/ +- /zh-cn/docs3-v2/java-sdk/faq/4/16/ +- /zh-cn/overview/mannual/java-sdk/faq/4/16/ +description: 4-16 - 服务已关闭 +linkTitle: 4-16 - 服务已关闭 +title: 4-16 - 服务已关闭 +type: docs +weight: 16 +--- + + + + + + +### 可能的原因 + +在错误的状态下继续调用 `org.apache.dubbo.rpc.protocol.tri.service.TriHealthImpl#enterTerminalState` 或者 `org.apache.dubbo.rpc.protocol.ReferenceCountInvokerWrapper#invoke`,在调用时已经是 terminal 或 destory状态。 + +### 排查和解决步骤 + +多次调用上述方法会进行提醒。一般仅用于单元测试。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/17.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/17.md new file mode 100644 index 000000000000..f0add9767594 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/17.md @@ -0,0 +1,26 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/4/17/ +- /zh-cn/docs3-v2/java-sdk/faq/4/17/ +- /zh-cn/overview/mannual/java-sdk/faq/4/17/ +description: 4-17 - 关闭所有调用程序时发生错误 +linkTitle: 4-17 - 关闭所有调用程序时发生错误 +title: 4-17 - 关闭所有调用程序时发生错误 +type: docs +weight: 17 +--- + + + + + + +### 可能的原因 + +一般为内部错误。 + +### 排查和解决步骤 + +可通过一些第三方的工具或者 `jstack [PID] > jstack.log` 分析堆栈信息,进行定位。 + +> 同时请在社区提交issue. diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/18.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/18.md new file mode 100644 index 000000000000..b29fd3250bba --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/18.md @@ -0,0 +1,22 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/4/18/ +- /zh-cn/docs3-v2/java-sdk/faq/4/18/ +- /zh-cn/overview/mannual/java-sdk/faq/4/18/ +description: 4-18 - 无法从调用中获取服务模型 +linkTitle: 4-18 - 无法从调用中获取服务模型 +title: 4-18 - 无法从调用中获取服务模型 +type: docs +weight: 18 +--- + + + + + + +### 可能的原因 + +当前仅用于单元测试场景,服务模型默认会进行初始化。 + +### 排查和解决步骤 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/19.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/19.md new file mode 100644 index 000000000000..a474cc14ab7f --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/19.md @@ -0,0 +1,26 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/4/19/ +- /zh-cn/docs3-v2/java-sdk/faq/4/19/ +- /zh-cn/overview/mannual/java-sdk/faq/4/19/ +description: 4-19 - 参数值有出错的可能 +linkTitle: 4-19 - 参数值有出错的可能 +title: 4-19 - 参数值有出错的可能 +type: docs +weight: 19 +--- + + + + + + +### 可能的原因 +这个错误码提示参数值可能不再正确。 + +目前出现在同一个协议同时监听多个端口下。由于设计限制,单个协议只能监听一个端口,否则端口配置会被覆盖掉。 + +### 排查和解决步骤 +调整协议和端口的监听关系。 + +> 该错误码的意义已经调整。对于 Dubbo 3.1.4、3.2.0-beta.3 及其之前的版本的该错误码的出错,请参考错误码 [0-2](/zh-cn/overview/mannual/java-sdk/faq/0/2/)。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/2.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/2.md new file mode 100644 index 000000000000..97c6fdf4fbb2 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/2.md @@ -0,0 +1,24 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/4/2/ +- /zh-cn/docs3-v2/java-sdk/faq/4/2/ +- /zh-cn/overview/mannual/java-sdk/faq/4/2/ +description: 4-2 - 序列化优化器初始发生错误 +linkTitle: 4-2 - 序列化优化器初始发生错误 +title: 4-2 - 序列化优化器初始发生错误 +type: docs +weight: 2 +--- + + + + + + +### 可能的原因 + +当前使用了 Kryo 和 FST 的序列化配置。 + +### 排查和解决步骤 + +[Kryo 和 FST 序列化](/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/serialization/) diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/20.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/20.md new file mode 100644 index 000000000000..b51fad776fa7 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/20.md @@ -0,0 +1,24 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/4/20/ +- /zh-cn/docs3-v2/java-sdk/faq/4/20/ +- /zh-cn/overview/mannual/java-sdk/faq/4/20/ +description: 4-20 - 数据解码失败 +linkTitle: 4-20 - 数据解码失败 +title: 4-20 - 数据解码失败 +type: docs +weight: 20 +--- + + + + + + +### 可能的原因 + +只发生在解码阶段,可能服务方和调用方的dubbo版本不匹配。 + +### 排查和解决步骤 + +检查当前使用的 dubbo 版本,尽量保持一致或向下兼容的高版本。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/21.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/21.md new file mode 100644 index 000000000000..d765a4654adf --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/21.md @@ -0,0 +1,28 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/4/21/ +- /zh-cn/docs3-v2/java-sdk/faq/4/21/ +- /zh-cn/overview/mannual/java-sdk/faq/4/21/ +description: 4-21 - 检测到不安全的序列化数据 +linkTitle: 4-21 - 检测到不安全的序列化数据 +title: 4-21 - 检测到不安全的序列化数据 +type: docs +weight: 21 +--- + + + + + + +### 可能的原因 + +当前服务端可能受到攻击或者是 Dubbo 内置的类检查逻辑没有扫描到您所定义的类。 + +### 排查和解决步骤 + +1. 如果请求源是攻击源,请及时进行安全加固。 +2. 如果请求源是预期的,请在 `security/serialize.allowlist` 资源文件中声明您所使用的类名,Dubbo 将自动将其加载到安全列表中。请参考 [类检查机制](/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/security/class-check/) 一文。 + + +> 当前 Dubbo 可以工作在监控模式和限制模式下。监控模式只打印日志,不进行拦截;限制模型将进行拦截。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/3.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/3.md new file mode 100644 index 000000000000..6836b47ad2fd --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/3.md @@ -0,0 +1,24 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/4/3/ +- /zh-cn/docs3-v2/java-sdk/faq/4/3/ +- /zh-cn/overview/mannual/java-sdk/faq/4/3/ +description: 4-3 - 接口引用调用失败 +linkTitle: 4-3 - 接口引用调用失败 +title: 4-3 - 接口引用调用失败 +type: docs +weight: 3 +--- + + + + + + +### 可能的原因 + +根据指定的协议参数,未找到暴露的服务接口或方法。 + +### 排查和解决步骤 + +可根据接口 URL 及方法名称,确认服务端是否存在。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/4.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/4.md new file mode 100644 index 000000000000..4342b3057e04 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/4.md @@ -0,0 +1,26 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/4/4/ +- /zh-cn/docs3-v2/java-sdk/faq/4/4/ +- /zh-cn/overview/mannual/java-sdk/faq/4/4/ +description: 4-4 - 非安全序列化方式 +linkTitle: 4-4 - 非安全序列化方式 +title: 4-4 - 非安全序列化方式 +type: docs +weight: 4 +--- + + + + + + +### 可能的原因 + +当前在使用非安全的序列化器, 并不推荐。具体配置为:`serialization="java"` + +> Java 序列化是不安全的。Dubbo 团队不推荐任何人使用它。如果你仍然想使用它,请遵循 [JEP 290](https://openjdk.java.net/jeps/290) 来设置序列化过滤器,以防止反序列化泄露。 + +### 排查和解决步骤 + +修改`serialization`的参数值. 将 protocol 内的序列化参数值修改为其他,如hessian2,fastjson2等。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/5.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/5.md new file mode 100644 index 000000000000..ccf8ef49de8c --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/5.md @@ -0,0 +1,24 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/4/5/ +- /zh-cn/docs3-v2/java-sdk/faq/4/5/ +- /zh-cn/overview/mannual/java-sdk/faq/4/5/ +description: 4-5 - 流关闭异常 +linkTitle: 4-5 - 流关闭异常 +title: 4-5 - 流关闭异常 +type: docs +weight: 5 +--- + + + + + + +### 可能的原因 + +提示信息,不影响程序的执行结果。 + +### 排查和解决步骤 + +可通过一些第三方的工具或者`jstack [PID] > jstack.log` 分析堆栈信息,进行定位。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/6.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/6.md new file mode 100644 index 000000000000..423246a3566c --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/6.md @@ -0,0 +1,26 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/4/6/ +- /zh-cn/docs3-v2/java-sdk/faq/4/6/ +- /zh-cn/overview/mannual/java-sdk/faq/4/6/ +description: 4-6 - 反序列化失败 +linkTitle: 4-6 - 反序列化失败 +title: 4-6 - 反序列化失败 +type: docs +weight: 6 +--- + + + + + + +### 可能的原因 + +发生在使用自定义的序列化方式的时候,在自定义 SPI `org.apache.dubbo.common.serialize.Serialization` 序列化方法在使用时发生错误。 + +### 排查和解决步骤 + +可通过一些第三方的工具或者 `jstack [PID] > jstack.log` 分析堆栈信息,获取引起错误的对象内容,再配合自定义实现进行修改。 + +> 参考 [序列化扩展](https://cn.dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/serialize/) diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/7.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/7.md new file mode 100644 index 000000000000..a0ce8627b22e --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/7.md @@ -0,0 +1,24 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/4/7/ +- /zh-cn/docs3-v2/java-sdk/faq/4/7/ +- /zh-cn/overview/mannual/java-sdk/faq/4/7/ +description: 4-7 - 关闭客户端时发生错误 +linkTitle: 4-7 - 关闭客户端时发生错误 +title: 4-7 - 关闭客户端时发生错误 +type: docs +weight: 7 +--- + + + + + + +### 可能的原因 + +见于各种 `Connect Client` 进行`close`或者`destory`的时候报错,不影响最终效果。 + +### 排查和解决步骤 + +可通过一些第三方的工具或者 `jstack [PID] > jstack.log` 分析堆栈信息,进行定位。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/8.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/8.md new file mode 100644 index 000000000000..70aa8aafeb22 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/8.md @@ -0,0 +1,24 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/4/8/ +- /zh-cn/docs3-v2/java-sdk/faq/4/8/ +- /zh-cn/overview/mannual/java-sdk/faq/4/8/ +description: 4-8 - 关闭服务端时发生错误 +linkTitle: 4-8 - 关闭服务端时发生错误 +title: 4-8 - 关闭服务端时发生错误 +type: docs +weight: 8 +--- + + + + + + +### 可能的原因 + +与4-7相似,都是发生在close时。 + +### 排查和解决步骤 + +可通过一些第三方的工具或者`jstack [PID] > jstack.log` 分析堆栈信息,进行定位。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/9.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/9.md new file mode 100644 index 000000000000..83c0a2a92fa6 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/9.md @@ -0,0 +1,33 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/4/9/ +- /zh-cn/docs3-v2/java-sdk/faq/4/9/ +- /zh-cn/overview/mannual/java-sdk/faq/4/9/ +description: 4-9 - 解析失败 +linkTitle: 4-9 - 解析失败 +title: 4-9 - 解析失败 +type: docs +weight: 9 +--- + + + + + + +### 可能的原因 + +一般为参数值不符合规则,在强转时发生错误。 +如: + +```java +String timeoutString = httpMetadata.headers().getFirst(TripleHeaderEnum.SERVICE_TIMEOUT.getHeader()); +Long timeout = Long.parseLong(timeoutString); + +Long timeout = GrpcUtils.parseTimeoutToMills(timeoutString); +invocation.put(CommonConstants.TIMEOUT_KEY, timeout); +``` + +### 排查和解决步骤 + +根据堆栈信息提示的 key 名称进行相对应的配置修改到符合转换规则即可。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/_index.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/_index.md new file mode 100644 index 000000000000..c4a3bc2cbb77 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/4/_index.md @@ -0,0 +1,11 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/4/ +- /zh-cn/docs3-v2/java-sdk/faq/4/ +- /zh-cn/overview/mannual/java-sdk/faq/4/_index/ +description: 4 - 协议层 +linkTitle: 4 - 协议层 +title: 4 - 协议层 +type: docs +weight: 4 +--- diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/1.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/1.md new file mode 100644 index 000000000000..df344c117184 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/1.md @@ -0,0 +1,29 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/5/1/ +- /zh-cn/docs3-v2/java-sdk/faq/5/1/ +- /zh-cn/overview/mannual/java-sdk/faq/5/1/ +description: 5-1 - 配置中心连接失败 +linkTitle: 5-1 - 配置中心连接失败 +title: 5-1 - 配置中心连接失败 +type: docs +weight: 1 +--- + + + + + + +### 可能的原因 + +1. 配置中心所在的服务器关机或宕机。 +2. IP 或者端口号写错。 +3. 防火墙错误拦截了配置中心的端口。 + + +### 排查和解决步骤 + +1. 检查配置中心 IP 以及端口的配置。 +2. 检查服务器是否开机,是否正常工作。 +3. 检查防火墙等是否放行配置中心所用的端口。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/10.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/10.md new file mode 100644 index 000000000000..786a46ca1b80 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/10.md @@ -0,0 +1,24 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/5/10/ +- /zh-cn/docs3-v2/java-sdk/faq/5/10/ +- /zh-cn/overview/mannual/java-sdk/faq/5/10/ +description: 5-10 - 服务的注册接口应用程序映射失败 +linkTitle: 5-10 - 服务的注册接口应用程序映射失败 +title: 5-10 - 服务的注册接口应用程序映射失败 +type: docs +weight: 10 +--- + + + + + + +### 可能的原因 + +服务暴露的服务元数据与应用程序不匹配,或被篡改。 + +### 排查和解决步骤 + +检查配置中心的元数据内容是否与应用程序内的匹配。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/11.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/11.md new file mode 100644 index 000000000000..a197e837788d --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/11.md @@ -0,0 +1,28 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/5/11/ +- /zh-cn/docs3-v2/java-sdk/faq/5/11/ +- /zh-cn/overview/mannual/java-sdk/faq/5/11/ +description: 5-11 - 注册实例错误 +linkTitle: 5-11 - 注册实例错误 +title: 5-11 - 注册实例错误 +type: docs +weight: 11 +--- + + + + + + +### 可能的原因 + +1. 配置中心的服务无法连接。 +2. 配置的协议、IP、端口不正确。 +3. 使用配置中心客户端版本与服务端版本冲突,无法建立有效连接。 + +### 排查和解决步骤 + +1. 检查配置中心的服务状态是否正常。 +2. 检查配置的协议、IP、端口不正确。 +3. 检查使用的配置中心客户端版本与服务端版本是否兼容。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/12.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/12.md new file mode 100644 index 000000000000..6bf125d511f7 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/12.md @@ -0,0 +1,28 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/5/12/ +- /zh-cn/docs3-v2/java-sdk/faq/5/12/ +- /zh-cn/overview/mannual/java-sdk/faq/5/12/ +description: 5-12 - 刷新实例和元数据错误 +linkTitle: 5-12 - 刷新实例和元数据错误 +title: 5-12 - 刷新实例和元数据错误 +type: docs +weight: 12 +--- + + + + + + +### 可能的原因 + +1. 配置中心的服务无法连接。 +2. 配置的协议、IP、端口不正确。 +3. 使用配置中心客户端版本与服务端版本冲突,无法建立有效连接。 + +### 排查和解决步骤 + +1. 检查配置中心的服务状态是否正常。 +2. 检查配置的协议、IP、端口不正确。 +3. 检查使用的配置中心客户端版本与服务端版本是否兼容。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/13.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/13.md new file mode 100644 index 000000000000..89a8208887ee --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/13.md @@ -0,0 +1,24 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/5/13/ +- /zh-cn/docs3-v2/java-sdk/faq/5/13/ +- /zh-cn/overview/mannual/java-sdk/faq/5/13/ +description: 5-13 - 无法销毁模型 +linkTitle: 5-13 - 无法销毁模型 +title: 5-13 - 无法销毁模型 +type: docs +weight: 13 +--- + + + + + + +### 可能的原因 + +自定义销毁方法,业务处理上存在异常。 + +### 排查和解决步骤 + +检查自定义销毁方法,业务处理逻辑是否存在运行时异常。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/14.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/14.md new file mode 100644 index 000000000000..7047387317aa --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/14.md @@ -0,0 +1,26 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/5/14/ +- /zh-cn/docs3-v2/java-sdk/faq/5/14/ +- /zh-cn/overview/mannual/java-sdk/faq/5/14/ +description: 5-14 - 模型启动错误 +linkTitle: 5-14 - 模型启动错误 +title: 5-14 - 模型启动错误 +type: docs +weight: 14 +--- + + + + + + +### 可能的原因 + +1. 服务在等待发布或订阅时,连接被断开。 +2. 网络连接超时。 + +### 排查和解决步骤 + +1. 检查应用服务器与配置中心的连接是否正常。 +2. 检查网络连接是否存在超时等。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/15.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/15.md new file mode 100644 index 000000000000..07c8d6271341 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/15.md @@ -0,0 +1,24 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/5/15/ +- /zh-cn/docs3-v2/java-sdk/faq/5/15/ +- /zh-cn/overview/mannual/java-sdk/faq/5/15/ +description: 5-15 - 模型引用错误 +linkTitle: 5-15 - 模型引用错误 +title: 5-15 - 模型引用错误 +type: docs +weight: 15 +--- + + + + + + +### 可能的原因 + +Dubbo 核心处理类的方法被错误使用或被篡改。 + +### 排查和解决步骤 + +检查应用程序上是否存在错误使用或反编译修改情况。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/16.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/16.md new file mode 100644 index 000000000000..cdc9a8359d58 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/16.md @@ -0,0 +1,27 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/5/16/ +- /zh-cn/docs3-v2/java-sdk/faq/5/16/ +- /zh-cn/overview/mannual/java-sdk/faq/5/16/ +description: 5-16 - 无法找到任何有效的协议 +linkTitle: 5-16 - 无法找到任何有效的协议 +title: 5-16 - 无法找到任何有效的协议 +type: docs +weight: 16 +--- + + + + + + +### 可能的原因 + +配置的协议不支持。 + +### 排查和解决步骤 + +目前支持的协议有 dubbo、rmi、hessian、http、webservice、thrift、redis 等。 + +> 另请参阅 +[配置项参考手册](/zh-cn/overview/mannual/java-sdk/reference-manual/config/) diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/17.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/17.md new file mode 100644 index 000000000000..d1ede8cecc09 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/17.md @@ -0,0 +1,26 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/5/17/ +- /zh-cn/docs3-v2/java-sdk/faq/5/17/ +- /zh-cn/overview/mannual/java-sdk/faq/5/17/ +description: 5-17 - 参数值格式错误 +linkTitle: 5-17 - 参数值格式错误 +title: 5-17 - 参数值格式错误 +type: docs +weight: 17 +--- + + + + + + +### 可能的原因 + +1. 属性配置值长度过长,一般设置在 200 个字符以内。 +2. 属性配置值格式错误,目前支持数字、 -、 _ 等 + +### 排查和解决步骤 + +1. 检查属性配置值内容是否过长,具体参考提示信息进行修改。 +2. 检查属性配置值内容是否包含特殊字符,如 @#$%^& 等,具体请参考提示信息进行修改。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/18.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/18.md new file mode 100644 index 000000000000..c137314a55d6 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/18.md @@ -0,0 +1,26 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/5/18/ +- /zh-cn/docs3-v2/java-sdk/faq/5/18/ +- /zh-cn/overview/mannual/java-sdk/faq/5/18/ +description: 5-18 - 通知注册事件失败 +linkTitle: 5-18 - 通知注册事件失败 +title: 5-18 - 通知注册事件失败 +type: docs +weight: 18 +--- + + + + + + +### 可能的原因 + +1. 通知已发送,业务处理逻辑上出现意外错误。 +2. 配置中心无法连接,超时错误。 + +### 排查和解决步骤 + +1. 检查自定义业务逻辑实现,是否存在运行时异常。 +2. 检查配置中心是否能够正常连接。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/2.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/2.md new file mode 100644 index 000000000000..385495293313 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/2.md @@ -0,0 +1,24 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/5/2/ +- /zh-cn/docs3-v2/java-sdk/faq/5/2/ +- /zh-cn/overview/mannual/java-sdk/faq/5/2/ +description: 5-2 - 注册/注销关闭钩子方法失败 +linkTitle: 5-2 - 注册/注销关闭钩子方法失败 +title: 5-2 - 注册/注销关闭钩子方法失败 +type: docs +weight: 2 +--- + + + + + + +### 可能的原因 + +自定义钩子方法,业务处理逻辑存在异常。 + +### 排查和解决步骤 + +检查自定义钩子方法,业务处理逻辑是否存在运行时异常。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/20.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/20.md new file mode 100644 index 000000000000..0b82a0959863 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/20.md @@ -0,0 +1,26 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/5/20/ +- /zh-cn/docs3-v2/java-sdk/faq/5/20/ +- /zh-cn/overview/mannual/java-sdk/faq/5/20/ +description: 5-20 - 停止 dubbo 模块时发生错误 +linkTitle: 5-20 - 停止 dubbo 模块时发生错误 +title: 5-20 - 停止 dubbo 模块时发生错误 +type: docs +weight: 20 +--- + + + + + + +### 可能的原因 + +1. 自定义实现销毁方法,可能存在业务逻辑运行时异常。 +2. 未优雅停止服务,可能存在业务逻辑未处理完成情况。 + +### 排查和解决步骤 + +1. 检查自定义实现销毁方法,业务逻辑。 +2. 检查停止服务时,是否存在耗时的业务处理逻辑。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/21.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/21.md new file mode 100644 index 000000000000..b6f968603615 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/21.md @@ -0,0 +1,25 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/5/21/ +- /zh-cn/docs3-v2/java-sdk/faq/5/21/ +- /zh-cn/overview/mannual/java-sdk/faq/5/21/ +description: 5-21 - 服务销毁时发生异常错误 +linkTitle: 5-21 - 服务销毁时发生异常错误 +title: 5-21 - 服务销毁时发生异常错误 +type: docs +weight: 21 +--- + + + + + + + +### 可能的原因 + +服务发现实例已销毁完成 + +> 当前方法在 3.1 版本已停止使用 + +### 排查和解决步骤 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/22.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/22.md new file mode 100644 index 000000000000..bd25b3026531 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/22.md @@ -0,0 +1,29 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/5/22/ +- /zh-cn/docs3-v2/java-sdk/faq/5/22/ +- /zh-cn/overview/mannual/java-sdk/faq/5/22/ +description: 5-22 - 注册中心在初始化时发生错误 +linkTitle: 5-22 - 注册中心在初始化时发生错误 +title: 5-22 - 注册中心在初始化时发生错误 +type: docs +weight: 22 +--- + + + + + + + +### 可能的原因 + +1. 注册中心的地址配置错误。 +2. 配置的地址信息无法通过网络正常连接。 +3. 配置中心客户端的版本与实际服务端的版本不符,存在兼容性异常。 + +### 排查和解决步骤 + +1. 检查配置地址是否正确。 +2. 检查网络是否通畅并可通过第三方客户端进行连接。 +3. 检查是否存在兼容性匹配问题,可参考第三方网站进行版本适配。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/23.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/23.md new file mode 100644 index 000000000000..33c9226637c3 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/23.md @@ -0,0 +1,27 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/5/23/ +- /zh-cn/docs3-v2/java-sdk/faq/5/23/ +- /zh-cn/overview/mannual/java-sdk/faq/5/23/ +description: 5-23 - 等待导出/引用服务发生异常 +linkTitle: 5-23 - 等待导出/引用服务发生异常 +title: 5-23 - 等待导出/引用服务发生异常 +type: docs +weight: 23 +--- + + + + + + + +### 可能的原因 + +导出/引用服务时,注册中心异常停止或无法对外提供正常服务。 + +### 排查和解决步骤 + +检查注册中心的是否可正常连接,并检查当前客户端版本是否与服务端兼容匹配。 + +> 导出/引用单方法内都对异常做了处理,理论上此异常不会被抛出。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/24.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/24.md new file mode 100644 index 000000000000..433294bf3f79 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/24.md @@ -0,0 +1,25 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/5/24/ +- /zh-cn/docs3-v2/java-sdk/faq/5/24/ +- /zh-cn/overview/mannual/java-sdk/faq/5/24/ +description: 5-24 - 异步等待引用服务发生异常 +linkTitle: 5-24 - 异步等待引用服务发生异常 +title: 5-24 - 异步等待引用服务发生异常 +type: docs +weight: 24 +--- + + + + + + + +### 可能的原因 + +注册中心异常停止或无法对外提供正常服务。 + +### 排查和解决步骤 + +检查注册中心的是否可正常连接,并检查当前客户端版本是否与服务端兼容匹配。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/25.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/25.md new file mode 100644 index 000000000000..e4b50ef41959 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/25.md @@ -0,0 +1,24 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/5/25/ +- /zh-cn/docs3-v2/java-sdk/faq/5/25/ +- /zh-cn/overview/mannual/java-sdk/faq/5/25/ +description: 5-25 - 自定义实现发生未定义异常 +linkTitle: 5-25 - 自定义实现发生未定义异常 +title: 5-25 - 自定义实现发生未定义异常 +type: docs +weight: 25 +--- + + + + + + +### 可能的原因 + +自定义实现的 `org.apache.dubbo.rpc.Protocol` 协议,在方法调用 destory 时发生业务逻辑异常。 + +### 排查和解决步骤 + +检查自定义实现类代码的 `destory` 方法。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/26.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/26.md new file mode 100644 index 000000000000..102de19e7eea --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/26.md @@ -0,0 +1,22 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/5/26/ +- /zh-cn/docs3-v2/java-sdk/faq/5/26/ +- /zh-cn/overview/mannual/java-sdk/faq/5/26/ +description: 5-26 - 元数据已导出 +linkTitle: 5-26 - 元数据已导出 +title: 5-26 - 元数据已导出 +type: docs +weight: 26 +--- + + + + + + +### 可能的原因 + +元数据在当前 JVM 已被导出。 + +### 排查和解决步骤 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/27.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/27.md new file mode 100644 index 000000000000..7bd71b15855b --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/27.md @@ -0,0 +1,24 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/5/27/ +- /zh-cn/docs3-v2/java-sdk/faq/5/27/ +- /zh-cn/overview/mannual/java-sdk/faq/5/27/ +description: 5-27 - 内部类API被错误使用 +linkTitle: 5-27 - 内部类API被错误使用 +title: 5-27 - 内部类API被错误使用 +type: docs +weight: 27 +--- + + + + + + +### 可能的原因 + +`org.apache.dubbo.config.ReferenceConfig` 和 `org.apache.dubbo.common.config.ReferenceCache` 或被定义为非单例模式。 + +### 排查和解决步骤 + +检查自定义注解或配置,将核心应用类定以了为非单例模式,检查 `scope` 配置。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/28.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/28.md new file mode 100644 index 000000000000..eca8853e7dc4 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/28.md @@ -0,0 +1,24 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/5/28/ +- /zh-cn/docs3-v2/java-sdk/faq/5/28/ +- /zh-cn/overview/mannual/java-sdk/faq/5/28/ +description: 5-28 - 未发现可用注解 +linkTitle: 5-28 - 未发现可用注解 +title: 5-28 - 未发现可用注解 +type: docs +weight: 28 +--- + + + + + + +### 可能的原因 + +扫描包配置下未发现可靠注解。主要为 `@DubboService` 或 `@Service` + +### 排查和解决步骤 + +检查当前使用的版本,2.7.7 之前将扫描 `@Service` 注解,之后为 `@DubboService` diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/29.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/29.md new file mode 100644 index 000000000000..f38389bab21c --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/29.md @@ -0,0 +1,24 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/5/29/ +- /zh-cn/docs3-v2/java-sdk/faq/5/29/ +- /zh-cn/overview/mannual/java-sdk/faq/5/29/ +description: 5-29 - 扫描包未配置 +linkTitle: 5-29 - 扫描包未配置 +title: 5-29 - 扫描包未配置 +type: docs +weight: 29 +--- + + + + + + +### 可能的原因 + +`@EnableDubbo.scanBasePackages` 注解参数值未配置。 + +### 排查和解决步骤 + +`@EnableDubbo.scanBasePackages` 配置即可。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/3.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/3.md new file mode 100644 index 000000000000..c3184a57622c --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/3.md @@ -0,0 +1,24 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/5/3/ +- /zh-cn/docs3-v2/java-sdk/faq/5/3/ +- /zh-cn/overview/mannual/java-sdk/faq/5/3/ +description: 5-3 - 销毁方法调用时发生意外错误 +linkTitle: 5-3 - 销毁方法调用时发生意外错误 +title: 5-3 - 销毁方法调用时发生意外错误 +type: docs +weight: 3 +--- + + + + + + +### 可能的原因 + +自定义销毁方法,业务处理上存在异常。 + +### 排查和解决步骤 + +检查自定义销毁方法,业务处理逻辑是否存在运行时异常。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/30.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/30.md new file mode 100644 index 000000000000..febece4c989a --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/30.md @@ -0,0 +1,24 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/5/30/ +- /zh-cn/docs3-v2/java-sdk/faq/5/30/ +- /zh-cn/overview/mannual/java-sdk/faq/5/30/ +description: 5-30 - 声明bean定义重复 +linkTitle: 5-30 - 声明bean定义重复 +title: 5-30 - 声明bean定义重复 +type: docs +weight: 30 +--- + + + + + + +### 可能的原因 + +声明的对象 id 或名称重复。 + +### 排查和解决步骤 + +根据控制台输出的全限定类名称,名称修改唯一即可。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/31.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/31.md new file mode 100644 index 000000000000..06d67461fa83 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/31.md @@ -0,0 +1,24 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/5/31/ +- /zh-cn/docs3-v2/java-sdk/faq/5/31/ +- /zh-cn/overview/mannual/java-sdk/faq/5/31/ +description: 5-31 - 状态检查错误 +linkTitle: 5-31 - 状态检查错误 +title: 5-31 - 状态检查错误 +type: docs +weight: 31 +--- + + + + + + +### 可能的原因 + +当前运行的服务器状态,系统 CPU 使用率过高或内存等指标太低 + +### 排查和解决步骤 + +检查当前服务器的内存使用状态,及 CPU 使用率等其他指标,可能存在宕机的危险。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/32.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/32.md new file mode 100644 index 000000000000..03eed30c2f1f --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/32.md @@ -0,0 +1,24 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/5/32/ +- /zh-cn/docs3-v2/java-sdk/faq/5/32/ +- /zh-cn/overview/mannual/java-sdk/faq/5/32/ +description: 5-32 - Apollo 断开连接时发生错误 +linkTitle: 5-32 - Apollo 断开连接时发生错误 +title: 5-32 - Apollo 断开连接时发生错误 +type: docs +weight: 32 +--- + + + + + + +### 可能的原因 + +Apollo 配置中心可能已关闭或者网络已断开。 + +### 排查和解决步骤 + +检查 Apollo 服务端服务状态,及网络间是否可正常通信。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/33.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/33.md new file mode 100644 index 000000000000..c6cd6f5465eb --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/33.md @@ -0,0 +1,24 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/5/33/ +- /zh-cn/docs3-v2/java-sdk/faq/5/33/ +- /zh-cn/overview/mannual/java-sdk/faq/5/33/ +description: 5-33 - Apollo 配置更新事件发生异常 +linkTitle: 5-33 - Apollo 配置更新事件发生异常 +title: 5-33 - Apollo 配置更新事件发生异常 +type: docs +weight: 33 +--- + + + + + + +### 可能的原因 + +Apollo 配置 API 使用错误。 + +### 排查和解决步骤 + +请参考动态配置中心使用文档中关于 Apollo 部分的描述。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/34.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/34.md new file mode 100644 index 000000000000..1dc2c83c3403 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/34.md @@ -0,0 +1,24 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/5/34/ +- /zh-cn/docs3-v2/java-sdk/faq/5/34/ +- /zh-cn/overview/mannual/java-sdk/faq/5/34/ +description: 5-34 - NACOS 发生错误 +linkTitle: 5-34 - NACOS 发生错误 +title: 5-34 - NACOS 发生错误 +type: docs +weight: 34 +--- + + + + + + +### 可能的原因 + +NACOS 配置 API 使用错误。 + +### 排查和解决步骤 + +请参考动态配置中心使用文档中关于 NACOS 部分的描述。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/35.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/35.md new file mode 100644 index 000000000000..6afe4a7879f2 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/35.md @@ -0,0 +1,27 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/5/35/ +- /zh-cn/docs3-v2/java-sdk/faq/5/35/ +- /zh-cn/overview/mannual/java-sdk/faq/5/35/ +description: 5-35 - 容器初始化失败 +linkTitle: 5-35 - 容器初始化失败 +title: 5-35 - 容器初始化失败 +type: docs +weight: 35 +--- + + + + + + +## 可能的原因 + +未定义接口的 `org.apache.dubbo.container.Container` SPI 实现。 + +附:目前在`org.apache.dubbo.container.Main` 类中测试使用。 + +## 排查和解决步骤 + + +

diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/36.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/36.md new file mode 100644 index 000000000000..6b337d196bf0 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/36.md @@ -0,0 +1,24 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/5/36/ +- /zh-cn/docs3-v2/java-sdk/faq/5/36/ +- /zh-cn/overview/mannual/java-sdk/faq/5/36/ +description: 5-36 - 过滤器校验时发生错误 +linkTitle: 5-36 - 过滤器校验时发生错误 +title: 5-36 - 过滤器校验时发生错误 +type: docs +weight: 36 +--- + + + + + + +### 可能的原因 + +自定义过滤器扩展类中重写的 `invoke` 方法,发生业务代码异常。 + +### 排查和解决步骤 +1. 使用 ps -eaf |grep <错误服务> +2. 可通过一些第三方的工具或者 `jstack [PID] > jstack.log` 分析堆栈信息,进行定位。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/37.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/37.md new file mode 100644 index 000000000000..e216f007259b --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/37.md @@ -0,0 +1,25 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/5/37/ +- /zh-cn/docs3-v2/java-sdk/faq/5/37/ +- /zh-cn/overview/mannual/java-sdk/faq/5/37/ +description: 5-37 - 动态配置监听处理发生错误 +linkTitle: 5-37 - 动态配置监听处理发生错误 +title: 5-37 - 动态配置监听处理发生错误 +type: docs +weight: 37 +--- + + + + + +文件发生变化时,监听事件处理失败 + +### 可能的原因 + +文件权限发生变化或目录权限发生变化。 + +### 排查和解决步骤 + +可根据控制台的堆栈信息,进行代码定位。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/38.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/38.md new file mode 100644 index 000000000000..e1a911575d5c --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/38.md @@ -0,0 +1,24 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/5/38/ +- /zh-cn/docs3-v2/java-sdk/faq/5/38/ +- /zh-cn/overview/mannual/java-sdk/faq/5/38/ +description: 5-38 - 配置参数未定义 +linkTitle: 5-38 - 配置参数未定义 +title: 5-38 - 配置参数未定义 +type: docs +weight: 38 +--- + + + + + + +### 可能的原因 + +配置参数未定义 + +### 排查和解决步骤 + +多为测试用例中使用,可根据提示明细,进行参数的设置。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/39.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/39.md new file mode 100644 index 000000000000..9ed6c90f3236 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/39.md @@ -0,0 +1,25 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/5/39/ +- /zh-cn/docs3-v2/java-sdk/faq/5/39/ +- /zh-cn/overview/mannual/java-sdk/faq/5/39/ +description: 5-39 - Dubbo配置bean初始化器发生错误 +linkTitle: 5-39 - Dubbo配置bean初始化器发生错误 +title: 5-39 - Dubbo配置bean初始化器发生错误 +type: docs +weight: 39 +--- + + + + + + +### 可能的原因 + +源代码或被修改 + +### 排查和解决步骤 + +检查业务代码未对核心类进行源码修改或加载的顺序修改。 +如:`org.apache.dubbo.config.spring.context.DubboConfigBeanInitializer` diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/4.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/4.md new file mode 100644 index 000000000000..f557175c9c96 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/4.md @@ -0,0 +1,26 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/5/4/ +- /zh-cn/docs3-v2/java-sdk/faq/5/4/ +- /zh-cn/overview/mannual/java-sdk/faq/5/4/ +description: 5-4 - 服务接口中找不到方法 +linkTitle: 5-4 - 服务接口中找不到方法 +title: 5-4 - 服务接口中找不到方法 +type: docs +weight: 4 +--- + + + + + + +### 可能的原因 + +1. 消费端调用的接口名#方法不存在。 +2. 服务端未正确的暴露当前接口。 + +### 排查和解决步骤 + +1. 检查消费端调用的接口名#方法是否存在。 +2. 检查服务端暴露的服务列表内是否存在。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/40.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/40.md new file mode 100644 index 000000000000..ca79402f4e1d --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/40.md @@ -0,0 +1,25 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/5/40/ +- /zh-cn/docs3-v2/java-sdk/faq/5/40/ +- /zh-cn/overview/mannual/java-sdk/faq/5/40/ +description: 5-40 - Dubbo配置bean未找到 +linkTitle: 5-40 - Dubbo配置bean未找到 +title: 5-40 - Dubbo配置bean未找到 +type: docs +weight: 40 +--- + + + + + + +### 可能的原因 + +源代码或被修改 + +### 排查和解决步骤 + +检查业务代码未对核心类进行源码修改或加载的顺序修改。 +如:`org.apache.dubbo.config.spring.context.DubboConfigBeanInitializer` diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/41.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/41.md new file mode 100644 index 000000000000..5167fc20cfed --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/41.md @@ -0,0 +1,24 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/5/41/ +- /zh-cn/docs3-v2/java-sdk/faq/5/41/ +- /zh-cn/overview/mannual/java-sdk/faq/5/41/ +description: 5-41 - SSL证书读取失败 +linkTitle: 5-41 - SSL证书读取失败 +title: 5-41 - SSL证书读取失败 +type: docs +weight: 41 +--- + + + + + + +### 可能的原因 + +SSL 证书配置异常 + +### 排查和解决步骤 + +检查 SSL 证书的配置,查看对应文件是否存在 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/42.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/42.md new file mode 100644 index 000000000000..e32b4a65ef2b --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/42.md @@ -0,0 +1,26 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/5/42/ +- /zh-cn/docs3-v2/java-sdk/faq/5/42/ +- /zh-cn/overview/mannual/java-sdk/faq/5/42/ +description: 5-42 - Dubbo 证书签发失败 +linkTitle: 5-42 - Dubbo 证书签发失败 +title: 5-42 - Dubbo 证书签发失败 +type: docs +weight: 42 +--- + + + + + + +### 可能的原因 + +Dubbo 请求远程 CA 签发证书失败 + +### 排查和解决步骤 + +- 检查 CA 连接配置 +- 检查 CA 运行状态 +- 检查 CA 日志 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/43.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/43.md new file mode 100644 index 000000000000..4ac65c40416f --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/43.md @@ -0,0 +1,24 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/5/43/ +- /zh-cn/docs3-v2/java-sdk/faq/5/43/ +- /zh-cn/overview/mannual/java-sdk/faq/5/43/ +description: 5-43 - Dubbo 证书签发连接不安全 +linkTitle: 5-43 - Dubbo 证书签发连接不安全 +title: 5-43 - Dubbo 证书签发连接不安全 +type: docs +weight: 43 +--- + + + + + + +### 可能的原因 + +Dubbo 与远程 CA 的连接不安全 + +### 排查和解决步骤 + +- 检查 Dubbo 进程是否已经正确配置了 CA 证书信息以及 OIDC(OpenID Connect)的 Token 获取方式 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/5.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/5.md new file mode 100644 index 000000000000..b1fc2889a647 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/5.md @@ -0,0 +1,24 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/5/5/ +- /zh-cn/docs3-v2/java-sdk/faq/5/5/ +- /zh-cn/overview/mannual/java-sdk/faq/5/5/ +description: 5-5 - 无法获得env变量 +linkTitle: 5-5 - 无法获得env变量 +title: 5-5 - 无法获得env变量 +type: docs +weight: 5 +--- + + + + + + +### 可能的原因 + +环境变量无法获取。 + +### 排查和解决步骤 + +检查提示的变量名,是否配置并可以正常读取加载。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/6.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/6.md new file mode 100644 index 000000000000..45dd63782dfe --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/6.md @@ -0,0 +1,24 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/5/6/ +- /zh-cn/docs3-v2/java-sdk/faq/5/6/ +- /zh-cn/overview/mannual/java-sdk/faq/5/6/ +description: 5-6 - 接口类型的属性冲突 +linkTitle: 5-6 - 接口类型的属性冲突 +title: 5-6 - 接口类型的属性冲突 +type: docs +weight: 6 +--- + + + + + + +### 可能的原因 + +泛化定义配置不正确。 + +### 排查和解决步骤 + +检查泛化定义是否正确。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/7.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/7.md new file mode 100644 index 000000000000..5041addb585f --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/7.md @@ -0,0 +1,28 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/5/7/ +- /zh-cn/docs3-v2/java-sdk/faq/5/7/ +- /zh-cn/overview/mannual/java-sdk/faq/5/7/ +description: 5-7 - 取消导出时发生意外错误 +linkTitle: 5-7 - 取消导出时发生意外错误 +title: 5-7 - 取消导出时发生意外错误 +type: docs +weight: 7 +--- + + + + + + +### 可能的原因 + +1. 配置中心的服务无法连接。 +2. 配置的协议、IP、端口不正确。 +3. 使用配置中心客户端版本与服务端版本冲突,无法建立有效连接。 + +### 排查和解决步骤 + +1. 检查配置中心的服务状态是否正常。 +2. 检查配置的协议、IP、端口不正确。 +3. 检查使用的配置中心客户端版本与服务端版本是否兼容。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/8.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/8.md new file mode 100644 index 000000000000..c0966beb4828 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/8.md @@ -0,0 +1,24 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/5/8/ +- /zh-cn/docs3-v2/java-sdk/faq/5/8/ +- /zh-cn/overview/mannual/java-sdk/faq/5/8/ +description: 5-8 - 协议将使用随机可用端口 +linkTitle: 5-8 - 协议将使用随机可用端口 +title: 5-8 - 协议将使用随机可用端口 +type: docs +weight: 8 +--- + + + + + + +### 可能的原因 + +协议指定的端口被占用,随机选择端口进行启动。 + +### 排查和解决步骤 + +检查当前配置端口是否被其它应用程序占用。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/9.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/9.md new file mode 100644 index 000000000000..57a333eb4a18 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/9.md @@ -0,0 +1,28 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/5/9/ +- /zh-cn/docs3-v2/java-sdk/faq/5/9/ +- /zh-cn/overview/mannual/java-sdk/faq/5/9/ +description: 5-9 - 服务配置导出失败 +linkTitle: 5-9 - 服务配置导出失败 +title: 5-9 - 服务配置导出失败 +type: docs +weight: 9 +--- + + + + + + +### 可能的原因 + +1. 配置中心的服务无法连接。 +2. 配置的协议、IP、端口不正确。 +3. 使用配置中心客户端版本与服务端版本冲突,无法建立有效连接。 + +### 排查和解决步骤 + +1. 检查配置中心的服务状态是否正常。 +2. 检查配置的协议、IP、端口不正确。 +3. 检查使用的配置中心客户端版本与服务端版本是否兼容。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/_index.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/_index.md new file mode 100644 index 000000000000..26a7bcd20484 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/5/_index.md @@ -0,0 +1,11 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/5/ +- /zh-cn/docs3-v2/java-sdk/faq/5/ +- /zh-cn/overview/mannual/java-sdk/faq/5/_index/ +description: 5 - 配置(中心)层 +linkTitle: 5 - 配置(中心)层 +title: 5 - 配置(中心)层 +type: docs +weight: 5 +--- diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/6/1.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/6/1.md new file mode 100644 index 000000000000..96c7734da080 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/6/1.md @@ -0,0 +1,26 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/6/1/ +- /zh-cn/docs3-v2/java-sdk/faq/6/1/ +- /zh-cn/overview/mannual/java-sdk/faq/6/1/ +description: 6-1 - 服务端连接失败 +linkTitle: 6-1 - 服务端连接失败 +title: 6-1 - 服务端连接失败 +type: docs +weight: 1 +--- + + + + + +网络通信层,在连接服务提供者服务时失败 + +### 可能的原因 + +服务提供者的网络异常断开或受防火墙及第三方工具的拦截,无法对外提供服务。 + +### 排查和解决步骤 + +1. 如果为 rest 连接,检查请求的服务端配置是否正确。 +2. 检查网络通信是否正常,可使用一些简单的 cmd 命令进行检测,如 `ping` 等。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/6/10.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/6/10.md new file mode 100644 index 000000000000..ac18c5ea06d4 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/6/10.md @@ -0,0 +1,24 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/6/10/ +- /zh-cn/docs3-v2/java-sdk/faq/6/10/ +- /zh-cn/overview/mannual/java-sdk/faq/6/10/ +description: 6-10 - 超过有效载荷限制异常 +linkTitle: 6-10 - 超过有效载荷限制异常 +title: 6-10 - 超过有效载荷限制异常 +type: docs +weight: 10 +--- + + + + + + +### 可能的原因 + +> 默认 `payload=8M`,请检查各项配置 + +### 排查和解决步骤 + +各组件支持的具体配置项及含义请参考 [配置项手册](/zh-cn/overview/mannual/java-sdk/reference-manual/config/properties/) diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/6/11.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/6/11.md new file mode 100644 index 000000000000..e8a385ec43eb --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/6/11.md @@ -0,0 +1,24 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/6/11/ +- /zh-cn/docs3-v2/java-sdk/faq/6/11/ +- /zh-cn/overview/mannual/java-sdk/faq/6/11/ +description: 6-11 - 字符集不被支持 +linkTitle: 6-11 - 字符集不被支持 +title: 6-11 - 字符集不被支持 +type: docs +weight: 11 +--- + + + + + + +## 可能的原因 + +> 默认 `UTF-8` 字符集 + +## 排查和解决步骤 + +结果会最终以 `UTF-8` 字符集进行处理。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/6/12.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/6/12.md new file mode 100644 index 000000000000..58b4d27d0b98 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/6/12.md @@ -0,0 +1,26 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/6/12/ +- /zh-cn/docs3-v2/java-sdk/faq/6/12/ +- /zh-cn/overview/mannual/java-sdk/faq/6/12/ +description: 6-12 - ZK客户端销毁时发生错误 +linkTitle: 6-12 - ZK客户端销毁时发生错误 +title: 6-12 - ZK客户端销毁时发生错误 +type: docs +weight: 12 +--- + + + + + + + +### 可能的原因 + +客户端与服务端连接已被拒绝 +客户端在销毁时,可能服务端正在进行选举或者其他操作,导致发生的异常。 + +### 排查和解决步骤 + +关闭方法,可针对堆栈信息进行查询。一般可不处理。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/6/13.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/6/13.md new file mode 100644 index 000000000000..76c1392b058f --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/6/13.md @@ -0,0 +1,25 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/6/13/ +- /zh-cn/docs3-v2/java-sdk/faq/6/13/ +- /zh-cn/overview/mannual/java-sdk/faq/6/13/ +description: 6-13 - 流关闭异常 +linkTitle: 6-13 - 流关闭异常 +title: 6-13 - 流关闭异常 +type: docs +weight: 13 +--- + + + + + + + +### 可能的原因 + +当前流已关闭 `Stream is closed` 或流关闭时,其他线程正在读取。 + +### 排查和解决步骤 + +一般为代码关闭流的顺序上发生了颠倒。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/6/14.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/6/14.md new file mode 100644 index 000000000000..07bd31411399 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/6/14.md @@ -0,0 +1,24 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/6/14/ +- /zh-cn/docs3-v2/java-sdk/faq/6/14/ +- /zh-cn/overview/mannual/java-sdk/faq/6/14/ +description: 6-14 - 服务端响应失败 +linkTitle: 6-14 - 服务端响应失败 +title: 6-14 - 服务端响应失败 +type: docs +weight: 14 +--- + + + + + + +### 可能的原因 + +在服务端与客户端交互发生数据时,客户端异常关闭。 + +### 排查和解决步骤 + +客户端异常终止或服务器宕机。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/6/15.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/6/15.md new file mode 100644 index 000000000000..565f47239166 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/6/15.md @@ -0,0 +1,24 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/6/15/ +- /zh-cn/docs3-v2/java-sdk/faq/6/15/ +- /zh-cn/overview/mannual/java-sdk/faq/6/15/ +description: 6-15 - 跳过未读完的流数据 +linkTitle: 6-15 - 跳过未读完的流数据 +title: 6-15 - 跳过未读完的流数据 +type: docs +weight: 15 +--- + + + + + + +### 可能的原因 + +解码时,如流中还有未读数据时会跳过未读完的流 + +### 排查和解决步骤 + +解码时会把数据全部一次性读取 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/6/16.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/6/16.md new file mode 100644 index 000000000000..4ed6d440761d --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/6/16.md @@ -0,0 +1,24 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/6/16/ +- /zh-cn/docs3-v2/java-sdk/faq/6/16/ +- /zh-cn/overview/mannual/java-sdk/faq/6/16/ +description: 6-16 - 重连时发生异常 +linkTitle: 6-16 - 重连时发生异常 +title: 6-16 - 重连时发生异常 +type: docs +weight: 16 +--- + + + + + + +### 可能的原因 + +每次发生重连时提示,网络不稳定造成的延迟重连。 + +### 排查和解决步骤 + +检查是否有网络丢包情况。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/6/2.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/6/2.md new file mode 100644 index 000000000000..425161657877 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/6/2.md @@ -0,0 +1,34 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/6/2/ +- /zh-cn/docs3-v2/java-sdk/faq/6/2/ +- /zh-cn/overview/mannual/java-sdk/faq/6/2/ +description: 6-2 - 客户端超时 +linkTitle: 6-2 - 客户端超时 +title: 6-2 - 客户端超时 +type: docs +weight: 2 +--- + + + + + +超时是调用端发生在请求发出后,无法在指定的时间内获得对应的响应。 + +### 可能的原因 +1. 服务端确实处理比较慢,无法在指定的时间返回结果,调用端就自动返回一个超时的异常响应来结束此次调用。 +2. 服务端如果响应的比较快,但当客户端 Load 很高,负载压力很大的时候,会因为客户端请求发不出去、响应卡在 TCP Buffer 等问题,造成超时。因为客户端接收到服务端发来的数据或者请求服务端的数据,都会在系统层面排队,如果系统负载比较高,在内核态的时间占比就会加长,从而造成客户端获取到值时已经超时。 +3. 通常是业务处理太慢,可在服务提供方机器上执行:`jstack [PID] > jstack.log` 分析线程都卡在哪个方法调用上,这里就是慢的原因。如果不能调优性能,请调高 timeout 阈值。 + + +### 排查和解决步骤 + +1. 两边可能有 GC,检查服务端和客户端 GC 日志,耗时很长的 GC,会导致超时。超时的发生很可能意味着调用端或者服务端的资源(CPU,内存或者网络)出现了瓶颈,需要检查服务端的问题还是调用端的问题来排除 GC 抖动等嫌疑。 +2. 检查服务端的网络质量,比如重传率来排除网络嫌疑。 +3. 借助链路跟踪的分析服务(比如阿里的 [ARMS](https://help.aliyun.com/document_detail/63796.html) ,开源的 [OpenTracing](https://github.com/opentracing/opentracing-java) +系的实现 [Zipkin](https://github.com/openzipkin/zipkin) 、[SkyWalking](https://github.com/apache/skywalking) 等)来分析下各个点的耗时情况。 + + +> 这个错误码的 FAQ 页面参考了空冥同学的 [《Dubbo 常见错误及解决方法》](https://github.com/StabilityMan/StabilityGuide/blob/master/docs/diagnosis/plugin/rpc/%E7%B3%BB%E7%BB%9F%E7%A8%B3%E5%AE%9A%E6%80%A7%E2%80%94%E2%80%94Dubbo%E5%B8%B8%E8%A7%81%E9%94%99%E8%AF%AF%E5%8F%8A%E8%A7%A3%E5%86%B3%E6%96%B9%E6%B3%95.md) 。 +所引文章通过 [CC-BY-4.0](http://creativecommons.org/licenses/by/4.0/) 协议赋予了汇编的权利。在此向原作者表示感谢。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/6/3.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/6/3.md new file mode 100644 index 000000000000..cc612f74e92d --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/6/3.md @@ -0,0 +1,24 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/6/3/ +- /zh-cn/docs3-v2/java-sdk/faq/6/3/ +- /zh-cn/overview/mannual/java-sdk/faq/6/3/ +description: 6-3 - 网络连接关闭失败 +linkTitle: 6-3 - 网络连接关闭失败 +title: 6-3 - 网络连接关闭失败 +type: docs +weight: 3 +--- + + + + + + +### 可能的原因 + +非优雅关闭服务,此时服务端可能在对外输出流未完成。 + +### 排查和解决步骤 + +一般为提示类警告信息,不影响后续的程序执行。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/6/4.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/6/4.md new file mode 100644 index 000000000000..40a49072c93a --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/6/4.md @@ -0,0 +1,22 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/6/4/ +- /zh-cn/docs3-v2/java-sdk/faq/6/4/ +- /zh-cn/overview/mannual/java-sdk/faq/6/4/ +description: 6-4 - 网络通讯层未知异常 +linkTitle: 6-4 - 网络通讯层未知异常 +title: 6-4 - 网络通讯层未知异常 +type: docs +weight: 4 +--- + + + + + + +### 可能的原因 +> 该错误码的意义已经调整。对于 Dubbo 3.1.4、3.2.0-beta.3 及其之前的版本的该错误码的出错,请参考错误码 [99-0](/zh-cn/overview/mannual/java-sdk/faq/99/0/)。 + +### 排查和解决步骤 +(该错误码目前空缺) diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/6/5.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/6/5.md new file mode 100644 index 000000000000..8cf5c6c41ed1 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/6/5.md @@ -0,0 +1,25 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/6/5/ +- /zh-cn/docs3-v2/java-sdk/faq/6/5/ +- /zh-cn/overview/mannual/java-sdk/faq/6/5/ +description: 6-5 - 网络连接断开失败 +linkTitle: 6-5 - 网络连接断开失败 +title: 6-5 - 网络连接断开失败 +type: docs +weight: 5 +--- + + + + + + + +### 可能的原因 + +超时是调用端发生在请求发出后,无法在指定的时间内获得对应的响应,出现客户端主动断开连接 + +### 排查和解决步骤 + +一般为提示类警告信息,不影响后续的程序执行。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/6/6.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/6/6.md new file mode 100644 index 000000000000..07f50c01f853 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/6/6.md @@ -0,0 +1,27 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/6/6/ +- /zh-cn/docs3-v2/java-sdk/faq/6/6/ +- /zh-cn/overview/mannual/java-sdk/faq/6/6/ +description: 6-6 - 不支持的消息 +linkTitle: 6-6 - 不支持的消息 +title: 6-6 - 不支持的消息 +type: docs +weight: 6 +--- + + + + + + + +### 可能的原因 + +返回的数据序列化错误,或超出序列化最大值 + +### 排查和解决步骤 + +可通过一些第三方的工具或者 `jstack [PID] > jstack.log` 分析堆栈信息,进行定位。 + +各组件支持的具体配置项及含义请参考 [配置项手册](/zh-cn/overview/mannual/java-sdk/reference-manual/config/properties/) diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/6/7.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/6/7.md new file mode 100644 index 000000000000..137a8002f48c --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/6/7.md @@ -0,0 +1,24 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/6/7/ +- /zh-cn/docs3-v2/java-sdk/faq/6/7/ +- /zh-cn/overview/mannual/java-sdk/faq/6/7/ +description: 6-7 - 线程连接数超限警告 +linkTitle: 6-7 - 服务端连接失败 +title: 6-7 - 线程连接数超限警告 +type: docs +weight: 7 +--- + + + + + + +### 可能的原因 + +连接数超过限制时的提醒消息,配置或连接数超过配置数的警告提醒。 + +### 排查和解决步骤 + +默认配置项 `connect.queue.warning.size=1000`,可通过配置进行调整。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/6/8.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/6/8.md new file mode 100644 index 000000000000..cce08265ad13 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/6/8.md @@ -0,0 +1,25 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/6/8/ +- /zh-cn/docs3-v2/java-sdk/faq/6/8/ +- /zh-cn/overview/mannual/java-sdk/faq/6/8/ +description: 6-8 - 返回数据解码失败 +linkTitle: 6-8 - 返回数据解码失败 +title: 6-8 - 返回数据解码失败 +type: docs +weight: 8 +--- + + + + + + + +### 可能的原因 + +返回数据格式错误或解码失败 + +### 排查和解决步骤 + +可通过 debug/warn 日志模式,输出具体服务类名称和返回的消息及堆栈信息。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/6/9.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/6/9.md new file mode 100644 index 000000000000..9ad290c6237d --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/6/9.md @@ -0,0 +1,28 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/6/9/ +- /zh-cn/docs3-v2/java-sdk/faq/6/9/ +- /zh-cn/overview/mannual/java-sdk/faq/6/9/ +description: 6-9 - 序列号ID存在重复 +linkTitle: 6-9 - 服务端连接失败 +title: 6-9 - 序列号ID存在重复 +type: docs +weight: 9 +--- + + + + + + + +### 可能的原因 + +1. 返回了一个空对象。 +2. 自定义序列号类,`org.apache.dubbo.common.serialize.Serialization#getContentTypeId` 与系统内置存在重复, +此时在加载时,以首个加载到的 SPI 实例为准。其他项将跳过。 + +### 排查和解决步骤 + +1. 检查返回结果。 +2. 内置值可参考类 `org.apache.dubbo.common.serialize.Constants` diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/6/_index.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/6/_index.md new file mode 100644 index 000000000000..c998a9712a62 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/6/_index.md @@ -0,0 +1,11 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/6/ +- /zh-cn/docs3-v2/java-sdk/faq/6/ +- /zh-cn/overview/mannual/java-sdk/faq/6/_index/ +description: 6 - 网络传输层 +linkTitle: 6 - 网络传输层 +title: 6 - 网络传输层 +type: docs +weight: 6 +--- diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/7/1.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/7/1.md new file mode 100644 index 000000000000..2757de9f90cb --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/7/1.md @@ -0,0 +1,25 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/7/1/ +- /zh-cn/docs3-v2/java-sdk/faq/7/1/ +- /zh-cn/overview/mannual/java-sdk/faq/7/1/ +description: 7-1 - QOS 已关闭 +linkTitle: 7-1 - QOS 已关闭 +title: 7-1 - QOS 已关闭 +type: docs +weight: 1 +--- + + + + + + +### 可能的原因 + +QOS 已关闭 + +### 排查和解决步骤 + + +> 请参考[QOS 操作手册](/zh-cn/overview/mannual/java-sdk/reference-manual/qos/)。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/7/2.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/7/2.md new file mode 100644 index 000000000000..06dfa2b102ff --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/7/2.md @@ -0,0 +1,25 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/7/2/ +- /zh-cn/docs3-v2/java-sdk/faq/7/2/ +- /zh-cn/overview/mannual/java-sdk/faq/7/2/ +description: 7-2 - QOS 已开启 +linkTitle: 7-2 - QOS 已开启 +title: 7-2 - QOS 已开启 +type: docs +weight: 2 +--- + + + + + + +### 可能的原因 + +QOS 已开启,默认为开启状态。 + +### 排查和解决步骤 + + +> 请参考[QOS 操作手册](/zh-cn/overview/mannual/java-sdk/reference-manual/qos/)。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/7/3.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/7/3.md new file mode 100644 index 000000000000..f9175cf1a4db --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/7/3.md @@ -0,0 +1,26 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/7/3/ +- /zh-cn/docs3-v2/java-sdk/faq/7/3/ +- /zh-cn/overview/mannual/java-sdk/faq/7/3/ +description: 7-3 - 设置超时时间的警告百分比值 +linkTitle: 7-3 - 设置超时时间的警告百分比值 +title: 7-3 - 设置超时时间的警告百分比值 +type: docs +weight: 3 +--- + + + + + + +## 可能的原因 + +QOS 设置超时时间的警告百分比值, 默认为0.75。修改后,控制台会打印此消息。 + +## 排查和解决步骤 + + +请参考 QOS 操作手册[性能采样命令](/zh-cn/overview/mannual/java-sdk/reference-manual/qos/profiler/)。 +

diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/7/4.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/7/4.md new file mode 100644 index 000000000000..fd8fc540bee9 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/7/4.md @@ -0,0 +1,25 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/7/4/ +- /zh-cn/docs3-v2/java-sdk/faq/7/4/ +- /zh-cn/overview/mannual/java-sdk/faq/7/4/ +description: 7-4 - QOS 服务启动失败 +linkTitle: 7-4 - QOS 服务启动失败 +title: 7-4 - QOS 服务启动失败 +type: docs +weight: 4 +--- + + + + + + +### 可能的原因 + +QOS 参数值未正确设置。主要参数有 `qos.host` 和 `qos.port` + +### 排查和解决步骤 + + +> 请参考QOS 操作手册[QOS 概述](/zh-cn/overview/mannual/java-sdk/reference-manual/qos/overview/)。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/7/5.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/7/5.md new file mode 100644 index 000000000000..b9726dd07e8d --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/7/5.md @@ -0,0 +1,26 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/7/5/ +- /zh-cn/docs3-v2/java-sdk/faq/7/5/ +- /zh-cn/overview/mannual/java-sdk/faq/7/5/ +description: 7-5 - QOS 命令未找到 +linkTitle: 7-5 - QOS 命令未找到 +title: 7-5 - QOS 命令未找到 +type: docs +weight: 5 +--- + + + + + + +### 可能的原因 + +QOS 命令拼写错误。 + +## 排查和解决步骤 + +QOS 命令不存在。 + +> 请参考 QOS 操作手册[基础命令手册](/zh-cn/overview/mannual/java-sdk/reference-manual/qos/command/)。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/7/6.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/7/6.md new file mode 100644 index 000000000000..83c49e4df379 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/7/6.md @@ -0,0 +1,25 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/7/6/ +- /zh-cn/docs3-v2/java-sdk/faq/7/6/ +- /zh-cn/overview/mannual/java-sdk/faq/7/6/ +description: 7-6 - QOS 发生未知异常 +linkTitle: 7-6 - QOS 发生未知异常 +title: 7-6 - QOS 发生未知异常 +type: docs +weight: 6 +--- + + + + + + +### 可能的原因 + +QOS 发生未知异常 + +### 排查和解决步骤 + +1. 检查当前请求的服务是否可正常访问。 +2. 可能由于某些原因,未能正确加载或返回 `CommandContext` 实例。可根据控制台的错误提醒信息,进行排查定位。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/7/7.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/7/7.md new file mode 100644 index 000000000000..5ac45a2ee3bb --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/7/7.md @@ -0,0 +1,25 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/7/7/ +- /zh-cn/docs3-v2/java-sdk/faq/7/7/ +- /zh-cn/overview/mannual/java-sdk/faq/7/7/ +description: 7-7 - QOS 无权限访问 +linkTitle: 7-7 - QOS 无权限访问 +title: 7-7 - QOS 无权限访问 +type: docs +weight: 7 +--- + + + + + + +### 可能的原因 + +本次 QoS 请求无权限访问对应的资源,通常出现在有恶意攻击的场景下 + +### 排查和解决步骤 + +检查请求是否是预期发生的,如果非预期请检查是否有恶意攻击源。 +> 如果是预期的,请参考 [QoS 安全](/zh-cn/overview/mannual/java-sdk/reference-manual/qos/overview/#%E5%AE%89%E5%85%A8) 一文配置对应的权限信息。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/7/_index.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/7/_index.md new file mode 100644 index 000000000000..6b3aef9e5110 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/7/_index.md @@ -0,0 +1,11 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/7/ +- /zh-cn/docs3-v2/java-sdk/faq/7/ +- /zh-cn/overview/mannual/java-sdk/faq/7/_index/ +description: 7 - QoS 插件模块 +linkTitle: 7 - QoS 插件模块 +title: 7 - QoS 插件模块 +type: docs +weight: 7 +--- diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/81/1.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/81/1.md new file mode 100644 index 000000000000..c57fa729d91b --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/81/1.md @@ -0,0 +1,28 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/81/1/ +- /zh-cn/docs3-v2/java-sdk/faq/81/1/ +- /zh-cn/overview/mannual/java-sdk/faq/81/1/ +description: 81-1 - ZK 启动异常 +linkTitle: 81-1 - ZK 启动异常 +title: 81-1 - ZK 启动异常 +type: docs +weight: 1 +--- + + + + + + +### 可能的原因 + +1. zk 的服务端版本与客户端版本存在不兼容问题,无法进行连接。 +2. zk 服务未正常启动或防火墙等原因不能对外提供服务。 + +### 排查和解决步骤 + +1. 确认客户端版本与服务端版本一致。 +2. zk 能够正常启动或对外能够提供正常服务。 + +可通过一些第三方的工具或者`jstack [PID] > jstack.log` 分析堆栈信息,进行定位。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/81/2.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/81/2.md new file mode 100644 index 000000000000..d6b530687d25 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/81/2.md @@ -0,0 +1,25 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/81/2/ +- /zh-cn/docs3-v2/java-sdk/faq/81/2/ +- /zh-cn/overview/mannual/java-sdk/faq/81/2/ +description: 81-2 - ZK 销毁异常 +linkTitle: 81-2 - ZK 销毁异常 +title: 81-2 - ZK 销毁异常 +type: docs +weight: 2 +--- + + + + + + +### 可能的原因 + +当前实例已销毁完成。 +网络或已断开。 + +### 排查和解决步骤 + +可通过一些第三方的工具或者 `jstack [PID] > jstack.log` 分析堆栈信息,进行定位。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/81/3.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/81/3.md new file mode 100644 index 000000000000..56acd1c8048a --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/81/3.md @@ -0,0 +1,26 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/81/3/ +- /zh-cn/docs3-v2/java-sdk/faq/81/3/ +- /zh-cn/overview/mannual/java-sdk/faq/81/3/ +description: 81-3 - 通过url无法下载文件 +linkTitle: 81-3 - 通过url无法下载文件 +title: 81-3 - 通过url无法下载文件 +type: docs +weight: 3 +--- + + + + + + +### 可能的原因 + +1. url 映射文件不存在。 +2. url 无法连接。 + +### 排查和解决步骤 + +1. 检查 url 映射文件是否存在。 +2. 通过浏览器或其他工具,能否正常访问。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/81/4.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/81/4.md new file mode 100644 index 000000000000..1fb0738db147 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/81/4.md @@ -0,0 +1,30 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/81/4/ +- /zh-cn/docs3-v2/java-sdk/faq/81/4/ +- /zh-cn/overview/mannual/java-sdk/faq/81/4/ +description: 81-4 - 嵌入式ZooKeeper运行异常 +linkTitle: 81-4 - 嵌入式ZooKeeper运行异常 +title: 81-4 - 嵌入式ZooKeeper运行异常 +type: docs +weight: 4 +--- + + + + + + +### 可能的原因 + +1. ZooKeeper 服务运行异常或宕机。 +2. Zookeeper 客户端版本与服务端启动版本不兼容,无法连接。 +3. 应用服务器与 ZooKeeper 服务连接中断。 +4. 受限防火墙或第三方防护工具。 + +### 排查和解决步骤 + +1. 检查 ZooKeeper 服务及所在服务器健康状态。 +2. 检查 Zookeeper 客户端版本与服务端启动版本是否存在兼容问题,保持版本一致。 +3. 检查应用服务器与 ZooKeeper 服务端口是否通畅。 +4. 检查防火墙或第三方防护工具设置,是否已禁止。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/81/_index.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/81/_index.md new file mode 100644 index 000000000000..3afa03d52492 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/81/_index.md @@ -0,0 +1,18 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/81/ +- /zh-cn/docs3-v2/java-sdk/faq/81/ +- /zh-cn/overview/mannual/java-sdk/faq/81/_index/ +description: 81 - 单元测试辅助模块(注册中心) +linkTitle: 81 - 单元测试辅助模块(注册中心) +title: 81 - 单元测试辅助模块(注册中心) +type: docs +weight: 81 +--- + + + + + + +这里主要是 `dubbo-test` 模块中用于测试注册中心模块的代码的相关错误码。 diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/99/0.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/99/0.md similarity index 87% rename from content/zh-cn/overview/mannual/java-sdk/faq/99/0.md rename to content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/99/0.md index 3a5b968ed78c..fa86ec7a4f07 100644 --- a/content/zh-cn/overview/mannual/java-sdk/faq/99/0.md +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/99/0.md @@ -1,7 +1,8 @@ --- aliases: - - /zh/docs3-v2/java-sdk/faq/99/0/ - - /zh-cn/docs3-v2/java-sdk/faq/99/0/ +- /zh/docs3-v2/java-sdk/faq/99/0/ +- /zh-cn/docs3-v2/java-sdk/faq/99/0/ +- /zh-cn/overview/mannual/java-sdk/faq/99/0/ description: 99-0 - 内部未知错误 linkTitle: 99-0 - 内部未知错误 title: 99-0 - 内部未知错误 @@ -26,4 +27,4 @@ Dubbo 内部的未知错误。 5. 如果都没解决,请尽可能做出一个复现该问题的最小 Demo,之后到 [GitHub Issue Tracker](https://github.com/apache/dubbo/issues) 下发 Issue。 > 另请参阅 -[配置项手册](/zh-cn/overview/mannual/java-sdk/reference-manual/config/properties/) \ No newline at end of file +[配置项手册](/zh-cn/overview/mannual/java-sdk/reference-manual/config/properties/) diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/99/1.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/99/1.md new file mode 100644 index 000000000000..56fb31b83cea --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/99/1.md @@ -0,0 +1,27 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/99/1/ +- /zh-cn/docs3-v2/java-sdk/faq/99/1/ +- /zh-cn/overview/mannual/java-sdk/faq/99/1/ +description: 99-1 - 程序被打断 +linkTitle: 99-1 - 程序被打断 +title: 99-1 - 程序被打断 +type: docs +weight: 2 +--- + + + + + +Dubbo 内部的未知错误。 + +### 可能的原因 + +程序收到来自 JVM 层面的打断通知,被迫停止阻塞等待 + +### 排查和解决步骤 + +此异常通常发生在线程池关闭或者应用关闭的过程中。 +请检查是否影响业务正常使用,如无影响可以忽略,如果有影响请参照对应的排查手册。 +更多的排查思路可以参考 [99-0](../0/) 一文。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/99/_index.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/99/_index.md new file mode 100644 index 000000000000..54769f408c6f --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/99/_index.md @@ -0,0 +1,11 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/99/ +- /zh-cn/docs3-v2/java-sdk/faq/99/ +- /zh-cn/overview/mannual/java-sdk/faq/99/_index/ +description: 99 - 其它未知错误 +linkTitle: 99 - 其它未知错误 +title: 99 - 其它未知错误 +type: docs +weight: 99 +--- diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/_index.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/_index.md new file mode 100755 index 000000000000..d1a247a7db2b --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/_index.md @@ -0,0 +1,18 @@ +--- +aliases: +- /zh/docs3-v2/java-sdk/faq/ +- /zh-cn/docs3-v2/java-sdk/faq/ +- /zh-cn/overview/mannual/java-sdk/faq/_index/ +description: 错误码 FAQ +linkTitle: 错误码 FAQ +title: 错误码 FAQ +type: docs +weight: 199 +--- + + + + + + +这里主要是提供 Java SDK 中各个错误码的可能原因和解决方法。 diff --git a/content/zh-cn/overview/mannual/java-sdk/faq/intro.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/intro.md similarity index 90% rename from content/zh-cn/overview/mannual/java-sdk/faq/intro.md rename to content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/intro.md index 9a68d87c8bc9..b6603302232c 100644 --- a/content/zh-cn/overview/mannual/java-sdk/faq/intro.md +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/faq/intro.md @@ -1,7 +1,9 @@ --- aliases: - - /zh/docs3-v2/java-sdk/faq/intro/ - - /zh-cn/docs3-v2/java-sdk/faq/intro/ +- /zh/docs3-v2/java-sdk/faq/intro/ +- /zh-cn/docs3-v2/java-sdk/faq/intro/ +- /zh-cn/overview/mannual/java-sdk/faq/intro/ +- /zh-cn/overview/java-sdk/reference-manual/faq/intro/ description: 错误码机制的介绍 linkTitle: 错误码机制的介绍 title: 错误码机制的介绍 @@ -48,4 +50,4 @@ void warn(String code, String cause, String extendedInformation, String msg, Thr 其中 code 指错误码,cause 指可能的原因(即 caused by... 后面所接的文字),extendedInformation 作为补充信息,直接附加在 caused by 这句话的后面。 -> 对于 error 级别也做了相同的扩展。 \ No newline at end of file +> 对于 error 级别也做了相同的扩展。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/graalvm/_index.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/graalvm/_index.md index 7d0272061f8a..035bda8d933b 100644 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/graalvm/_index.md +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/graalvm/_index.md @@ -4,9 +4,8 @@ aliases: - /zh-cn/docs3-v2/java-sdk/reference-manual/graalvm/ description: "" hide_summary: true -linkTitle: Dubbo 集成 Graalvm参考手册 +linkTitle: GraalVM title: Dubbo 集成 Graalvm参考手册 -toc_hide: true type: docs weight: 9 --- diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/support-graalvm.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/graalvm/support-graalvm.md similarity index 80% rename from content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/support-graalvm.md rename to content/zh-cn/overview/mannual/java-sdk/reference-manual/graalvm/support-graalvm.md index 93cf7934cfe0..947998df91a5 100644 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/support-graalvm.md +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/graalvm/support-graalvm.md @@ -2,20 +2,23 @@ aliases: - /zh/docs3-v2/java-sdk/advanced-features-and-usage/performance/support-graalvm/ - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/performance/support-graalvm/ -description: Dubbo 支持 GraalVM Native Image + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/support-graalvm/ +description: "Dubbo AOT 技术详解,如何使用 GraalVM Native Image 实现 Dubbo 应用静态化。" linkTitle: 支持 GraalVM Native Image -title: 支持 Graal VM +title: "Dubbo AOT -- 如何使用 GraalVM Native Image 实现 Dubbo 应用静态化" type: docs weight: 40 --- +在 Dubbo 3.3.0 版本中,我们正式发布了 Dubbo AOT 静态化解决方案。本文档将介绍将介绍如何借助 Dubbo AOT 技术将应用接入 GraalVM Native Image,将应用编译为 Native 二进制包的流程以及目前支持的组件。 - - -## 功能说明 -Dubbo3.2 支持 Native-Image 文档, 本文档将介绍将 dubbo3.x 项目接入 GraalVM Native Image,进行 native-image 编译为二进制的流程以及目前支持的组件。 +{{% alert title="Dubbo GraalVM 适配文档可能更新滞后" color="warning" %}} +由于 Dubbo AOT 技术发展迅速,本文档内容可能无法总是保持及时更新,请结合以下内容了解最新内容与使用方式: +* 示例项目源码 +* 博客文章与演讲 关于 GraalVm 的更多信息可以阅读 https://www.graalvm.org/docs/getting-started/container-images/ 此文档。 +{{% /alert %}} ## 使用场景 - 本机映像编译:将应用程序预编译为本机映像,缩短启动时间并减少内存使用。 @@ -188,29 +191,29 @@ dubbo: ### 序列化组件 -| 组件名称 | 所需的插件 | 插件版本 | 备注 | -| ------------ | ------------------- | --------------------------------------- | ---------------------------- | -| FastJson2 | dubbo-maven-plugin | 3.3.0-beta.1-SNAPSHOT (Preview)及其以上 | | -| JDK | native-maven-plugin | 0.9.24 及其以上 | | -| Hessian-Lite | | | 对JDK 17支持不友好,暂不支持 | +| 组件名称 | 所需的插件 | 插件版本 | 备注 | +| ------------ | ------------------- |-------------| ---------------------------- | +| FastJson2 | dubbo-maven-plugin | 3.3.0 及其以上 | | +| JDK | native-maven-plugin | 0.9.24 及其以上 | | +| Hessian-Lite | | | 对JDK 17支持不友好,暂不支持 | ### 注册中心组件 | 组件名称 | 所需的插件 | 插件版本 | 备注 | | --------- | ------------------ | ------------------------------- | ------------------------ | -| Zookeeper | dubbo-maven-plugin | 3.3.0-beta.1-SNAPSHOT (Preview) | 仅支持Zookeeper Curator5 | +| Zookeeper | dubbo-maven-plugin | 3.3.0 | 仅支持Zookeeper Curator5 | ### 元数据中心组件 | 组件名称 | 所需的插件 | 插件版本 | 备注 | | --------- | ------------------ | ------------------------------- | ------------------------ | -| Zookeeper | dubbo-maven-plugin | 3.3.0-beta.1-SNAPSHOT (Preview) | 仅支持Zookeeper Curator5 | +| Zookeeper | dubbo-maven-plugin | 3.3.0 | 仅支持Zookeeper Curator5 | ### 配置中心组件 -| 组件名称 | 所需的插件 | 插件版本 | 备注 | -| --------- | ------------------ | ------------------------------- | ------------------------ | -| Zookeeper | dubbo-maven-plugin | 3.3.0-beta.1-SNAPSHOT (Preview) | 仅支持Zookeeper Curator5 | +| 组件名称 | 所需的插件 | 插件版本 | 备注 | +| --------- | ------------------ |-------| ------------------------ | +| Zookeeper | dubbo-maven-plugin | 3.3.0 | 仅支持Zookeeper Curator5 | ### 可观测性组件 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/merics/_index.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/merics/_index.md new file mode 100644 index 000000000000..40b7c93713bc --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/merics/_index.md @@ -0,0 +1,11 @@ +--- +aliases: + - /zh/docs3-v2/java-sdk/reference-manual/mesh/ + - /zh-cn/docs3-v2/java-sdk/reference-manual/mesh/ +description: Dubbo Mesh 使用指南 +linkTitle: Mesh手册 +title: Mesh手册 +type: docs +weight: 98 +toc_hide: true +--- diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/observability/meter.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/merics/meter.md similarity index 98% rename from content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/observability/meter.md rename to content/zh-cn/overview/mannual/java-sdk/reference-manual/merics/meter.md index 5c6f9c735327..efe8534aa980 100644 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/observability/meter.md +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/merics/meter.md @@ -31,7 +31,7 @@ Dubbo Metrics 的总体设计请参考 [可观测性 Metrics Proposal](/zh-cn/ov ``` * 完整示例请参见 dubbo-samples-metrics-spring-boot -* 完整配置参数请参见 [Metrics 配置项手册](../../../reference-manual/config/properties/#metrics) +* 完整配置参数请参见 [Metrics 配置项手册](/zh-cn/overview/mannual/java-sdk/reference-manual/config/properties//) ## 实现原理解析 @@ -328,4 +328,4 @@ public class TimeWindowQuantile { 其中,address、port、url 均是可选项,如不配置则 Admin 使用默认约定值。 -> 用户直接在Dubbo配置文件中配置Prometheus Pushgateway的地址即可,如,其中interval代表推送间隔 \ No newline at end of file +> 用户直接在Dubbo配置文件中配置Prometheus Pushgateway的地址即可,如,其中interval代表推送间隔 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/mesh/_index.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/mesh/_index.md index 9aecb1f5ac59..40b7c93713bc 100644 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/mesh/_index.md +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/mesh/_index.md @@ -6,5 +6,6 @@ description: Dubbo Mesh 使用指南 linkTitle: Mesh手册 title: Mesh手册 type: docs -weight: 7 +weight: 98 +toc_hide: true --- diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/metadata-center/_index.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/metadata-center/_index.md index c7bf5722ce57..81b2a134a551 100644 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/metadata-center/_index.md +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/metadata-center/_index.md @@ -7,5 +7,5 @@ description: Dubbo 元数据中心基本使用与工作原理 linkTitle: 元数据中心 title: 元数据中心 type: docs -weight: 5 +weight: 7 --- diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/metadata-center/nacos.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/metadata-center/nacos.md index 5c23b2764c6d..04a6817adb63 100644 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/metadata-center/nacos.md +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/metadata-center/nacos.md @@ -10,14 +10,9 @@ type: docs weight: 2 --- - - - - - ## 1 预备工作 - 了解 [Dubbo 基本开发步骤](/zh-cn/overview/mannual/java-sdk/quick-start/spring-boot/) -- 参考 [Nacos快速入门](https://nacos.io/zh-cn/docs/quick-start.html) 启动 Nacos server +- 参考 [Nacos](/zh-cn/overview/reference/integrations/nacos/) 启动 Nacos server > 当Dubbo使用`3.0.0`及以上版本时,需要使用Nacos `2.0.0`及以上版本 @@ -28,7 +23,7 @@ Dubbo 融合 Nacos 成为元数据中心的操作步骤非常简单,大致分 ### 2.1 增加 Maven 依赖 如果项目已经启用 Nacos 作为注册中心,则无需增加任何额外配置。 -如果未启用 Nacos 注册中心,则请参考 [为注册中心增加 Nacos 依赖](../../registry/nacos/#21-增加依赖)。 +如果未启用 Nacos 注册中心,则请参考 [为注册中心增加 Nacos 依赖](/zh-cn/overview/mannual/java-sdk/reference-manual/registry/nacos/#12-nacos-版本)。 ### 2.2 启用 Nacos 配置中心 ```xml diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/metadata-center/others.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/metadata-center/others.md new file mode 100644 index 000000000000..b3fe43c42530 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/metadata-center/others.md @@ -0,0 +1,84 @@ +--- +aliases: + - /zh/docs3-v2/java-sdk/reference-manual/metadata-center/redis/ + - /zh-cn/docs3-v2/java-sdk/reference-manual/metadata-center/redis/ + - /zh-cn/overview/what/ecosystem/metadata-center/redis/ +description: "更多元数据中心扩展实现,包括 redis、etcd、consul 等" +linkTitle: 扩展实现 +title: 更多元数据中心扩展实现 +type: docs +weight: 4 +--- + +Dubbo 框架还默认提供了 redis、etcd、consul 等元数据中心适配实现 + +## Redis + +Redis 实现由主干库提供内置实现,但需要增加以下依赖: + +```xml + + + redis.clients + jedis + 3.10.0 + + +``` + +```yaml +dubbo + metadata-report + address: redis://127.0.0.1:1111 +``` + +或者 + +```properties +dubbo.metadata-report.address=redis://127.0.0.1:1111 +``` + +## Etcd + +Etcd 元数据中心由社区生态库维护,具体可参见 [](https://github.com/apache/dubbo-spi-extensions/tree/master/dubbo-metadata-report-extensions/dubbo-metadata-report-etcd)。 + +增加依赖: + +```xml + + org.apache.dubbo.extensions + dubbo-metadata-report-etcd + 3.3.0 + +``` + +调整配置: + +```yaml +dubbo + metadata-report + address: etcd://127.0.0.1:1111 +``` + + +## Consul + +Consul 元数据中心由社区生态库维护,具体可参见 [](https://github.com/apache/dubbo-spi-extensions/tree/master/dubbo-metadata-report-extensions/dubbo-metadata-report-consul)。 + +增加依赖: + +```xml + + org.apache.dubbo.extensions + dubbo-metadata-report-consul + 3.3.0 + +``` + +调整配置: + +```yaml +dubbo + metadata-report + address: consul://127.0.0.1:1111 +``` \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/metadata-center/overview.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/metadata-center/overview.md index ff96d162b6b9..daf98308059c 100644 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/metadata-center/overview.md +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/metadata-center/overview.md @@ -10,13 +10,9 @@ weight: 1 --- - - - - 元数据中心为 Dubbo 中的两类元数据提供了存取能力 -- 1 地址发现元数据 -- 2 服务运维元数据 +- 1 地址发现元数据,用于应用级服务发现 +- 2 服务运维元数据,用于外围运维系统如可视化控制台进行服务查询、测试等。 ## 1 地址发现元数据 Dubbo3 中引入了 [应用级服务发现机制](/zh-cn/overview/core-features/service-discovery/#面向百万实例集群的服务发现机制) 用来解决异构微服务体系互通与大规模集群实践的性能问题,应用级服务发现将全面取代 2.x 时代的接口级服务发现。 @@ -46,6 +42,8 @@ $ demo-provider,two-demo-provider,dubbo-demo-annotation-provider `接口级配置元数据`是作为地址发现的补充,相比于 Spring Cloud 等地址发现模型只能同步 ip、port 信息,Dubbo 的服务发现机制可以同步接口列表、接口定义、接口级参数配置等信息。 这部分内容根据当前应用的自身信息、以及接口信息计算而来,并且从性能角度出发,还根据元数据生成 revision,以实现不同机器实例间的元数据聚合。 +> 可通过设置 `dubbo.metadata-report.report-metadata=false` 关闭元数据上报。 + 以 Zookeeper 为例,接口配置元数据保存在以下位置,如果多个实例生成的 revision 相同,则最终会共享同一份元数据配置: `/dubbo/metadata/{application name}/{revision}` @@ -120,6 +118,8 @@ Dubbo 上报的服务运维元数据通常为各种运维系统所用,如服 各种第三方系统可直接读取并使用这部分数据,具体对接方式可参见本章提及的几个第三方系统。 +> 可通过设置 `dubbo.metadata-report.report-definition=false` 关闭元数据上报。 + ### 2.1 Provider 上报的元数据 provider端存储的元数据内容如下: diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/metadata-center/redis.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/metadata-center/redis.md deleted file mode 100644 index 0561833abc6d..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/metadata-center/redis.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/reference-manual/metadata-center/redis/ - - /zh-cn/docs3-v2/java-sdk/reference-manual/metadata-center/redis/ - - /zh-cn/overview/what/ecosystem/metadata-center/redis/ -description: Redis 元数据中心基本使用与工作原理 -linkTitle: Redis -title: Redis -type: docs -weight: 4 ---- - -暂未支持 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/metadata-center/zookeeper.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/metadata-center/zookeeper.md index 1f9c4617ab5a..d169b3e15840 100644 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/metadata-center/zookeeper.md +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/metadata-center/zookeeper.md @@ -13,14 +13,14 @@ weight: 3 ## 1 预备工作 - 了解 [Dubbo 基本开发步骤](/zh-cn/overview/mannual/java-sdk/quick-start/spring-boot/) -- 安装并启动 [Zookeeper](https://zookeeper.apache.org/) +- 安装并启动 [Zookeeper](/zh-cn/overview/reference/integrations/zookeeper/) ## 2 使用说明 ### 2.1 增加 Maven 依赖 如果项目已经启用 Zookeeper 作为注册中心,则无需增加任何额外配置。 -如果未使用 Zookeeper 注册中心,则请参考 [为注册中心增加 Zookeeper 相关依赖](../../registry/zookeeper/#21-增加-maven-依赖)。 +如果未使用 Zookeeper 注册中心,则请参考 [为注册中心增加 Zookeeper 相关依赖](/zh-cn/overview/mannual/java-sdk/reference-manual/registry/zookeeper/#11-增加-maven-依赖)。 ### 2.2 启用 Zookeeper 配置中心 ```xml @@ -52,7 +52,7 @@ metadataConfig.setAddress("zookeeper://127.0.0.1:2181"); ## 3 高级配置 -完整配置参数请参考 [metadata-report-config](../../config/properties/#metadata-report-config)。 +完整配置参数请参考 [metadata-report-config](/zh-cn/overview/mannual/java-sdk/reference-manual/config/properties/#dubbometadata-report)。 ## 4 工作原理 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/performance/_index.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/performance/_index.md index 247ee229c9bd..3796c3466da1 100755 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/performance/_index.md +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/performance/_index.md @@ -3,7 +3,7 @@ aliases: - /zh/docs3-v2/java-sdk/reference-manual/performance/ - /zh-cn/docs3-v2/java-sdk/reference-manual/performance/ description: Dubbo 基准测试性能参考指南 -linkTitle: 性能参考手册 +linkTitle: 性能Benchmark title: 性能参考手册 type: docs weight: 8 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/performance/benchmarking.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/performance/benchmarking.md index d7bf52f0f8e8..1c2e5a6a23b9 100644 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/performance/benchmarking.md +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/performance/benchmarking.md @@ -9,12 +9,6 @@ type: docs weight: 1 --- - - - - - - ## 1 Benchmark 结论 对比 2.x 版本,Dubbo3 版本 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/_index.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/_index.md index ba40804fc9ec..9289bb67279a 100755 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/_index.md +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/_index.md @@ -4,8 +4,8 @@ aliases: - /zh-cn/docs3-v2/java-sdk/reference-manual/protocol/ - /zh/overview/what/ecosystem/protocol/ description: Dubbo RPC 协议指南 -linkTitle: RPC 协议 +linkTitle: RPC协议 title: RPC 协议 type: docs -weight: 4 +weight: 2 --- diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/dubbo.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/dubbo.md index 25cfb9f9d4c0..5d67a7415400 100644 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/dubbo.md +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/dubbo.md @@ -3,17 +3,21 @@ aliases: - /zh/docs3-v2/java-sdk/reference-manual/protocol/dubbo/ - /zh-cn/docs3-v2/java-sdk/reference-manual/protocol/dubbo/ - /zh/overview/what/ecosystem/protocol/dubbo/ -description: Dubbo协议 -linkTitle: Dubbo协议 +description: "本文描述 Dubbo 协议 java 实现的特点与具体实现细节" +linkTitle: dubbo title: Dubbo协议 type: docs -weight: 2 +weight: 3 --- -## 特性说明 -Dubbo 缺省协议采用单一长连接和 NIO 异步通讯,适合于小数据量大并发的服务调用,以及服务消费者机器数远大于服务提供者机器数的情况。 +Dubbo 缺省协议采用单一长连接和 NIO 异步通讯,适合于小数据量大并发的服务调用,以及服务消费者机器数远大于服务提供者机器数的情况。dubbo RPC是dubbo体系中最核心的一种高性能、高吞吐量的远程调用方式,我喜欢称之为多路复用的TCP长连接调用。 + + +主要用于两个dubbo系统之间作远程调用,特别适合高并发、小数据的互联网场景。反之,Dubbo 缺省协议不适合传送大数据量的服务,比如传文件,传视频等,除非请求量很低。 + +* **长连接:避免了每次调用新建TCP连接,提高了调用的响应速度。** +* **多路复用:单个TCP连接可交替传输多个请求和响应的消息,降低了连接的等待闲置时间,从而减少了同样并发数下的网络连接数,提高了系统吞吐量。** -反之,Dubbo 缺省协议不适合传送大数据量的服务,比如传文件,传视频等,除非请求量很低。 ![dubbo-protocol.jpg](/imgs/user/dubbo-protocol.jpg) @@ -56,10 +60,6 @@ Dubbo 缺省协议采用单一长连接和 NIO 异步通讯,适合于小数据 - 会抛异常的情况:枚举值一边多一种,一边少一种,正好使用了差别的那种,或者属性名相同,类型不同。 {{% /alert %}} -## 使用场景 - -适合大并发小数据量的服务调用,服务消费者远大于服务提供者的情景。 - ## 使用方式 ### 配置协议 @@ -114,17 +114,16 @@ Dubbo 协议缺省每服务每提供者每消费者使用单一长连接,如 ## 常见问题 -### Q1 -为什么要消费者比提供者个数多? +### Q1 为什么要消费者比提供者个数多? 因 dubbo 协议采用单一长连接,假设网络为千兆网卡 **1024Mbit=128MByte**,根据测试经验数据每条连接最多只能压满 7MByte(不同的环境可能不一样,供参考),理论上 1 个服务提供者需要 20 个服务消费者才能压满网卡。 -### Q2 -为什么不能传大包? +### Q2 为什么不能传大包? 因 dubbo 协议采用单一长连接,如果每次请求的数据包大小为 500KByte,假设网络为千兆网卡 **1024Mbit=128MByte**,每条连接最大 7MByte (不同的环境可能不一样),单个服务提供者的 TPS(每秒处理事务数)最大为:128MByte / 500KByte = 262。单个消费者调用单个服务提供者的 TPS (每秒处理事务数)最大为:7MByte / 500KByte = 14。如果能接受,可以考虑使用,否则网络将成为瓶颈。 -### Q3 -为什么采用异步单一长连接? +### Q3 为什么采用异步单一长连接? 因为服务的现状大都是服务提供者少,通常只有几台机器,而服务的消费者多,可能整个网站都在访问该服务,比如 Morgan 的提供者只有 6 台提供者,却有上百台消费者,每天有 1.5 亿次调用,如果采用常规的 hessian 服务,服务提供者很容易就被压跨,通过单一连接,保证单一消费者不会压死提供者,长连接,减少连接握手验证等,并使用异步 IO,复用线程池,防止 C10K 问题。 + + diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/grpc.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/grpc.md deleted file mode 100644 index 30c3774d20f7..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/grpc.md +++ /dev/null @@ -1,44 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/reference-manual/protocol/grpc/ - - /zh-cn/docs3-v2/java-sdk/reference-manual/protocol/grpc/ - - /zh/overview/what/ecosystem/protocol/grpc/ -description: gRPC协议 -linkTitle: gRPC协议 -title: gRPC协议 -type: docs -weight: 5 ---- - - - - - - - -## 特性说明 -Dubbo 自 2.7.5 版本开始支持 gRPC 协议,对于计划使用 HTTP/2 通信,或者想利用 gRPC 带来的 Stream、反压、Reactive 编程等能力的开发者来说, -都可以考虑启用 gRPC 协议。 - -#### 支持 gRPC 的好处 -* 为期望使用 gRPC 协议的用户带来服务治理能力,方便接入 Dubbo 体系 -* 用户可以使用 Dubbo 风格的,基于接口的编程风格来定义和使用远程服务 - -## 使用场景 - -- 需要立即响应才能继续处理的同步后端微服务到微服务通信。 -- 需要支持混合编程平台的 Polyglot 环境。 -- 性能至关重要的低延迟和高吞吐量通信。 -- 点到点实时通信 - gRPC 无需轮询即可实时推送消息,并且能对双向流式处理提供出色的支持。 -- 网络受约束环境 - 二进制 gRPC 消息始终小于等效的基于文本的 JSON 消息。 - -## 使用方式 -### 在 Dubbo 中使用 gRPC -[示例](https://github.com/apache/dubbo-samples/tree/925c3d150d9030bc72988564e4f97eca1f6fcb89/3-extensions/protocol/dubbo-samples-grpc) - -### 步骤 -1. 使用 IDL 定义服务 -2. 配置 compiler 插件,本地预编译 -3. 配置暴露/引用 Dubbo 服务 - -> 除了原生 StreamObserver 接口类型之外,Dubbo 还支持 [RxJava](https://github.com/apache/dubbo-samples/tree/925c3d150d9030bc72988564e4f97eca1f6fcb89/3-extensions/protocol/dubbo-samples-grpc/dubbo-samples-rxjava)、[Reactor](https://github.com/apache/dubbo-samples/tree/925c3d150d9030bc72988564e4f97eca1f6fcb89/3-extensions/protocol/dubbo-samples-grpc/dubbo-samples-reactor) 编程风格的 API。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/hessian.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/hessian.md deleted file mode 100644 index 58cfe4508363..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/hessian.md +++ /dev/null @@ -1,89 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/reference-manual/protocol/hessian/ - - /zh-cn/docs3-v2/java-sdk/reference-manual/protocol/hessian/ -description: Hessian协议 -linkTitle: Hessian协议 -title: Hessian协议 -type: docs -weight: 10 ---- - - - - - - - -## 特性说明 -Hessian 协议用于集成 Hessian 的服务,Hessian 底层采用 Http 通讯,采用 Servlet 暴露服务,Dubbo 缺省内嵌 Jetty 作为服务器实现。 - -[Hessian](http://hessian.caucho.com) 是 Caucho 开源的一个 RPC 框架,其通讯效率高于 WebService 和 Java 自带的序列化。 - -* 连接个数:多连接 -* 连接方式:短连接 -* 传输协议:HTTP -* 传输方式:同步传输 -* 序列化:Hessian二进制序列化 -* 适用范围:传入传出参数数据包较大,提供者比消费者个数多,提供者压力较大,可传文件。 -* 适用场景:页面传输,文件传输,或与原生hessian服务互操作。 - -Dubbo 的 Hessian 协议可以和原生 Hessian 服务互操作,即: - -* 提供者用 Dubbo 的 Hessian 协议暴露服务,消费者直接用标准 Hessian 接口调用, -* 或者提供方用标准 Hessian 暴露服务,消费方用 Dubbo 的 Hessian 协议调用。 - -#### 约束 -* 参数及返回值需实现 `Serializable` 接口。 -* 参数及返回值不能自定义实现 `List`, `Map`, `Number`, `Date`, `Calendar` 等接口,只能用 JDK 自带的实现,因为 hessian 会做特殊处理,自定义实现类中的属性值都会丢失。 - -## 使用场景 -hessian是一个轻量级的RPC服务,是基于Binary-RPC协议实现的,序列化与反序列化实例。 - - -## 使用方式 - -### 依赖 - -从 Dubbo 3 开始,Hessian 协议已经不再内嵌在 Dubbo 中,需要单独引入独立的[模块](/zh-cn/download/spi-extensions/#dubbo-rpc)。 -```xml - - org.apache.dubbo.extensions - dubbo-rpc-hessian - 1.0.0 - -``` - -```xml - - com.caucho - hessian - 4.0.7 - -``` - -### 定义 hessian 协议 -```xml - -``` - -### 设置默认协议 -```xml - -``` - -### 设置 service 协议 -```xml - -``` - -### 多端口 -```xml - - -``` - -### 直连 -```xml - -``` \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/http.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/http.md deleted file mode 100644 index 067fd8bf65f4..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/http.md +++ /dev/null @@ -1,81 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/reference-manual/protocol/http/ - - /zh-cn/docs3-v2/java-sdk/reference-manual/protocol/http/ - - /zh/overview/what/ecosystem/protocol/http/ -description: HTTP协议 -linkTitle: HTTP协议 -title: HTTP协议 -type: docs -weight: 6 ---- - - - - - - - -## 特性说明 -基于 HTTP 表单的远程调用协议,采用 Spring 的 HttpInvoker 实现,`2.3.0` 以上版本支持。 - -* 连接个数:多连接 -* 连接方式:短连接 -* 传输协议:HTTP -* 传输方式:同步传输 -* 序列化:表单序列化 -* 适用范围:传入传出参数数据包大小混合,提供者比消费者个数多,可用浏览器查看,可用表单或URL传入参数,暂不支持传文件。 -* 适用场景:需同时给应用程序和浏览器 JS 使用的服务。 - -#### 约束 -* 参数及返回值需符合 Bean 规范 - -## 使用场景 - -http短连接,协议标准化且易读,容易对接外部系统,适用于上层业务模块。 - -## 使用方式 - -从 Dubbo 3 开始,Http 协议已经不再内嵌在 Dubbo 中,需要单独引入独立的[模块](/zh-cn/download/spi-extensions/#dubbo-rpc)。 -```xml - - org.apache.dubbo.extensions - dubbo-rpc-http - 1.0.0 - -``` - -### 配置协议 -```xml - -``` - -### 配置 Jetty Server (默认) -```xml - -``` - -### 配置 Servlet Bridge Server (推荐使用) -```xml - -``` - -### 配置 DispatcherServlet - -```xml - - dubbo - org.apache.dubbo.remoting.http.servlet.DispatcherServlet - 1 - - - dubbo - /* - -``` - -{{% alert title="注意" color="primary" %}} -如果使用 servlet 派发请求 -* 协议的端口 `` 必须与 servlet 容器的端口相同, -* 协议的上下文路径 `` 必须与 servlet 应用的上下文路径相同。 -{{% /alert %}} diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/memcached.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/memcached.md deleted file mode 100644 index 8f6c8686401d..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/memcached.md +++ /dev/null @@ -1,71 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/reference-manual/protocol/memcached/ - - /zh-cn/docs3-v2/java-sdk/reference-manual/protocol/memcached/ -description: Memcached协议 -linkTitle: Memcached协议 -title: Memcached协议 -type: docs -weight: 12 ---- - - - - - -## 特性说明 -[Memcached](http://memcached.org/) 是一个高效的 KV 缓存服务器。基于 memcached 实现的 RPC 协议。 - -> `2.3.0` 以上版本支持。 - - - -## 使用场景 -缓解数据库压力,提高交互速度等。 - -## 使用方式 -### 引入依赖 - -从 Dubbo 3 开始,Memcached 协议已经不再内嵌在 Dubbo 中,需要单独引入独立的[模块](/zh-cn/download/spi-extensions/#dubbo-rpc)。 -```xml - - org.apache.dubbo.extensions - dubbo-rpc-memcached - 1.0.0 - -``` - -### 注册 memcached 服务的地址 -```java -RegistryFactory registryFactory = ExtensionLoader.getExtensionLoader(RegistryFactory.class).getAdaptiveExtension(); -Registry registry = registryFactory.getRegistry(URL.valueOf("zookeeper://10.20.153.10:2181")); -registry.register(URL.valueOf("memcached://10.20.153.11/com.foo.BarService?category=providers&dynamic=false&application=foo&group=member&loadbalance=consistenthash")); -``` - -### 在客户端引用 -**不需要感知 Memcached 的地址** - -在客户端使用 - -```xml - -``` - -或者点对点直连 - -```xml - -``` - -也可以使用自定义接口 -```xml - -``` - -其中 "p:xxx" 为 spring 的标准 p 标签 -```xml - -``` -如果方法名和 memcached 的标准方法名不相同,则需要配置映射关系; - -方法名建议和 memcached 的标准方法名相同,即:get(key), set(key, value), delete(key)。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/multi-protocols.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/multi-protocols.md new file mode 100644 index 000000000000..123c5265cbb1 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/multi-protocols.md @@ -0,0 +1,136 @@ +--- +aliases: + - /zh/docs3-v2/java-sdk/advanced-features-and-usage/service/multi-protocols/ + - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/service/multi-protocols/ + - /zh-cn/overview/tasks/protocols/multi-protocols/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/multi-protocols +description: 在 Dubbo 中配置多协议 +linkTitle: 多协议 +title: 多协议 +type: docs +weight: 4 +--- + +区别于普通的 RPC 框架,Dubbo 作为一款微服务框架提供了非常灵活的协议支持,它不绑定一个单一通信协议。因此你**可以发布在一个进程中同时发布多个 RPC 协议、调用不同的 RPC 协议**。接下来我们就详细介绍多协议的具体使用场景与使用方式。 + +## 使用场景 +有很多场景可能会用到不同的协议,包括安全性、性能、与第三方系统互调等业务诉求。本文我们不分析具体的业务需求,而是从 Dubbo 框架提供的多协议能力出发分析框架能提供的多协议能力: + +* 作为服务提供者(provider),同一个服务发布为多个协议,供不同消费端调用 +* 作为服务提供者(provider),多个服务分别发布为不同协议,供不同消费端调用 +* 作为服务消费者(consumer),指定以某个特定协议调用某一个服务 + +## 使用方式 + +### 同一个服务发布为多个协议 + +如果使用 Spring Boot,可以修改 application.yml 或 application.properties 如下: +```yaml +dubbo: + protocols: + - id: dubbo-id + name: dubbo + port: 20880 + - id: tri-id + name: tri + port: 50051 +``` + +对于 Spring XML: + +```xml + + +``` + +接下来为服务配置(默认不配置的情况下,服务会发布到以上所有协议配置): + +```java +@DubboService(protocol="dubbo-id,triple-id") +private DemoServiceImpl implements DemoService {} +``` + +### 多个服务分别发布为不同协议 + +如果使用 Spring Boot,可以修改 application.yml 或 application.properties 如下: +```yaml +dubbo: + protocols: + - id: dubbo-id + name: dubbo + port: 20880 + - id: tri-id + name: tri + port: 50051 +``` + +接下来为不同的服务分别配置不同的协议引用: + +```java +@DubboService(protocol="dubbo-id") +private DemoServiceImpl implements DemoService {} +``` + +```java +@DubboService(protocol="triple-id") +private GreetingServiceImpl implements GreetingService {} +``` + +### 指定协议调用服务 + +对于消费端而言,直接在声明引用的时候指定要调用的协议关键字就可以了: + +```java +@DubboReference(protocol="dubbo") +private DemoService demoService; +``` + +```java +@DubboReference(protocol="tri") +private GreetingService greetingService; +``` + +## 不同的实现方式 + +### 多端口多协议 +多协议发布是指为同一个服务同时提供多种协议访问方式,多协议可以是任意两个或多个协议的组合,比如下面的配置将同时发布了 dubbo、triple 协议: + +```yaml +dubbo: + protocols: + - name: tri + port: 50051 + - name: dubbo + port: 20880 +``` + +基于以上配置,如果应用中有服务 DemoService,则既可以通过 dubbo 协议访问 DemoService,也可以通过 triple 协议访问 DemoService,其工作原理图如下: + +多协议 + +1. 提供者实例同时监听两个端口 20880 和 50051 +2. 同一个实例,会在注册中心注册两条地址 url +3. 不同的消费端可以选择以不同协议调用同一个提供者发布的服务 + +对于消费端而言,如果用户没有明确配置,默认情况下框架会自动选择 `dubbo` 协议调用。Dubbo 框架支持配置通过哪个协议访问服务,如 `@DubboReference(protocol="tri")`,或者在 application.yml 配置文件中指定全局默认值: + +```yaml +dubbo: + consumer: + protocol: tri +``` + +### 单端口多协议 + +除了以上发布多个端口、注册多条 url 到注册中心的方式。对于 dubbo、triple 这两个内置协议,框架提供了在单个端口上同时发布 dubbo 和 triple 协议的能力。这对于老用户来说是一个非常重要的能力,因为它可以做到不增加任何负担的情况下,让使用 dubbo 协议的用户可以额外发布 triple 协议,这样当所有的应用都实现多协议发布之后,我们就可以设置消费端去通过 triple 协议发起调用了。 + +单端口多协议 + +单端口多协议的基本配置如下: + + ```yaml + dubbo: + protocol: + name: dubbo + ext-protocol: tri + ``` diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/others/_index.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/others/_index.md new file mode 100755 index 000000000000..ae16b6a99d5a --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/others/_index.md @@ -0,0 +1,11 @@ +--- +aliases: + - /zh/docs3-v2/java-sdk/reference-manual/protocol/ + - /zh-cn/docs3-v2/java-sdk/reference-manual/protocol/ + - /zh/overview/what/ecosystem/protocol/ +description: Dubbo RPC 协议指南 +linkTitle: 扩展实现 +title: Dubbo 提供的更多 RPC 扩展协议实现 +type: docs +weight: 100 +--- diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/others/hessian.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/others/hessian.md new file mode 100644 index 000000000000..e22981e1813b --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/others/hessian.md @@ -0,0 +1,87 @@ +--- +aliases: + - /zh/docs3-v2/java-sdk/reference-manual/protocol/hessian/ + - /zh-cn/docs3-v2/java-sdk/reference-manual/protocol/hessian/ + - /zh-cn/overview/mannual/java-sdk/reference-manual/protocol/hessian/ +description: Hessian协议 +linkTitle: Hessian协议 +title: Hessian协议 +type: docs +weight: 10 +--- + + + + +## 特性说明 +Hessian 协议用于集成 Hessian 的服务,Hessian 底层采用 Http 通讯,采用 Servlet 暴露服务,Dubbo 缺省内嵌 Jetty 作为服务器实现。 + +[Hessian](http://hessian.caucho.com) 是 Caucho 开源的一个 RPC 框架,其通讯效率高于 WebService 和 Java 自带的序列化。 + +* 连接个数:多连接 +* 连接方式:短连接 +* 传输协议:HTTP +* 传输方式:同步传输 +* 序列化:Hessian二进制序列化 +* 适用范围:传入传出参数数据包较大,提供者比消费者个数多,提供者压力较大,可传文件。 +* 适用场景:页面传输,文件传输,或与原生hessian服务互操作。 + +Dubbo 的 Hessian 协议可以和原生 Hessian 服务互操作,即: + +* 提供者用 Dubbo 的 Hessian 协议暴露服务,消费者直接用标准 Hessian 接口调用, +* 或者提供方用标准 Hessian 暴露服务,消费方用 Dubbo 的 Hessian 协议调用。 + +#### 约束 +* 参数及返回值需实现 `Serializable` 接口。 +* 参数及返回值不能自定义实现 `List`, `Map`, `Number`, `Date`, `Calendar` 等接口,只能用 JDK 自带的实现,因为 hessian 会做特殊处理,自定义实现类中的属性值都会丢失。 + +## 使用场景 +hessian是一个轻量级的RPC服务,是基于Binary-RPC协议实现的,序列化与反序列化实例。 + + +## 使用方式 + +### 依赖 + +从 Dubbo 3 开始,Hessian 协议已经不再内嵌在 Dubbo 中,需要单独引入独立的[模块](/zh-cn/download/spi-extensions/#dubbo-rpc)。 +```xml + + org.apache.dubbo.extensions + dubbo-rpc-hessian + 3.3.0 + +``` + +```xml + + com.caucho + hessian + 4.0.7 + +``` + +### 定义 hessian 协议 +```xml + +``` + +### 设置默认协议 +```xml + +``` + +### 设置 service 协议 +```xml + +``` + +### 多端口 +```xml + + +``` + +### 直连 +```xml + +``` diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/others/http.md.bak b/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/others/http.md.bak new file mode 100644 index 000000000000..b06415fe1389 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/others/http.md.bak @@ -0,0 +1,81 @@ +--- +aliases: + - /zh/docs3-v2/java-sdk/reference-manual/protocol/http/ + - /zh-cn/docs3-v2/java-sdk/reference-manual/protocol/http/ + - /zh/overview/what/ecosystem/protocol/http/ +description: HTTP协议 +linkTitle: HTTP协议 +title: HTTP协议 +type: docs +weight: 6 +--- + + + + + + + +## 特性说明 +基于 HTTP 表单的远程调用协议,采用 Spring 的 HttpInvoker 实现,`2.3.0` 以上版本支持。 + +* 连接个数:多连接 +* 连接方式:短连接 +* 传输协议:HTTP +* 传输方式:同步传输 +* 序列化:表单序列化 +* 适用范围:传入传出参数数据包大小混合,提供者比消费者个数多,可用浏览器查看,可用表单或URL传入参数,暂不支持传文件。 +* 适用场景:需同时给应用程序和浏览器 JS 使用的服务。 + +#### 约束 +* 参数及返回值需符合 Bean 规范 + +## 使用场景 + +http短连接,协议标准化且易读,容易对接外部系统,适用于上层业务模块。 + +## 使用方式 + +从 Dubbo 3 开始,Http 协议已经不再内嵌在 Dubbo 中,需要单独引入独立的[模块](/zh-cn/download/spi-extensions/#dubbo-rpc)。 +```xml + + org.apache.dubbo.extensions + dubbo-rpc-http + 3.3.0 + +``` + +### 配置协议 +```xml + +``` + +### 配置 Jetty Server (默认) +```xml + +``` + +### 配置 Servlet Bridge Server (推荐使用) +```xml + +``` + +### 配置 DispatcherServlet + +```xml + + dubbo + org.apache.dubbo.remoting.http.servlet.DispatcherServlet + 1 + + + dubbo + /* + +``` + +{{% alert title="注意" color="primary" %}} +如果使用 servlet 派发请求 +* 协议的端口 `` 必须与 servlet 容器的端口相同, +* 协议的上下文路径 `` 必须与 servlet 应用的上下文路径相同。 +{{% /alert %}} diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/others/memcached.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/others/memcached.md new file mode 100644 index 000000000000..6e861e7ec71a --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/others/memcached.md @@ -0,0 +1,57 @@ +--- +aliases: + - /zh-cn/overview/mannual/java-sdk/reference-manual/protocol/memcached/ +description: Memcached 协议 +linkTitle: Memcached 协议 +title: Memcached 协议 +type: docs +weight: 5 +--- + + + +基于 memcached [^1] 实现的 RPC 协议。 + +{{% alert title="提示" color="primary" %}} +`2.3.0` 以上版本支持 +{{% /alert %}} + +## 注册 memcached 服务的地址 + +```java +RegistryFactory registryFactory = ExtensionLoader.getExtensionLoader(RegistryFactory.class).getAdaptiveExtension(); +Registry registry = registryFactory.getRegistry(URL.valueOf("zookeeper://10.20.153.10:2181")); +registry.register(URL.valueOf("memcached://10.20.153.11/com.foo.BarService?category=providers&dynamic=false&application=foo&group=member&loadbalance=consistenthash")); +``` + +## 在客户端引用 + +在客户端使用 [^2]: + +```xml + +``` + +或者,点对点直连: + +```xml + +``` + +也可以使用自定义接口: + +```xml + +``` + +方法名建议和 memcached 的标准方法名相同,即:get(key), set(key, value), delete(key)。 + +如果方法名和 memcached 的标准方法名不相同,则需要配置映射关系 [^3]: + +```xml + +``` + +[^1]: [Memcached](http://memcached.org/) 是一个高效的 KV 缓存服务器 +[^2]: 不需要感知 Memcached 的地址 +[^3]: 其中 "p:xxx" 为 spring 的标准 p 标签 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/others/redis.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/others/redis.md new file mode 100644 index 000000000000..677e3dc8735e --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/others/redis.md @@ -0,0 +1,58 @@ +--- +aliases: + - /zh-cn/overview/mannual/java-sdk/reference-manual/protocol/redis/ +description: Redis 协议 +linkTitle: Redis 协议 +title: Redis 协议 +type: docs +weight: 4 +--- + + + + +基于 Redis [^1] 实现的 RPC 协议。 + +{{% alert title="提示" color="primary" %}} +`2.3.0` 以上版本支持 +{{% /alert %}} + +## 注册 redis 服务的地址 + +```java +RegistryFactory registryFactory = ExtensionLoader.getExtensionLoader(RegistryFactory.class).getAdaptiveExtension(); +Registry registry = registryFactory.getRegistry(URL.valueOf("zookeeper://10.20.153.10:2181")); +registry.register(URL.valueOf("redis://10.20.153.11/com.foo.BarService?category=providers&dynamic=false&application=foo&group=member&loadbalance=consistenthash")); +``` + +## 在客户端引用 + +在客户端使用 [^2]: + +```xml + +``` + +或者,点对点直连: + +```xml + +``` + +也可以使用自定义接口: + +```xml + +``` + +方法名建议和 redis 的标准方法名相同,即:get(key), set(key, value), delete(key)。 + +如果方法名和 redis 的标准方法名不相同,则需要配置映射关系 [^3]: + +```xml + +``` + +[^1]: [Redis](http://redis.io) 是一个高效的 KV 存储服务器 +[^2]: 不需要感知 Redis 的地址 +[^3]: 其中 "p:xxx" 为 spring 的标准 p 标签 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/rmi.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/others/rmi.md similarity index 97% rename from content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/rmi.md rename to content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/others/rmi.md index 3b88e8f097a9..191f6463e2d0 100644 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/rmi.md +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/others/rmi.md @@ -3,6 +3,7 @@ aliases: - /zh/docs3-v2/java-sdk/reference-manual/protocol/rmi/ - /zh-cn/docs3-v2/java-sdk/reference-manual/protocol/rmi/ - /zh/overview/what/ecosystem/protocol/rmi/ + - /zh-cn/overview/mannual/java-sdk/reference-manual/protocol/rmi/ description: Rmi协议 linkTitle: Rmi协议 title: Rmi协议 @@ -45,7 +46,7 @@ RMI 协议采用 JDK 标准的 `java.rmi.*` 实现,采用阻塞式短连接和 org.apache.dubbo.extensions dubbo-rpc-rmi - 1.0.0 + 3.3.0 ``` diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/others/thrift.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/others/thrift.md new file mode 100644 index 000000000000..028ddbf24c5a --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/others/thrift.md @@ -0,0 +1,49 @@ +--- +aliases: + - /zh-cn/overview/mannual/java-sdk/reference-manual/protocol/thrift/ +description: Thrift 协议 +linkTitle: Thrift 协议 +title: Thrift 协议 +type: docs +weight: 4 +--- + + + + +当前 dubbo 支持的 thrift 协议是对 thrift 原生协议 [^1] 的扩展,在原生协议的基础上添加了一些额外的头信息,比如 service name,magic number 等。 + +{{% alert title="提示" color="primary" %}} +`2.3.0` 以上版本支持 +{{% /alert %}} + +使用 dubbo thrift 协议同样需要使用 thrift 的 idl compiler 编译生成相应的 java 代码,后续版本中会在这方面做一些增强。 + +## 依赖 + +```xml + + org.apache.thrift + libthrift + 0.8.0 + +``` + +## 配置 + +所有服务共用一个端口 [^2]: + +```xml + +``` + +## 使用 + +可以参考 [dubbo 项目中的示例代码](https://github.com/apache/dubbo/tree/master/dubbo-rpc/dubbo-rpc-thrift/src/test/java/org/apache/dubbo/rpc/protocol/thrift) + +## 常见问题 + +* Thrift 不支持 null 值,即:不能在协议中传递 null 值 + +[^1]: [Thrift](http://thrift.apache.org) 是 Facebook 捐给 Apache 的一个 RPC 框架 +[^2]: 与原生Thrift不兼容 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/v3.2_rest_protocol_design.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/others/v3.2_rest_protocol_design.md similarity index 98% rename from content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/v3.2_rest_protocol_design.md rename to content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/others/v3.2_rest_protocol_design.md index 4dd501e625e8..025ecc665590 100644 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/v3.2_rest_protocol_design.md +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/others/v3.2_rest_protocol_design.md @@ -10,24 +10,10 @@ type: docs weight: 6 --- - - - -# Dubbo RestProtocol 设计文档 - -## 原版本dubbo rest - -consumer - -restClient支持 依赖resteasy 不支持spring mvc  - -provider(较重) - -依赖web container   (tomcat,jetty,)servlet 模式,jaxrs netty server - -### 改版dubbo rest  - -方向: +{{% alert title="注意" color="warning" %}} +从 Dubbo 3.3 版本开始,Rest 协议已移至 Extensions 库,由 Triple 协议来对 Rest 提供更全面的支持,具体参见 [Triple Rest用户手册](../../tripe-rest-manual/), +如需继续使用原 Rest 协议,可引入对应 [dubbo-spi-extensions](https://github.com/apache/dubbo-spi-extensions/tree/master/dubbo-rpc-extensions/dubbo-rpc-rest) 库依赖 +{{% /alert %}} 更加轻量,具有dubbo风格的rest,微服务体系互通(Springcloud Alibaba) diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/webservice.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/others/webservice.md similarity index 96% rename from content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/webservice.md rename to content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/others/webservice.md index 544a78baaf59..6da21d39eedc 100644 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/webservice.md +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/others/webservice.md @@ -2,6 +2,7 @@ aliases: - /zh/docs3-v2/java-sdk/reference-manual/protocol/webservice/ - /zh-cn/docs3-v2/java-sdk/reference-manual/protocol/webservice/ + - /zh-cn/overview/mannual/java-sdk/reference-manual/protocol/webservice/ description: Webservice协议 linkTitle: Webservice协议 title: Webservice协议 @@ -9,12 +10,6 @@ type: docs weight: 11 --- - - - - - - ## 特性说明 基于 WebService 的远程调用协议,基于 [Apache CXF](http://cxf.apache.org) 的 `frontend-simple` 和 `transports-http` 实现。`2.3.0` 以上版本支持。 @@ -44,7 +39,7 @@ CXF 是 Apache 开源的一个 RPC 框架,由 Xfire 和 Celtix 合并而来。 org.apache.dubbo.extensions dubbo-rpc-webservice - 1.0.0 + 3.3.0 ``` diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/overview.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/overview.md index b7dfbf965614..c9c60b3e953b 100644 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/overview.md +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/overview.md @@ -9,204 +9,40 @@ type: docs weight: 1 --- +Dubbo 作为一款 RPC 框架内置了高效的 RPC 通信协议,帮助解决服务间的编码与通信问题,目前支持的协议包括: + * triple,基于 HTTP/1、HTTP/2 的高性能通信协议,100% 兼容 gRPC,支持 Unary、Streming 等通信模式;支持发布 REST 风格的 HTTP 服务。 + * dubbo,基于 TCP 的高性能私有通信协议,缺点是通用性较差,更适合在 Dubbo SDK 间使用; + * 任意协议扩展,通过扩展 protocol 可以之前任意 RPC 协议,官方生态库提供 JsonRPC、thrift 等支持。 + +## 协议选型 + +**开发者该如何确定使用哪一种协议那?** 以下是我们从使用场景、性能、编程易用性、多语言互通等方面对多个主流协议的对比分析: + +| 协议 | 性能 | 网关友好 | 流式通信 | 多语言支持 | 编程API | 说明 | +| --- | --- | --- | --- | --- | --- | --- | +| triple | 高 | 高 | 支持,客户端流、服务端流、双向流 | 支持(Java、Go、Node.js、JavaScript、Rust) | Java Interface、Protobuf(IDL) | 在多语言兼容、性能、网关、Streaming、gRPC 等方面最均衡的协议实现,官方推荐。
支持 `application/json` 格式 payload http 直接访问。 | +| dubbo | 高 | 低 | 不支持 | 支持(Java、Go) | Java Interface | 性能最高的私有协议,但前端流量接入、多语言支持等成本较高 | + +以下是 triple、dubbo 两个主要协议的具体开发、配置、运行态信息: + | 协议名称 | 配置值 | 服务定义方式 | 默认端口 | 传输层协议 | 序列化协议 | 是否默认 | + | --- | --- | --- | --- | --- | --- | --- | + | **triple** | tri | - Java Interface
- Java Interface+SpringWeb注解
- Java Interface+JaxRS注解
- Protobuf(IDL) | 50051 | HTTP/1、HTTP/2 | Protobuf Binary、Protobuf-json | 否 | + | **dubbo** | dubbo | - Java Interface | 20880 | TCP | Hessian、Fastjson2、JSON、JDK、Avro、Kryo 等 | **是** | + + {{% alert title="注意" color="warning" %}} + * 自 3.3 版本开始,triple 协议支持以 rest 风格发布标准的 http 服务,因此框架中实际已不存在独立的 rest protocol 扩展实现, + * 考虑到对过往版本的兼容性,当前 Dubbo 各个发行版本均默认使用 `dubbo` 通信协议。**对于新用户而言,我们强烈建议在一开始就明确配置使用 `triple` 协议**,老用户也尽快参考文档 [实现协议的平滑迁移](/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/triple/migration)。 + {{% /alert %}} + +## 多协议扩展 +以下是当前 Dubbo 官方生态库提供的拓展协议实现。如果要扩展更多自定义协议,请参考 [SPI 扩展手册](/zh-cn/overview/mannual/java-sdk/reference-manual/spi/) 或 [使用教程 - 协议扩展](/zh-cn/overview/mannual/java-sdk/tasks/extensibility/protocol/)。 + +| 协议 | 配置值 | 说明 | +| --- | --- | --- | +| Hessian | hessian | Hessian 定义的 RPC 通信协议,具体查看 [hessian协议](../others/hessian/) | +| Spring HTTP | http | Spring 定义的基于 HTTP 的私有协议,具体查看 [hessian协议](../others/hessian/) | +| Apache Thrift | thrift | Thrift 协议,具备高性能、支持多语言的特点,具体查看 [Thrift协议](../others/thrift/) | +| JsonRPC | jsonrpc | 具体查看 [JsonRPC](../others/jsonrpc/) | +| RMI | rmi | 具体查看 [RMI协议](../others/rmi/) | +| WebService | webservice | 具体查看 [WebService协议](../others/webservice/) | - - - - -Dubbo3 提供了 Triple(Dubbo3)、Dubbo2 协议,这是 Dubbo 框架的原生协议。除此之外,Dubbo3 也对众多第三方协议进行了集成,并将它们纳入 Dubbo 的编程与服务治理体系, -包括 gRPC、Thrift、JsonRPC、Hessian2、REST 等。以下重点介绍 Triple 与 Dubbo2 协议。 - -## 协议说明 - -Triple 协议是 Dubbo3 推出的主力协议。Triple 意为第三代,通过 Dubbo1.0/ Dubbo2.0 两代协议的演进,以及云原生带来的技术标准化浪潮,Dubbo3 新协议 Triple 应运而生。 - -### RPC 协议 - -协议是 RPC 的核心,它规范了数据在网络中的传输内容和格式。除必须的请求、响应数据外,通常还会包含额外控制数据,如单次请求的序列化方式、超时时间、压缩方式和鉴权信息等。 - -协议的内容包含三部分 -- 数据交换格式: 定义 RPC 的请求和响应对象在网络传输中的字节流内容,也叫作序列化方式 -- 协议结构: 定义包含字段列表和各字段语义以及不同字段的排列方式 -- 协议通过定义规则、格式和语义来约定数据如何在网络间传输。一次成功的 RPC 需要通信的两端都能够按照协议约定进行网络字节流的读写和对象转换。如果两端对使用的协议不能达成一致,就会出现鸡同鸭讲,无法满足远程通信的需求。 - -![协议选择](/imgs/v3/concepts/triple-protocol.png) - -RPC 协议的设计需要考虑以下内容: -- 通用性: 统一的二进制格式,跨语言、跨平台、多传输层协议支持 -- 扩展性: 协议增加字段、升级、支持用户扩展和附加业务元数据 -- 性能:As fast as it can be -- 穿透性:能够被各种终端设备识别和转发:网关、代理服务器等 - 通用性和高性能通常无法同时达到,需要协议设计者进行一定的取舍。 - -### HTTP/1.1 协议 - -比于直接构建于 TCP 传输层的私有 RPC 协议,构建于 HTTP 之上的远程调用解决方案会有更好的通用性,如WebServices 或 REST 架构,使用 HTTP + JSON 可以说是一个事实标准的解决方案。 - -选择构建在 HTTP 之上,有两个最大的优势: - -- HTTP 的语义和可扩展性能很好的满足 RPC 调用需求。 -- 通用性,HTTP 协议几乎被网络上的所有设备所支持,具有很好的协议穿透性。 - -但也存在比较明显的问题: - -- 典型的 Request – Response 模型,一个链路上一次只能有一个等待的 Request 请求。会产生 HOL。 -- Human Readable Headers,使用更通用、更易于人类阅读的头部传输格式,但性能相当差 -- 无直接 Server Push 支持,需要使用 Polling Long-Polling 等变通模式 - -### gRPC 协议 -上面提到了在 HTTP 及 TCP 协议之上构建 RPC 协议各自的优缺点,相比于 Dubbo 构建于 TCP 传输层之上,Google 选择将 gRPC 直接定义在 HTTP/2 协议之上。 -gRPC 的优势由HTTP2 和 Protobuf 继承而来。 - -- 基于 HTTP2 的协议足够简单,用户学习成本低,天然有 server push/ 多路复用 / 流量控制能力 -- 基于 Protobuf 的多语言跨平台二进制兼容能力,提供强大的统一跨语言能力 -- 基于协议本身的生态比较丰富,k8s/etcd 等组件的天然支持协议,云原生的事实协议标准 - -但是也存在部分问题 - -- 对服务治理的支持比较基础,更偏向于基础的 RPC 功能,协议层缺少必要的统一定义,对于用户而言直接用起来并不容易。 -- 强绑定 protobuf 的序列化方式,需要较高的学习成本和改造成本,对于现有的偏单语言的用户而言,迁移成本不可忽视 - -### Triple 协议 -最终我们选择了兼容 gRPC ,以 HTTP2 作为传输层构建新的协议,也就是 Triple。 - -容器化应用程序和微服务的兴起促进了针对负载内容优化技术的发展。 客户端中使用的传统通信协议( RESTFUL或其他基于 HTTP 的自定义协议)难以满足应用在性能、可维护性、扩展性、安全性等方便的需求。一个跨语言、模块化的协议会逐渐成为新的应用开发协议标准。自从 2017 年 gRPC 协议成为 CNCF 的项目后,包括 k8s、etcd 等越来越多的基础设施和业务都开始使用 gRPC 的生态,作为云原生的微服务化框架, Dubbo 的新协议也完美兼容了 gRPC。并且,对于 gRPC 协议中一些不完善的部分, Triple 也将进行增强和补充。 - -那么,Triple 协议是否解决了上面我们提到的一系列问题呢? - -- 性能上: Triple 协议采取了 metadata 和 payload 分离的策略,这样就可以避免中间设备,如网关进行 payload 的解析和反序列化,从而降低响应时间。 -- 路由支持上,由于 metadata 支持用户添加自定义 header ,用户可以根据 header 更方便的划分集群或者进行路由,这样发布的时候切流灰度或容灾都有了更高的灵活性。 -- 安全性上,支持双向TLS认证(mTLS)等加密传输能力。 -- 易用性上,Triple 除了支持原生 gRPC 所推荐的 Protobuf 序列化外,使用通用的方式支持了 Hessian / JSON 等其他序列化,能让用户更方便的升级到 Triple 协议。对原有的 Dubbo 服务而言,修改或增加 Triple 协议 只需要在声明服务的代码块添加一行协议配置即可,改造成本几乎为 0。 - -## 最终选择协议 - -![Triple 协议通信方式](/imgs/v3/concepts/triple.png) - -现状 - -- 1、完整兼容grpc、客户端/服务端可以与原生grpc客户端打通 - -- 2、目前已经经过大规模生产实践验证,达到生产级别 - -特点与优势 - -- 1、具备跨语言互通的能力,传统的多语言多 SDK 模式和 Mesh 化跨语言模式都需要一种更通用易扩展的数据传输格式。 - -- 2、提供更完善的请求模型,除了支持传统的 Request/Response 模型(Unary 单向通信),还支持 Stream(流式通信) 和 Bidirectional(双向通信)。 - -- 3、易扩展、穿透性高,包括但不限于 Tracing / Monitoring 等支持,也应该能被各层设备识别,网关设施等可以识别数据报文,对 Service Mesh 部署友好,降低用户理解难度。 - -- 4、多种序列化方式支持、平滑升级 - -- 5、支持 Java 用户无感知升级,不需要定义繁琐的 IDL 文件,仅需要简单的修改协议名便可以轻松升级到 Triple 协议 - -### Triple 协议内容介绍 - -基于 grpc 协议进行进一步扩展 - -- Service-Version → "tri-service-version" {Dubbo service version} -- Service-Group → "tri-service-group" {Dubbo service group} -- Tracing-ID → "tri-trace-traceid" {tracing id} -- Tracing-RPC-ID → "tri-trace-rpcid" {_span id _} -- Cluster-Info → "tri-unit-info" {cluster infomation} - -其中 Service-Version 跟 Service-Group 分别标识了 Dubbo 服务的 version 跟 group 信息,因为grpc的 path 申明了 service name 跟 method name,相比于 Dubbo 协议,缺少了version 跟 group 信息;Tracing-ID、Tracing-RPC-ID 用于全链路追踪能力,分别表示 tracing id 跟 span id 信息;Cluster-Info 表示集群信息,可以使用其构建一些如集群划分等路由相关的灵活的服务治理能力。 - -### Triple Streaming - -Triple协议相比传统的unary方式,多了目前提供的Streaming RPC的能力 - -- Streaming 用于什么场景呢? - -在一些大文件传输、直播等应用场景中, consumer或provider需要跟对端进行大量数据的传输,由于这些情况下的数据量是非常大的,因此是没有办法可以在一个RPC的数据包中进行传输,因此对于这些数据包我们需要对数据包进行分片之后,通过多次RPC调用进行传输,如果我们对这些已经拆分了的RPC数据包进行并行传输,那么到对端后相关的数据包是无序的,需要对接收到的数据进行排序拼接,相关的逻辑会非常复杂。但如果我们对拆分了的RPC数据包进行串行传输,那么对应的网络传输RTT与数据处理的时延会是非常大的。 - -为了解决以上的问题,并且为了大量数据的传输以流水线方式在consumer与provider之间传输,因此Streaming RPC的模型应运而生。 - -通过Triple协议的Streaming RPC方式,会在consumer跟provider之间建立多条用户态的长连接,Stream。同一个TCP连接之上能同时存在多个Stream,其中每条Stream都有StreamId进行标识,对于一条Stream上的数据包会以顺序方式读写。 - - -{{% alert title="总结" color="info" %}} -在API领域,最重要的趋势是标准化技术的崛起。Triple 协议是 Dubbo3 推出的主力协议。它采用分层设计,其数据交换格式基于Protobuf (Protocol Buffers) 协议开发,具备优秀的序列化/反序列化效率,当然还支持多种序列化方式,也支持众多开发语言。在传输层协议,Triple 选择了 HTTP/2,相较于 HTTP/1.1,其传输效率有了很大提升。此外HTTP/2作为一个成熟的开放标准,具备丰富的安全、流控等能力,同时拥有良好的互操作性。Triple 不仅可以用于Server端服务调用,也可以支持浏览器、移动App和IoT设备与后端服务的交互,同时 Triple协议无缝支持 Dubbo3 的全部服务治理能力。 - -在Cloud Native的潮流下,跨平台、跨厂商、跨环境的系统间互操作性的需求必然会催生基于开放标准的RPC技术,而gRPC顺应了历史趋势,得到了越来越广泛地应用。在微服务领域,Triple协议的提出与落地,是 Dubbo3 迈向云原生微服务的一大步。 -{{% /alert %}} - -## Dubbo2 - -### Protocol SPEC - -![/dev-guide/images/dubbo_protocol_header.jpg](/imgs/dev/dubbo_protocol_header.png) - - -- Magic - Magic High & Magic Low (16 bits) - - Identifies dubbo protocol with value: 0xdabb - -- Req/Res (1 bit) - - Identifies this is a request or response. Request - 1; Response - 0. - -- 2 Way (1 bit) - - Only useful when Req/Res is 1 (Request), expect for a return value from server or not. Set to 1 if need a return value from server. - -- Event (1 bit) - - Identifies an event message or not, for example, heartbeat event. Set to 1 if this is an event. - -- Serialization ID (5 bit) - - Identifies serialization type: the value for fastjson is 6. - -- Status (8 bits) - - Only useful when Req/Res is 0 (Response), identifies the status of response - - - 20 - OK - - 30 - CLIENT_TIMEOUT - - 31 - SERVER_TIMEOUT - - 40 - BAD_REQUEST - - 50 - BAD_RESPONSE - - 60 - SERVICE_NOT_FOUND - - 70 - SERVICE_ERROR - - 80 - SERVER_ERROR - - 90 - CLIENT_ERROR - - 100 - SERVER_THREADPOOL_EXHAUSTED_ERROR - -- Request ID (64 bits) - - Identifies an unique request. Numeric (long). - -- Data Length (32) - - Length of the content (the variable part) after serialization, counted by bytes. Numeric (integer). - -- Variable Part - - Each part is a byte[] after serialization with specific serialization type, identifies by Serialization ID. - -Every part is a byte[] after serialization with specific serialization type, identifies by Serialization ID - -1. If the content is a Request (Req/Res = 1), each part consists of the content, in turn is: - - Dubbo version - - Service name - - Service version - - Method name - - Method parameter types - - Method arguments - - Attachments - -1. If the content is a Response (Req/Res = 0), each part consists of the content, in turn is: - - Return value type, identifies what kind of value returns from server side: RESPONSE_NULL_VALUE - 2, RESPONSE_VALUE - 1, RESPONSE_WITH_EXCEPTION - 0. - - Return value, the real value returns from server. - - -{{% alert title="" color="primary" %}} -对于(Variable Part)变长部分,当前版本的dubbo框架使用json序列化时,在每部分内容间额外增加了换行符作为分隔,请选手在Variable Part的每个part后额外增加换行符, 如: - -``` -Dubbo version bytes (换行符) -Service name bytes (换行符) -``` -{{% /alert %}} diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/redis.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/redis.md deleted file mode 100644 index a36225e9cff4..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/redis.md +++ /dev/null @@ -1,71 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/reference-manual/protocol/redis/ - - /zh-cn/docs3-v2/java-sdk/reference-manual/protocol/redis/ -description: Redis协议 -linkTitle: Redis协议 -title: Redis协议 -type: docs -weight: 9 ---- - - - - - - - -## 特性说明 -[Redis](http://redis.io) 是一个高效的 KV 存储服务器。基于 Redis 实现的 RPC 协议。 - -> `2.3.0` 以上版本支持。 - - -## 使用场景 - -缓存,限流,分布式锁等 - -## 使用方式 - -### 引入依赖 - -从 Dubbo 3 开始,Redis 协议已经不再内嵌在 Dubbo 中,需要单独引入独立的[模块](/zh-cn/download/spi-extensions/#dubbo-rpc)。 -```xml - - org.apache.dubbo.extensions - dubbo-rpc-redis - 1.0.0 - -``` - - -### 注册 redis 服务的地址 -```java -RegistryFactory registryFactory = ExtensionLoader.getExtensionLoader(RegistryFactory.class).getAdaptiveExtension(); -Registry registry = registryFactory.getRegistry(URL.valueOf("zookeeper://10.20.153.10:2181")); -registry.register(URL.valueOf("redis://10.20.153.11/com.foo.BarService?category=providers&dynamic=false&application=foo&group=member&loadbalance=consistenthash")); -``` - -### 在客户端引用 -不需要感知 Redis 的地址 - -在客户端使用: -```xml - -``` -或者点对点直连: -```xml - -``` -也可以使用自定义接口: -```xml - -``` - -其中 "p:xxx" 为 spring 的标准 p 标签 -```xml - -``` -方法名建议和 redis 的标准方法名相同,即:get(key), set(key, value), delete(key)。 - -如果方法名和 redis 的标准方法名不相同,则需要配置映射关系。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/rest.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/rest.md deleted file mode 100644 index 271a74071b24..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/rest.md +++ /dev/null @@ -1,760 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/reference-manual/protocol/rest/ - - /zh-cn/docs3-v2/java-sdk/reference-manual/protocol/rest/ -description: Rest协议 -linkTitle: Rest协议 -title: Rest协议 -type: docs -weight: 4 ---- - - - - - - -基于标准的 Java REST API——JAX-RS 2.0(Java API for RESTful Web Services 的简写)实现的 REST 调用支持 - -## 特性说明 -此协议提供通过 web 访问服务的简单方式,将服务与其他基于 web 的应用程序集成。 -支持 JSON、XML 和 Text 格式的请求和响应,发布和使用服务的便捷方式,也提供了服务版本控制、服务过滤、服务元数据和服务参数, 实现 Dubbo 框架的灵活性和可伸缩性。 - -## 使用场景 -将 Dubbo 服务公开为 RESTful API,与微服务和现有 RESTful 系统集成,实现与非 Java 客户端的互操作性,并促进混合通信。 - -## 使用方式 - -### 快速入门 - -在 dubbo 中开发一个 REST 风格的服务会比较简单,下面以一个注册用户的简单服务为例说明。 - -这个服务要实现的功能是提供如下 URL(注:这个URL不是完全符合 REST 的风格,但是更简单实用) -``` -http://localhost:8080/users/register -``` -而任何客户端都可以将包含用户信息的 JSON 字符串 POST 到以上 URL 来完成用户注册。 - -首先,开发服务的接口 - -```java -public class UserService { - void registerUser(User user); -} -``` - -然后,开发服务的实现 - -```java -@Path("users") -public class UserServiceImpl implements UserService { - - @POST - @Path("register") - @Consumes({MediaType.APPLICATION_JSON}) - public void registerUser(User user) { - // save the user... - } -} -``` -上面的实现非常简单,但是由于该 REST 服务是要发布到指定 URL 上,供任意语言的客户端甚至浏览器来访问,所以这里额外添加了几个 JAX-RS 的标准 annotation 来做相关的配置。 - -@Path("users"):指定访问 UserService 的 URL 相对路径是 /users,即 http://localhost:8080/users - -@Path("register"):指定访问 registerUser() 方法的 URL 相对路径是 /register,再结合上一个 @Path为UserService 指定的路径,则调用 UserService.register() 的完整路径为 http://localhost:8080/users/register - -@POST:指定访问 registerUser()用HTTP POST方法 - -@Consumes({MediaType.APPLICATION_JSON}):指定 registerUser() 接收 JSON 格式的数据。REST 框架会自动将 JSON 数据反序列化为 User 对象 - -最后,在 spring 配置文件中添加此服务,即完成所有服务开发工作 - - ```xml - - - - - - - - -``` - -### REST 服务提供端 - -下面我们扩充“快速入门”中的UserService,进一步展示在dubbo中REST服务提供端的开发要点。 - -### HTTP POST/GET 的实现 - -REST 服务中虽然建议使用 HTTP 协议中四种标准方法 POST、DELETE、PUT、GET 来分别实现常见的“增删改查”,但实际中,我们一般情况直接用POST来实现“增改”,GET 来实现“删查”即可(DELETE 和 PUT 甚至会被一些防火墙阻挡)。 - -前面已经简单演示了 POST 的实现,在此,我们为 UserService 添加一个获取注册用户资料的功能,来演示 GET 的实现。 - -这个功能就是要实现客户端通过访问如下不同 URL 来获取不同 ID 的用户资料 - -``` -http://localhost:8080/users/1001 -http://localhost:8080/users/1002 -http://localhost:8080/users/1003 -``` - -当然,也可以通过其他形式的URL来访问不同 ID 的用户资料,例如 - -``` -http://localhost:8080/users/load?id=1001 -``` - -JAX-RS 本身可以支持所有这些形式。但是上面那种在 URL 路径中包含查询参数的形式(http://localhost:8080/users/1001) 更符合 REST 的一般习惯,所以更推荐大家来使用。下面我们就为 UserService 添加一个 getUser() 方法来实现这种形式的 URL 访问 - -```java -@GET -@Path("{id : \\d+}") -@Produces({MediaType.APPLICATION_JSON}) -public User getUser(@PathParam("id") Long id) { - // ... -} -``` - -@GET:指定用 HTTP GET 方法访问 - -@Path("{id : \\d+}"):根据上面的功能需求,访问 getUser() 的 URL 应当是 “http://localhost:8080/users/ + 任意数字",并且这个数字要被做为参数传入 getUser() 方法。 这里的 annotation 配置中,@Path中间的 {id: xxx} 指定 URL 相对路径中包含了名为id参数,而它的值也将被自动传递给下面用 @PathParam("id") 修饰的方法参数 id。{id:后面紧跟的\\d+ 是一个正则表达式,指定了 id 参数必须是数字。 - -@Produces({MediaType.APPLICATION_JSON}):指定getUser()输出JSON格式的数据。框架会自动将User对象序列化为JSON数据。 - -### Annotation - -在 Dubbo 中开发 REST 服务主要都是通过 JAX-RS的annotation 来完成配置的,在上面的示例中,我们都是将 annotation 放在服务的实现类中。但其实,我们完全也可以将 annotation 放到服务的接口上,这两种方式是完全等价的,例如: - -```java -@Path("users") -public interface UserService { - - @GET - @Path("{id : \\d+}") - @Produces({MediaType.APPLICATION_JSON}) - User getUser(@PathParam("id") Long id); -} -``` - -在一般应用中,我们建议将 annotation 放到服务实现类,这样 annotation 和 java 实现代码位置更接近,更便于开发和维护。另外更重要的是,我们一般倾向于避免对接口的污染,保持接口的纯净性和广泛适用性。 - -但是,如后文所述,如果我们要用 dubbo 直接开发的消费端来访问此服务,则 annotation 必须放到接口上。 - -如果接口和实现类都同时添加了 annotation,则实现类的 annotation 配置会生效,接口上的 annotation 被直接忽略。 - -### 多数据格式支持 - -在 dubbo 中开发的 REST 服务可以同时支持传输多种格式的数据,以给客户端提供最大的灵活性。其中我们目前对最常用的 JSON 和 XML 格式特别添加了额外的功能。 - -比如,我们要让上例中的getUser()方法支持分别返回 JSON 和 XML 格式的数据,只需要在 annotation 中同时包含两种格式即可 - -```java -@Produces({MediaType.APPLICATION_JSON, MediaType.TEXT_XML}) -User getUser(@PathParam("id") Long id); -``` - -或者也可以直接用字符串(还支持通配符)表示 MediaType - -```java -@Produces({"application/json", "text/xml"}) -User getUser(@PathParam("id") Long id); -``` - -如果所有方法都支持同样类型的输入输出数据格式,则我们无需在每个方法上做配置,只需要在服务类上添加 annotation 即可 - -```java -@Path("users") -@Consumes({MediaType.APPLICATION_JSON, MediaType.TEXT_XML}) -@Produces({MediaType.APPLICATION_JSON, MediaType.TEXT_XML}) -public class UserServiceImpl implements UserService { - // ... -} - -``` - -在一个 REST 服务同时对多种数据格式支持的情况下,根据 JAX-RS 标准,一般是通过HTTP中的MIME header(content-type和accept)来指定当前想用的是哪种格式的数据。 - -但是在 dubbo 中,我们还自动支持目前业界普遍使用的方式,即用一个 URL 后缀(.json和.xml)来指定想用的数据格式。例如,在添加上述 annotation后,直接访问 http://localhost:8888/users/1001.json 则表示用 json 格式,直接访问 http://localhost:8888/users/1002.xml 则表示用 xml 格式,比用 HTTP Header 更简单直观。Twitter、微博等的 REST API 都是采用这种方式。 -如果你既不加 HTTP header,也不加后缀,则 dubbo 的 REST 会优先启用在以上 annotation 定义中排位最靠前的那种数据格式。 - -> 注意:这里要支持 XML 格式数据,在 annotation 中既可以用 MediaType.TEXT_XML,也可以用 MediaType.APPLICATION_XML,但是 TEXT_XML 是更常用的,并且如果要利用上述的 URL 后缀方式来指定数据格式,只能配置为 TEXT_XML 才能生效。 - -### 中文字符支持 - -为了在 dubbo REST 中正常输出中文字符,和通常的 Java web 应用一样,我们需要将 HTTP 响应的 contentType 设置为 UTF-8编码。 - -基于 JAX-RS 的标准用法,我们只需要做如下 annotation 配置即可: - -```java -@Produces({"application/json; charset=UTF-8", "text/xml; charset=UTF-8"}) -User getUser(@PathParam("id") Long id); -``` - -为了方便用户,我们在 dubbo REST 中直接添加了一个支持类,来定义以上的常量,可以直接使用,减少出错的可能性。 - -```java -@Produces({ContentType.APPLICATION_JSON_UTF_8, ContentType.TEXT_XML_UTF_8}) -User getUser(@PathParam("id") Long id); -``` - -### XML 数据格式 - -由于 JAX-RS 的实现一般都用标准的 JAXB(Java API for XML Binding)来序列化和反序列化 XML 格式数据,所以我们需要为每一个要用 XML 传输的对象添加一个类级别的 JAXB annotation,否则序列化将报错。例如为 getUser() 中返回的 User 添加如下 - -```java -@XmlRootElement -public class User implements Serializable { - // ... -} -``` - -此外,如果service方法中的返回值是Java的 primitive类型(如int,long,float,double等),最好为它们添加一层wrapper对象,因为JAXB不能直接序列化primitive类型。 - -例如,我们想让前述的registerUser()方法返回服务器端为用户生成的ID号: - -```java -long registerUser(User user); -``` - -由于 primitive 类型不被 JAXB 序列化支持,所以添加一个 wrapper 对象: - -```java -@XmlRootElement -public class RegistrationResult implements Serializable { - - private Long id; - - public RegistrationResult() { - } - - public RegistrationResult(Long id) { - this.id = id; - } - - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } -} -``` - -并修改 service 方法: - -```java -RegistrationResult registerUser(User user); -``` - -这样不但能够解决 XML 序列化的问题,而且使得返回的数据都符合 XML 和 JSON 的规范。例如,在 JSON中,返回的将是如下形式 - -```javascript -{"id": 1001} -``` - -如果不加 wrapper,JSON 返回值将直接是 - -``` -1001 -``` - -而在 XML 中,加 wrapper 后返回值将是: - -```xml - - 1002 - -``` - -这种 wrapper 对象其实利用所谓 Data Transfer Object(DTO)模式,采用 DTO 还能对传输数据做更多有用的定制。 - -### 定制序列化 - -如上所述,REST 的底层实现会在 service 的对象和 JSON/XML 数据格式之间自动做序列化/反序列化。但有些场景下,如果觉得这种自动转换不满足要求,可以对其做定制。 - -Dubbo 中的 REST 实现是用 JAXB 做 XML 序列化,用 Jackson 做 JSON 序列化,所以在对象上添加 JAXB 或 Jackson 的 annotation 即可以定制映射。 - -例如,定制对象属性映射到 XML 元素的名字: - -```java -@XmlRootElement -@XmlAccessorType(XmlAccessType.FIELD) -public class User implements Serializable { - - @XmlElement(name="username") - private String name; -} -``` - -定制对象属性映射到 JSON 字段的名字: - -```java -public class User implements Serializable { - - @JsonProperty("username") - private String name; -} -``` - -更多资料请参考 JAXB 和 Jackson 的官方文档,或自行 google。 - -### REST Server 的实现 - -目前在 dubbo 中,我们支持5种嵌入式 rest server 的实现,并同时支持采用外部应用服务器来做 rest server 的实现。rest server 可以通过如下配置实现: - -```xml - -``` - -以上配置选用了嵌入式的 jetty 来做 rest server,同时,如果不配置 server 属性,rest 协议默认也是选用 jetty。jetty 是非常成熟的 java servlet 容器,并和 dubbo 已经有较好的集成(目前5种嵌入式 server 中只有 jetty 和后面所述的 tomcat、tjws,与 dubbo 监控系统等完成了无缝的集成),所以,如果你的 dubbo 系统是单独启动的进程,你可以直接默认采用 jetty 即可。 - - -```xml - -``` - -以上配置选用了嵌入式的 tomcat 来做 rest server。在嵌入式 tomcat 上,REST 的性能比 jetty 上要好得多(参见后面的基准测试),建议在需要高性能的场景下采用 tomcat。 - -```xml - -``` - -以上配置选用嵌入式的 netty 来做 rest server。(TODO more contents to add) - -```xml - (tjws is now deprecated) - -``` - -以上配置选用嵌入式的 tjws 或 Sun HTTP server 来做 rest server。这两个 server 实现非常轻量级,非常方便在集成测试中快速启动使用,当然也可以在负荷不高的生产环境中使用。 注:tjws目前已经被deprecated掉了,因为它不能很好的和servlet 3.1 API工作。 - -如果你的 dubbo 系统不是单独启动的进程,而是部署到了 Java 应用服务器中,则建议你采用以下配置 - -```xml - -``` - -通过将 server 设置为 servlet,dubbo 将采用外部应用服务器的 servlet 容器来做 rest server。同时,还要在 dubbo 系统的 web.xml 中添加如下配置 - -```xml - - - contextConfigLocation - /WEB-INF/classes/META-INF/spring/dubbo-demo-provider.xml - - - - org.apache.dubbo.remoting.http.servlet.BootstrapListener - - - - org.springframework.web.context.ContextLoaderListener - - - - dispatcher - org.apache.dubbo.remoting.http.servlet.DispatcherServlet - 1 - - - - dispatcher - /* - - -``` - -即必须将 dubbo 的 BootstrapListener 和 DispatherServlet 添加到 web.xml,以完成 dubbo 的 REST 功能与外部 servlet 容器的集成。 - -> 注意:如果你是用 spring 的 ContextLoaderListener 来加载 spring,则必须保证 BootstrapListener 配置在 ContextLoaderListener 之前,否则 dubbo 初始化会出错。 - -其实,这种场景下你依然可以坚持用嵌入式 server,但外部应用服务器的 servlet 容器往往比嵌入式 server 更加强大(特别是如果你是部署到更健壮更可伸缩的 WebLogic,WebSphere 等),另外有时也便于在应用服务器做统一管理、监控等等。 - -### 获取 Context 信息 - -在远程调用中,值得获取的上下文信息可能有很多种,这里特别以获取客户端 IP 为例。 - -在 dubbo 的 REST 中,我们有两种方式获取客户端 IP。 - -第一种方式,用 JAX-RS 标准的 @Context annotation - -```java -public User getUser(@PathParam("id") Long id, @Context HttpServletRequest request) { - System.out.println("Client address is " + request.getRemoteAddr()); -} -``` - -用 Context 修饰 getUser() 的一个方法参数后,就可以将当前的 HttpServletRequest 注入进来,然后直接调用 servlet api 获取 IP。 - -> 注意:这种方式只能在将server设置为 tjws、tomcat、jetty 或者 servlet 的时候才能工作,因为只有这几种 server 的实现才提供了 servlet 容器。另外,标准的JAX-RS还支持用@Context修饰service类的一个实例字段来获取HttpServletRequest,但在dubbo中我们没有对此作出支持。 - -第二种方式,用 dubbo 中常用的 RpcContext - -```java -public User getUser(@PathParam("id") Long id) { - System.out.println("Client address is " + RpcContext.getContext().getRemoteAddressString()); -} -``` - -> 注意:这种方式只能在设置 server="jetty" 或者 server="tomcat" 或者 server="servlet" 或者 server="tjws" 的时候才能工作。另外,目前 dubbo 的 RpcContext 是一种比较有侵入性的用法,未来我们很可能会做出重构。 - -如果你想保持你的项目对 JAX-RS 的兼容性,未来脱离 dubbo 也可以运行,请选择第一种方式。如果你想要更优雅的服务接口定义,请选用第二种方式。 - -此外,在最新的 dubbo rest 中,还支持通过 RpcContext 来获取 HttpServletRequest和 HttpServletResponse,以提供更大的灵活性来方便用户实现某些复杂功能,比如在 dubbo 标准的 filter 中访问 HTTP Header。用法示例如下 - -```java -if (RpcContext.getContext().getRequest() != null && RpcContext.getContext().getRequest() instanceof HttpServletRequest) { - System.out.println("Client address is " + ((HttpServletRequest) RpcContext.getContext().getRequest()).getRemoteAddr()); -} - -if (RpcContext.getContext().getResponse() != null && RpcContext.getContext().getResponse() instanceof HttpServletResponse) { - System.out.println("Response object from RpcContext: " + RpcContext.getContext().getResponse()); -} -``` - -> 注意:为了保持协议的中立性,RpcContext.getRequest()和RpcContext.getResponse()返回的仅仅是一个Object类,而且可能为null。所以,你必须自己做null和类型的检查。 - -> 注意:只有在设置server="jetty"或者server="tomcat"或者server="servlet"的时候,你才能通过以上方法正确的得到HttpServletRequest和HttpServletResponse,因为只有这几种server实现了servlet容器。 - -为了简化编程,在此你也可以用泛型的方式来直接获取特定类型的 request/response: - -```java -if (RpcContext.getContext().getRequest(HttpServletRequest.class) != null) { - System.out.println("Client address is " + RpcContext.getContext().getRequest(HttpServletRequest.class).getRemoteAddr()); -} - -if (RpcContext.getContext().getResponse(HttpServletResponse.class) != null) { - System.out.println("Response object from RpcContext: " + RpcContext.getContext().getResponse(HttpServletResponse.class)); -} -``` - -如果 request/response 不符合指定的类型,这里也会返回 null。 - -### 端口号和 Context Path - -dubbo 中的 rest 协议默认将采用80端口,如果想修改端口,直接配置: - -```xml - -``` - -另外,如前所述,我们可以用 @Path 来配置单个 rest 服务的 URL 相对路径。但其实,我们还可以设置一个所有 rest 服务都适用的基础相对路径,即 java web 应用中常说的 context path。 - -只需要添加如下 contextpath 属性即可: - -```xml - -``` - -以前面代码为例: - -```java -@Path("users") -public class UserServiceImpl implements UserService { - - @POST - @Path("register") - @Consumes({MediaType.APPLICATION_JSON}) - public void registerUser(User user) { - // save the user... - } -} -``` - -现在 registerUser() 的完整访问路径 - -``` -http://localhost:8888/services/users/register -``` - -注意:如果你是选用外部应用服务器做 rest server,即配置 - -```xml - -``` - -则必须保证这里设置的 port、contextpath,与外部应用服务器的端口、DispatcherServlet 的上下文路径(即 webapp path 加上 servlet url pattern)保持一致。例如,对于部署为 tomcat ROOT 路径的应用,这里的 contextpath 必须与 web.xml 中 DispacherServlet 的`` 完全一致: - -```xml - - dispatcher - /services/* - -``` - -### 线程数和 IO 线程数 - -可以为 rest 服务配置线程池大小 - -```xml - -``` - -> 注意:目前线程池的设置只有当server="netty"或者server="jetty"或者server="tomcat"的时候才能生效。另外,如果server="servlet",由于这时候启用的是外部应用服务器做rest server,不受dubbo控制,所以这里的线程池设置也无效。 - -如果是选用 netty server,还可以配置 Netty 的 IO worker 线程数 - -```xml - -``` - -### 配置长连接 - -Dubbo 中的 rest 服务默认都是采用 http 长连接来访问,如果想切换为短连接,直接配置 - -```xml - -``` - -> 注意:这个配置目前只对 server="netty"和server="tomcat" 才能生效。 - -### 最大 HTTP 连接数 - -可以配置服务器提供端所能同时接收的最大 HTTP 连接数,防止 REST server 被过多连接撑爆,以作为一种最基本的自我保护机制 - -```xml - -``` - -当然,由于这个配置针对消费端生效的,所以也可以在消费端配置 - -```xml - -``` - -但是,通常我们建议配置在服务提供端提供此类配置。按照 dubbo 官方文档的说法:“Provider 上尽量多配置 Consumer 端的属性,让 Provider 实现者一开始就思考 Provider 服务特点、服务质量的问题。” - -> 注意:如果 dubbo 的 REST 服务是发布给非 dubbo 的客户端使用,则这里 `` 上的配置完全无效,因为这种客户端不受 dubbo 控制。 - - -### Annotation 取代部分 Spring XML 配置 - -以上所有的讨论都是基于 dubbo 在 spring 中的 xml 配置。但是,dubbo/spring 本身也支持用 annotation 来作配置,所以我们也可以按dubbo官方文档中的步骤,把相关 annotation 加到 REST 服务的实现中,取代一些 xml 配置,例如 - -```java -@Service(protocol = "rest") -@Path("users") -public class UserServiceImpl implements UserService { - - @Autowired - private UserRepository userRepository; - - @POST - @Path("register") - @Consumes({MediaType.APPLICATION_JSON}) - public void registerUser(User user) { - // save the user - userRepository.save(user); - } -} -``` - -annotation 的配置更简单更精确,通常也更便于维护(当然现代IDE都可以在xml中支持比如类名重构,所以就这里的特定用例而言,xml 的维护性也很好)。而 xml 对代码的侵入性更小一些,尤其有利于动态修改配置,特别是比如你要针对单个服务配置连接超时时间、每客户端最大连接数、集群策略、权重等等。另外,特别对复杂应用或者模块来说,xml 提供了一个中心点来涵盖的所有组件和配置,更一目了然,一般更便于项目长时期的维护。 - -当然,选择哪种配置方式没有绝对的优劣,和个人的偏好也不无关系。 - -### 添加自定义的 Filter、Interceptor - -Dubbo 的 REST 也支持 JAX-RS 标准的 Filter 和 Interceptor,以方便对 REST 的请求与响应过程做定制化的拦截处理。 - -其中,Filter 主要用于访问和设置 HTTP 请求和响应的参数、URI 等等。例如,设置 HTTP 响应的 cache header: - -```java -public class CacheControlFilter implements ContainerResponseFilter { - - public void filter(ContainerRequestContext req, ContainerResponseContext res) { - if (req.getMethod().equals("GET")) { - res.getHeaders().add("Cache-Control", "someValue"); - } - } -} -``` - -Interceptor 主要用于访问和修改输入与输出字节流,例如,手动添加 GZIP 压缩 - -```java -public class GZIPWriterInterceptor implements WriterInterceptor { - - @Override - public void aroundWriteTo(WriterInterceptorContext context) - throws IOException, WebApplicationException { - OutputStream outputStream = context.getOutputStream(); - context.setOutputStream(new GZIPOutputStream(outputStream)); - context.proceed(); - } -} -``` - -在标准 JAX-RS 应用中,我们一般是为 Filter 和 Interceptor 添加 @Provider annotation,然后 JAX-RS runtime 会自动发现并启用它们。而在 dubbo 中,我们是通过添加XML配置的方式来注册 Filter 和 Interceptor: - -```xml - -``` - -在此,我们可以将 Filter、Interceptor 和 DynamicFeature 这三种类型的对象都添加到 `extension` 属性上,多个之间用逗号分隔。(DynamicFeature 是另一个接口,可以方便我们更动态的启用 Filter 和 Interceptor,感兴趣请自行 google。) - -当然,dubbo 自身也支持 Filter 的概念,但我们这里讨论的 Filter 和 Interceptor 更加接近协议实现的底层,相比 dubbo 的 filter,可以做更底层的定制化。 - -> 注:这里的 XML 属性叫 extension,而不是叫 interceptor 或者 filter,是因为除了 Interceptor 和 Filter,未来我们还会添加更多的扩展类型。 - -如果 REST 的消费端也是 dubbo 系统(参见下文的讨论),则也可以用类似方式为消费端配置 Interceptor 和 Filter。但注意,JAX-RS 中消费端的 Filter 和提供端的 Filter 是两种不同的接口。例如前面例子中服务端是 ContainerResponseFilter 接口,而消费端对应的是 ClientResponseFilter: - -```java -public class LoggingFilter implements ClientResponseFilter { - - public void filter(ClientRequestContext reqCtx, ClientResponseContext resCtx) throws IOException { - System.out.println("status: " + resCtx.getStatus()); - System.out.println("date: " + resCtx.getDate()); - System.out.println("last-modified: " + resCtx.getLastModified()); - System.out.println("location: " + resCtx.getLocation()); - System.out.println("headers:"); - for (Entry> header : resCtx.getHeaders().entrySet()) { - System.out.print("\t" + header.getKey() + " :"); - for (String value : header.getValue()) { - System.out.print(value + ", "); - } - System.out.print("\n"); - } - System.out.println("media-type: " + resCtx.getMediaType().getType()); - } -} -``` - -### 添加自定义的 Exception 处理 - -Dubbo 的 REST 也支持 JAX-RS 标准的 ExceptionMapper,可以用来定制特定 exception 发生后应该返回的 HTTP 响应。 - -```java -public class CustomExceptionMapper implements ExceptionMapper { - - public Response toResponse(NotFoundException e) { - return Response.status(Response.Status.NOT_FOUND).entity("Oops! the requested resource is not found!").type("text/plain").build(); - } -} -``` - -和 Interceptor、Filter 类似,将其添加到 XML 配置文件中即可启用 - -```xml - -``` - -### HTTP 日志输出 - -Dubbo rest 支持输出所有 HTTP 请求/响应中的 header 字段和 body 消息体。 - -在 XML 配置中添加如下自带的 REST filter: - -```xml - -``` - -然后配置在 logging 配置中至少为 org.apache.dubbo.rpc.protocol.rest.support 打开 INFO 级别日志输出,例如,在 log4j.xml 中配置 - -```xml - - - - -``` - -当然,你也可以直接在 ROOT logger 打开 INFO 级别日志输出 - -```xml - - - - -``` - -然后在日志中会有类似如下的内容输出 - -``` -The HTTP headers are: -accept: application/json;charset=UTF-8 -accept-encoding: gzip, deflate -connection: Keep-Alive -content-length: 22 -content-type: application/json -host: 192.168.1.100:8888 -user-agent: Apache-HttpClient/4.2.1 (java 1.5) -``` - -``` -The contents of request body is: -{"id":1,"name":"dang"} -``` - -打开 HTTP 日志输出后,除了正常日志输出的性能开销外,也会在比如 HTTP 请求解析时产生额外的开销,因为需要建立额外的内存缓冲区来为日志的输出做数据准备。 - -### 输入参数的校验 - -dubbo 的 rest 支持采用 Java 标准的 bean validation annotation(JSR 303) 来做输入校验 http://beanvalidation.org/ - -为了和其他 dubbo 远程调用协议保持一致,在 rest 中作校验的 annotation 必须放在服务的接口上,例如 - -```java -public interface UserService { - - User getUser(@Min(value=1L, message="User ID must be greater than 1") Long id); -} - -``` - -当然,在很多其他的 bean validation 的应用场景都是将 annotation 放到实现类而不是接口上。把 annotation 放在接口上至少有一个好处是,dubbo 的客户端可以共享这个接口的信息,dubbo 甚至不需要做远程调用,在本地就可以完成输入校验。 - -然后按照 dubbo 的标准方式在 XML 配置中打开验证: - -```xml - -``` - -在 dubbo 的其他很多远程调用协议中,如果输入验证出错,是直接将 `RpcException` 抛向客户端,而在 rest 中由于客户端经常是非 dubbo,甚至非 java 的系统,所以不便直接抛出 Java 异常。因此,目前我们将校验错误以 XML 的格式返回 - -```xml - - - getUserArgument0 - User ID must be greater than 1 - 0 - - -``` - -稍后也会支持其他数据格式的返回值。至于如何对验证错误消息作国际化处理,直接参考 bean validation 的相关文档即可。 - -如果你认为默认的校验错误返回格式不符合你的要求,可以如上面章节所述,添加自定义的 ExceptionMapper 来自由的定制错误返回格式。需要注意的是,这个 ExceptionMapper 必须用泛型声明来捕获 dubbo 的 RpcException,才能成功覆盖 dubbo rest 默认的异常处理策略。为了简化操作,其实这里最简单的方式是直接继承 dubbo rest 的 RpcExceptionMapper,并覆盖其中处理校验异常的方法即可 - -```java -public class MyValidationExceptionMapper extends RpcExceptionMapper { - - protected Response handleConstraintViolationException(ConstraintViolationException cve) { - ViolationReport report = new ViolationReport(); - for (ConstraintViolation cv : cve.getConstraintViolations()) { - report.addConstraintViolation(new RestConstraintViolation( - cv.getPropertyPath().toString(), - cv.getMessage(), - cv.getInvalidValue() == null ? "null" : cv.getInvalidValue().toString())); - } - // 采用json输出代替xml输出 - return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(report).type(ContentType.APPLICATION_JSON_UTF_8).build(); - } -} -``` - -然后将这个 ExceptionMapper 添加到 XML 配置中即可: - -```xml - -``` diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/rest.md.bak b/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/rest.md.bak new file mode 100644 index 000000000000..e53ad674b3a8 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/rest.md.bak @@ -0,0 +1,815 @@ +--- +aliases: + - /zh/docs3-v2/java-sdk/reference-manual/protocol/rest/ + - /zh-cn/docs3-v2/java-sdk/reference-manual/protocol/rest/ +description: Rest协议 +linkTitle: rest +title: Rest协议 +type: docs +weight: 4 +--- + +# JSON 兼容性检查 + + +## 特性说明 +`Dubbo`目前支持使用`Rest`协议进行服务调用,`Rest`协议默认会使用`JSON`作为序列化方式,但`JSON`并不支持`Java`的一些特殊用法,如`接口`和`抽象类`等。 + +`Dubbo 3.3`版本在服务发布流程中增加了`服务接口JSON兼容性检测`功能, 可以确保服务接口传输对象是否可以被`JSON`序列化, 进一步提升`Rest`服务接口的正确性。 + +## 使用场景 +使用`Rest`作为通信协议,`JSON`作为序列化方式时,对服务接口进行兼容性检查,确保服务接口传输对象可以正确地被`JSON`序列化。 + +## 使用方式 + +当使用`Rest`协议作为通信协议,`JSON`作为序列化方式时,可以在`xml`文件中通过配置`protocol`的`json-check-level`属性来配置`JSON兼容性检查`的级别。 + +目前有`3`种级别,每种级别的具体含义如下: + +* `disabled`:表示`不开启JSON兼容性检查`,此时不会对接口进行兼容性检查。 +* `warn`:表示`开启JSON兼容性检查`,如果出现不兼容的情况,将会以`warn`级别的日志形式将不兼容的接口名称打印输出到终端。 +* `strict`:表示`开启JSON兼容性检查`,如果出现不兼容的情况,将会在启动时抛出`IllegalStateException`异常,终止启动流程,同时会将不兼容的接口名称存放在异常信息中。 + +> 如果没有通过`json-check-level`指定兼容性检查级别,则默认是`warn`告警级别。 + +### 使用示例 + +```xml + + + + + + + + + + + + + + + + + + + + + + +``` + + + + + +基于标准的 Java REST API——JAX-RS 2.0(Java API for RESTful Web Services 的简写)实现的 REST 调用支持 + +## 特性说明 +此协议提供通过 web 访问服务的简单方式,将服务与其他基于 web 的应用程序集成。 +支持 JSON、XML 和 Text 格式的请求和响应,发布和使用服务的便捷方式,也提供了服务版本控制、服务过滤、服务元数据和服务参数, 实现 Dubbo 框架的灵活性和可伸缩性。 + +## 使用场景 +将 Dubbo 服务公开为 RESTful API,与微服务和现有 RESTful 系统集成,实现与非 Java 客户端的互操作性,并促进混合通信。 + +## 使用方式 + +### 快速入门 + +在 dubbo 中开发一个 REST 风格的服务会比较简单,下面以一个注册用户的简单服务为例说明。 + +这个服务要实现的功能是提供如下 URL(注:这个URL不是完全符合 REST 的风格,但是更简单实用) +``` +http://localhost:8080/users/register +``` +而任何客户端都可以将包含用户信息的 JSON 字符串 POST 到以上 URL 来完成用户注册。 + +首先,开发服务的接口 + +```java +public class UserService { + void registerUser(User user); +} +``` + +然后,开发服务的实现 + +```java +@Path("users") +public class UserServiceImpl implements UserService { + + @POST + @Path("register") + @Consumes({MediaType.APPLICATION_JSON}) + public void registerUser(User user) { + // save the user... + } +} +``` +上面的实现非常简单,但是由于该 REST 服务是要发布到指定 URL 上,供任意语言的客户端甚至浏览器来访问,所以这里额外添加了几个 JAX-RS 的标准 annotation 来做相关的配置。 + +@Path("users"):指定访问 UserService 的 URL 相对路径是 /users,即 http://localhost:8080/users + +@Path("register"):指定访问 registerUser() 方法的 URL 相对路径是 /register,再结合上一个 @Path为UserService 指定的路径,则调用 UserService.register() 的完整路径为 http://localhost:8080/users/register + +@POST:指定访问 registerUser()用HTTP POST方法 + +@Consumes({MediaType.APPLICATION_JSON}):指定 registerUser() 接收 JSON 格式的数据。REST 框架会自动将 JSON 数据反序列化为 User 对象 + +最后,在 spring 配置文件中添加此服务,即完成所有服务开发工作 + + ```xml + + + + + + + + +``` + +### REST 服务提供端 + +下面我们扩充“快速入门”中的UserService,进一步展示在dubbo中REST服务提供端的开发要点。 + +### HTTP POST/GET 的实现 + +REST 服务中虽然建议使用 HTTP 协议中四种标准方法 POST、DELETE、PUT、GET 来分别实现常见的“增删改查”,但实际中,我们一般情况直接用POST来实现“增改”,GET 来实现“删查”即可(DELETE 和 PUT 甚至会被一些防火墙阻挡)。 + +前面已经简单演示了 POST 的实现,在此,我们为 UserService 添加一个获取注册用户资料的功能,来演示 GET 的实现。 + +这个功能就是要实现客户端通过访问如下不同 URL 来获取不同 ID 的用户资料 + +``` +http://localhost:8080/users/1001 +http://localhost:8080/users/1002 +http://localhost:8080/users/1003 +``` + +当然,也可以通过其他形式的URL来访问不同 ID 的用户资料,例如 + +``` +http://localhost:8080/users/load?id=1001 +``` + +JAX-RS 本身可以支持所有这些形式。但是上面那种在 URL 路径中包含查询参数的形式(http://localhost:8080/users/1001) 更符合 REST 的一般习惯,所以更推荐大家来使用。下面我们就为 UserService 添加一个 getUser() 方法来实现这种形式的 URL 访问 + +```java +@GET +@Path("{id : \\d+}") +@Produces({MediaType.APPLICATION_JSON}) +public User getUser(@PathParam("id") Long id) { + // ... +} +``` + +@GET:指定用 HTTP GET 方法访问 + +@Path("{id : \\d+}"):根据上面的功能需求,访问 getUser() 的 URL 应当是 “http://localhost:8080/users/ + 任意数字",并且这个数字要被做为参数传入 getUser() 方法。 这里的 annotation 配置中,@Path中间的 {id: xxx} 指定 URL 相对路径中包含了名为id参数,而它的值也将被自动传递给下面用 @PathParam("id") 修饰的方法参数 id。{id:后面紧跟的\\d+ 是一个正则表达式,指定了 id 参数必须是数字。 + +@Produces({MediaType.APPLICATION_JSON}):指定getUser()输出JSON格式的数据。框架会自动将User对象序列化为JSON数据。 + +### Annotation + +在 Dubbo 中开发 REST 服务主要都是通过 JAX-RS的annotation 来完成配置的,在上面的示例中,我们都是将 annotation 放在服务的实现类中。但其实,我们完全也可以将 annotation 放到服务的接口上,这两种方式是完全等价的,例如: + +```java +@Path("users") +public interface UserService { + + @GET + @Path("{id : \\d+}") + @Produces({MediaType.APPLICATION_JSON}) + User getUser(@PathParam("id") Long id); +} +``` + +在一般应用中,我们建议将 annotation 放到服务实现类,这样 annotation 和 java 实现代码位置更接近,更便于开发和维护。另外更重要的是,我们一般倾向于避免对接口的污染,保持接口的纯净性和广泛适用性。 + +但是,如后文所述,如果我们要用 dubbo 直接开发的消费端来访问此服务,则 annotation 必须放到接口上。 + +如果接口和实现类都同时添加了 annotation,则实现类的 annotation 配置会生效,接口上的 annotation 被直接忽略。 + +### 多数据格式支持 + +在 dubbo 中开发的 REST 服务可以同时支持传输多种格式的数据,以给客户端提供最大的灵活性。其中我们目前对最常用的 JSON 和 XML 格式特别添加了额外的功能。 + +比如,我们要让上例中的getUser()方法支持分别返回 JSON 和 XML 格式的数据,只需要在 annotation 中同时包含两种格式即可 + +```java +@Produces({MediaType.APPLICATION_JSON, MediaType.TEXT_XML}) +User getUser(@PathParam("id") Long id); +``` + +或者也可以直接用字符串(还支持通配符)表示 MediaType + +```java +@Produces({"application/json", "text/xml"}) +User getUser(@PathParam("id") Long id); +``` + +如果所有方法都支持同样类型的输入输出数据格式,则我们无需在每个方法上做配置,只需要在服务类上添加 annotation 即可 + +```java +@Path("users") +@Consumes({MediaType.APPLICATION_JSON, MediaType.TEXT_XML}) +@Produces({MediaType.APPLICATION_JSON, MediaType.TEXT_XML}) +public class UserServiceImpl implements UserService { + // ... +} + +``` + +在一个 REST 服务同时对多种数据格式支持的情况下,根据 JAX-RS 标准,一般是通过HTTP中的MIME header(content-type和accept)来指定当前想用的是哪种格式的数据。 + +但是在 dubbo 中,我们还自动支持目前业界普遍使用的方式,即用一个 URL 后缀(.json和.xml)来指定想用的数据格式。例如,在添加上述 annotation后,直接访问 http://localhost:8888/users/1001.json 则表示用 json 格式,直接访问 http://localhost:8888/users/1002.xml 则表示用 xml 格式,比用 HTTP Header 更简单直观。Twitter、微博等的 REST API 都是采用这种方式。 +如果你既不加 HTTP header,也不加后缀,则 dubbo 的 REST 会优先启用在以上 annotation 定义中排位最靠前的那种数据格式。 + +> 注意:这里要支持 XML 格式数据,在 annotation 中既可以用 MediaType.TEXT_XML,也可以用 MediaType.APPLICATION_XML,但是 TEXT_XML 是更常用的,并且如果要利用上述的 URL 后缀方式来指定数据格式,只能配置为 TEXT_XML 才能生效。 + +### 中文字符支持 + +为了在 dubbo REST 中正常输出中文字符,和通常的 Java web 应用一样,我们需要将 HTTP 响应的 contentType 设置为 UTF-8编码。 + +基于 JAX-RS 的标准用法,我们只需要做如下 annotation 配置即可: + +```java +@Produces({"application/json; charset=UTF-8", "text/xml; charset=UTF-8"}) +User getUser(@PathParam("id") Long id); +``` + +为了方便用户,我们在 dubbo REST 中直接添加了一个支持类,来定义以上的常量,可以直接使用,减少出错的可能性。 + +```java +@Produces({ContentType.APPLICATION_JSON_UTF_8, ContentType.TEXT_XML_UTF_8}) +User getUser(@PathParam("id") Long id); +``` + +### XML 数据格式 + +由于 JAX-RS 的实现一般都用标准的 JAXB(Java API for XML Binding)来序列化和反序列化 XML 格式数据,所以我们需要为每一个要用 XML 传输的对象添加一个类级别的 JAXB annotation,否则序列化将报错。例如为 getUser() 中返回的 User 添加如下 + +```java +@XmlRootElement +public class User implements Serializable { + // ... +} +``` + +此外,如果service方法中的返回值是Java的 primitive类型(如int,long,float,double等),最好为它们添加一层wrapper对象,因为JAXB不能直接序列化primitive类型。 + +例如,我们想让前述的registerUser()方法返回服务器端为用户生成的ID号: + +```java +long registerUser(User user); +``` + +由于 primitive 类型不被 JAXB 序列化支持,所以添加一个 wrapper 对象: + +```java +@XmlRootElement +public class RegistrationResult implements Serializable { + + private Long id; + + public RegistrationResult() { + } + + public RegistrationResult(Long id) { + this.id = id; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } +} +``` + +并修改 service 方法: + +```java +RegistrationResult registerUser(User user); +``` + +这样不但能够解决 XML 序列化的问题,而且使得返回的数据都符合 XML 和 JSON 的规范。例如,在 JSON中,返回的将是如下形式 + +```javascript +{"id": 1001} +``` + +如果不加 wrapper,JSON 返回值将直接是 + +``` +1001 +``` + +而在 XML 中,加 wrapper 后返回值将是: + +```xml + + 1002 + +``` + +这种 wrapper 对象其实利用所谓 Data Transfer Object(DTO)模式,采用 DTO 还能对传输数据做更多有用的定制。 + +### 定制序列化 + +如上所述,REST 的底层实现会在 service 的对象和 JSON/XML 数据格式之间自动做序列化/反序列化。但有些场景下,如果觉得这种自动转换不满足要求,可以对其做定制。 + +Dubbo 中的 REST 实现是用 JAXB 做 XML 序列化,用 Jackson 做 JSON 序列化,所以在对象上添加 JAXB 或 Jackson 的 annotation 即可以定制映射。 + +例如,定制对象属性映射到 XML 元素的名字: + +```java +@XmlRootElement +@XmlAccessorType(XmlAccessType.FIELD) +public class User implements Serializable { + + @XmlElement(name="username") + private String name; +} +``` + +定制对象属性映射到 JSON 字段的名字: + +```java +public class User implements Serializable { + + @JsonProperty("username") + private String name; +} +``` + +更多资料请参考 JAXB 和 Jackson 的官方文档,或自行 google。 + +### REST Server 的实现 + +目前在 dubbo 中,我们支持5种嵌入式 rest server 的实现,并同时支持采用外部应用服务器来做 rest server 的实现。rest server 可以通过如下配置实现: + +```xml + +``` + +以上配置选用了嵌入式的 jetty 来做 rest server,同时,如果不配置 server 属性,rest 协议默认也是选用 jetty。jetty 是非常成熟的 java servlet 容器,并和 dubbo 已经有较好的集成(目前5种嵌入式 server 中只有 jetty 和后面所述的 tomcat、tjws,与 dubbo 监控系统等完成了无缝的集成),所以,如果你的 dubbo 系统是单独启动的进程,你可以直接默认采用 jetty 即可。 + + +```xml + +``` + +以上配置选用了嵌入式的 tomcat 来做 rest server。在嵌入式 tomcat 上,REST 的性能比 jetty 上要好得多(参见后面的基准测试),建议在需要高性能的场景下采用 tomcat。 + +```xml + +``` + +以上配置选用嵌入式的 netty 来做 rest server。(TODO more contents to add) + +```xml + (tjws is now deprecated) + +``` + +以上配置选用嵌入式的 tjws 或 Sun HTTP server 来做 rest server。这两个 server 实现非常轻量级,非常方便在集成测试中快速启动使用,当然也可以在负荷不高的生产环境中使用。 注:tjws目前已经被deprecated掉了,因为它不能很好的和servlet 3.1 API工作。 + +如果你的 dubbo 系统不是单独启动的进程,而是部署到了 Java 应用服务器中,则建议你采用以下配置 + +```xml + +``` + +通过将 server 设置为 servlet,dubbo 将采用外部应用服务器的 servlet 容器来做 rest server。同时,还要在 dubbo 系统的 web.xml 中添加如下配置 + +```xml + + + contextConfigLocation + /WEB-INF/classes/META-INF/spring/dubbo-demo-provider.xml + + + + org.apache.dubbo.remoting.http.servlet.BootstrapListener + + + + org.springframework.web.context.ContextLoaderListener + + + + dispatcher + org.apache.dubbo.remoting.http.servlet.DispatcherServlet + 1 + + + + dispatcher + /* + + +``` + +即必须将 dubbo 的 BootstrapListener 和 DispatherServlet 添加到 web.xml,以完成 dubbo 的 REST 功能与外部 servlet 容器的集成。 + +> 注意:如果你是用 spring 的 ContextLoaderListener 来加载 spring,则必须保证 BootstrapListener 配置在 ContextLoaderListener 之前,否则 dubbo 初始化会出错。 + +其实,这种场景下你依然可以坚持用嵌入式 server,但外部应用服务器的 servlet 容器往往比嵌入式 server 更加强大(特别是如果你是部署到更健壮更可伸缩的 WebLogic,WebSphere 等),另外有时也便于在应用服务器做统一管理、监控等等。 + +### 获取 Context 信息 + +在远程调用中,值得获取的上下文信息可能有很多种,这里特别以获取客户端 IP 为例。 + +在 dubbo 的 REST 中,我们有两种方式获取客户端 IP。 + +第一种方式,用 JAX-RS 标准的 @Context annotation + +```java +public User getUser(@PathParam("id") Long id, @Context HttpServletRequest request) { + System.out.println("Client address is " + request.getRemoteAddr()); +} +``` + +用 Context 修饰 getUser() 的一个方法参数后,就可以将当前的 HttpServletRequest 注入进来,然后直接调用 servlet api 获取 IP。 + +> 注意:这种方式只能在将server设置为 tjws、tomcat、jetty 或者 servlet 的时候才能工作,因为只有这几种 server 的实现才提供了 servlet 容器。另外,标准的JAX-RS还支持用@Context修饰service类的一个实例字段来获取HttpServletRequest,但在dubbo中我们没有对此作出支持。 + +第二种方式,用 dubbo 中常用的 RpcContext + +```java +public User getUser(@PathParam("id") Long id) { + System.out.println("Client address is " + RpcContext.getContext().getRemoteAddressString()); +} +``` + +> 注意:这种方式只能在设置 server="jetty" 或者 server="tomcat" 或者 server="servlet" 或者 server="tjws" 的时候才能工作。另外,目前 dubbo 的 RpcContext 是一种比较有侵入性的用法,未来我们很可能会做出重构。 + +如果你想保持你的项目对 JAX-RS 的兼容性,未来脱离 dubbo 也可以运行,请选择第一种方式。如果你想要更优雅的服务接口定义,请选用第二种方式。 + +此外,在最新的 dubbo rest 中,还支持通过 RpcContext 来获取 HttpServletRequest和 HttpServletResponse,以提供更大的灵活性来方便用户实现某些复杂功能,比如在 dubbo 标准的 filter 中访问 HTTP Header。用法示例如下 + +```java +if (RpcContext.getContext().getRequest() != null && RpcContext.getContext().getRequest() instanceof HttpServletRequest) { + System.out.println("Client address is " + ((HttpServletRequest) RpcContext.getContext().getRequest()).getRemoteAddr()); +} + +if (RpcContext.getContext().getResponse() != null && RpcContext.getContext().getResponse() instanceof HttpServletResponse) { + System.out.println("Response object from RpcContext: " + RpcContext.getContext().getResponse()); +} +``` + +> 注意:为了保持协议的中立性,RpcContext.getRequest()和RpcContext.getResponse()返回的仅仅是一个Object类,而且可能为null。所以,你必须自己做null和类型的检查。 + +> 注意:只有在设置server="jetty"或者server="tomcat"或者server="servlet"的时候,你才能通过以上方法正确的得到HttpServletRequest和HttpServletResponse,因为只有这几种server实现了servlet容器。 + +为了简化编程,在此你也可以用泛型的方式来直接获取特定类型的 request/response: + +```java +if (RpcContext.getContext().getRequest(HttpServletRequest.class) != null) { + System.out.println("Client address is " + RpcContext.getContext().getRequest(HttpServletRequest.class).getRemoteAddr()); +} + +if (RpcContext.getContext().getResponse(HttpServletResponse.class) != null) { + System.out.println("Response object from RpcContext: " + RpcContext.getContext().getResponse(HttpServletResponse.class)); +} +``` + +如果 request/response 不符合指定的类型,这里也会返回 null。 + +### 端口号和 Context Path + +dubbo 中的 rest 协议默认将采用80端口,如果想修改端口,直接配置: + +```xml + +``` + +另外,如前所述,我们可以用 @Path 来配置单个 rest 服务的 URL 相对路径。但其实,我们还可以设置一个所有 rest 服务都适用的基础相对路径,即 java web 应用中常说的 context path。 + +只需要添加如下 contextpath 属性即可: + +```xml + +``` + +以前面代码为例: + +```java +@Path("users") +public class UserServiceImpl implements UserService { + + @POST + @Path("register") + @Consumes({MediaType.APPLICATION_JSON}) + public void registerUser(User user) { + // save the user... + } +} +``` + +现在 registerUser() 的完整访问路径 + +``` +http://localhost:8888/services/users/register +``` + +注意:如果你是选用外部应用服务器做 rest server,即配置 + +```xml + +``` + +则必须保证这里设置的 port、contextpath,与外部应用服务器的端口、DispatcherServlet 的上下文路径(即 webapp path 加上 servlet url pattern)保持一致。例如,对于部署为 tomcat ROOT 路径的应用,这里的 contextpath 必须与 web.xml 中 DispacherServlet 的`` 完全一致: + +```xml + + dispatcher + /services/* + +``` + +### 线程数和 IO 线程数 + +可以为 rest 服务配置线程池大小 + +```xml + +``` + +> 注意:目前线程池的设置只有当server="netty"或者server="jetty"或者server="tomcat"的时候才能生效。另外,如果server="servlet",由于这时候启用的是外部应用服务器做rest server,不受dubbo控制,所以这里的线程池设置也无效。 + +如果是选用 netty server,还可以配置 Netty 的 IO worker 线程数 + +```xml + +``` + +### 配置长连接 + +Dubbo 中的 rest 服务默认都是采用 http 长连接来访问,如果想切换为短连接,直接配置 + +```xml + +``` + +> 注意:这个配置目前只对 server="netty"和server="tomcat" 才能生效。 + +### 最大 HTTP 连接数 + +可以配置服务器提供端所能同时接收的最大 HTTP 连接数,防止 REST server 被过多连接撑爆,以作为一种最基本的自我保护机制 + +```xml + +``` + +当然,由于这个配置针对消费端生效的,所以也可以在消费端配置 + +```xml + +``` + +但是,通常我们建议配置在服务提供端提供此类配置。按照 dubbo 官方文档的说法:“Provider 上尽量多配置 Consumer 端的属性,让 Provider 实现者一开始就思考 Provider 服务特点、服务质量的问题。” + +> 注意:如果 dubbo 的 REST 服务是发布给非 dubbo 的客户端使用,则这里 `` 上的配置完全无效,因为这种客户端不受 dubbo 控制。 + + +### Annotation 取代部分 Spring XML 配置 + +以上所有的讨论都是基于 dubbo 在 spring 中的 xml 配置。但是,dubbo/spring 本身也支持用 annotation 来作配置,所以我们也可以按dubbo官方文档中的步骤,把相关 annotation 加到 REST 服务的实现中,取代一些 xml 配置,例如 + +```java +@Service(protocol = "rest") +@Path("users") +public class UserServiceImpl implements UserService { + + @Autowired + private UserRepository userRepository; + + @POST + @Path("register") + @Consumes({MediaType.APPLICATION_JSON}) + public void registerUser(User user) { + // save the user + userRepository.save(user); + } +} +``` + +annotation 的配置更简单更精确,通常也更便于维护(当然现代IDE都可以在xml中支持比如类名重构,所以就这里的特定用例而言,xml 的维护性也很好)。而 xml 对代码的侵入性更小一些,尤其有利于动态修改配置,特别是比如你要针对单个服务配置连接超时时间、每客户端最大连接数、集群策略、权重等等。另外,特别对复杂应用或者模块来说,xml 提供了一个中心点来涵盖的所有组件和配置,更一目了然,一般更便于项目长时期的维护。 + +当然,选择哪种配置方式没有绝对的优劣,和个人的偏好也不无关系。 + +### 添加自定义的 Filter、Interceptor + +Dubbo 的 REST 也支持 JAX-RS 标准的 Filter 和 Interceptor,以方便对 REST 的请求与响应过程做定制化的拦截处理。 + +其中,Filter 主要用于访问和设置 HTTP 请求和响应的参数、URI 等等。例如,设置 HTTP 响应的 cache header: + +```java +public class CacheControlFilter implements ContainerResponseFilter { + + public void filter(ContainerRequestContext req, ContainerResponseContext res) { + if (req.getMethod().equals("GET")) { + res.getHeaders().add("Cache-Control", "someValue"); + } + } +} +``` + +Interceptor 主要用于访问和修改输入与输出字节流,例如,手动添加 GZIP 压缩 + +```java +public class GZIPWriterInterceptor implements WriterInterceptor { + + @Override + public void aroundWriteTo(WriterInterceptorContext context) + throws IOException, WebApplicationException { + OutputStream outputStream = context.getOutputStream(); + context.setOutputStream(new GZIPOutputStream(outputStream)); + context.proceed(); + } +} +``` + +在标准 JAX-RS 应用中,我们一般是为 Filter 和 Interceptor 添加 @Provider annotation,然后 JAX-RS runtime 会自动发现并启用它们。而在 dubbo 中,我们是通过添加XML配置的方式来注册 Filter 和 Interceptor: + +```xml + +``` + +在此,我们可以将 Filter、Interceptor 和 DynamicFeature 这三种类型的对象都添加到 `extension` 属性上,多个之间用逗号分隔。(DynamicFeature 是另一个接口,可以方便我们更动态的启用 Filter 和 Interceptor,感兴趣请自行 google。) + +当然,dubbo 自身也支持 Filter 的概念,但我们这里讨论的 Filter 和 Interceptor 更加接近协议实现的底层,相比 dubbo 的 filter,可以做更底层的定制化。 + +> 注:这里的 XML 属性叫 extension,而不是叫 interceptor 或者 filter,是因为除了 Interceptor 和 Filter,未来我们还会添加更多的扩展类型。 + +如果 REST 的消费端也是 dubbo 系统(参见下文的讨论),则也可以用类似方式为消费端配置 Interceptor 和 Filter。但注意,JAX-RS 中消费端的 Filter 和提供端的 Filter 是两种不同的接口。例如前面例子中服务端是 ContainerResponseFilter 接口,而消费端对应的是 ClientResponseFilter: + +```java +public class LoggingFilter implements ClientResponseFilter { + + public void filter(ClientRequestContext reqCtx, ClientResponseContext resCtx) throws IOException { + System.out.println("status: " + resCtx.getStatus()); + System.out.println("date: " + resCtx.getDate()); + System.out.println("last-modified: " + resCtx.getLastModified()); + System.out.println("location: " + resCtx.getLocation()); + System.out.println("headers:"); + for (Entry> header : resCtx.getHeaders().entrySet()) { + System.out.print("\t" + header.getKey() + " :"); + for (String value : header.getValue()) { + System.out.print(value + ", "); + } + System.out.print("\n"); + } + System.out.println("media-type: " + resCtx.getMediaType().getType()); + } +} +``` + +### 添加自定义的 Exception 处理 + +Dubbo 的 REST 也支持 JAX-RS 标准的 ExceptionMapper,可以用来定制特定 exception 发生后应该返回的 HTTP 响应。 + +```java +public class CustomExceptionMapper implements ExceptionMapper { + + public Response toResponse(NotFoundException e) { + return Response.status(Response.Status.NOT_FOUND).entity("Oops! the requested resource is not found!").type("text/plain").build(); + } +} +``` + +和 Interceptor、Filter 类似,将其添加到 XML 配置文件中即可启用 + +```xml + +``` + +### HTTP 日志输出 + +Dubbo rest 支持输出所有 HTTP 请求/响应中的 header 字段和 body 消息体。 + +在 XML 配置中添加如下自带的 REST filter: + +```xml + +``` + +然后配置在 logging 配置中至少为 org.apache.dubbo.rpc.protocol.rest.support 打开 INFO 级别日志输出,例如,在 log4j.xml 中配置 + +```xml + + + + +``` + +当然,你也可以直接在 ROOT logger 打开 INFO 级别日志输出 + +```xml + + + + +``` + +然后在日志中会有类似如下的内容输出 + +``` +The HTTP headers are: +accept: application/json;charset=UTF-8 +accept-encoding: gzip, deflate +connection: Keep-Alive +content-length: 22 +content-type: application/json +host: 192.168.1.100:8888 +user-agent: Apache-HttpClient/4.2.1 (java 1.5) +``` + +``` +The contents of request body is: +{"id":1,"name":"dang"} +``` + +打开 HTTP 日志输出后,除了正常日志输出的性能开销外,也会在比如 HTTP 请求解析时产生额外的开销,因为需要建立额外的内存缓冲区来为日志的输出做数据准备。 + +### 输入参数的校验 + +dubbo 的 rest 支持采用 Java 标准的 bean validation annotation(JSR 303) 来做输入校验 http://beanvalidation.org/ + +为了和其他 dubbo 远程调用协议保持一致,在 rest 中作校验的 annotation 必须放在服务的接口上,例如 + +```java +public interface UserService { + + User getUser(@Min(value=1L, message="User ID must be greater than 1") Long id); +} + +``` + +当然,在很多其他的 bean validation 的应用场景都是将 annotation 放到实现类而不是接口上。把 annotation 放在接口上至少有一个好处是,dubbo 的客户端可以共享这个接口的信息,dubbo 甚至不需要做远程调用,在本地就可以完成输入校验。 + +然后按照 dubbo 的标准方式在 XML 配置中打开验证: + +```xml + +``` + +在 dubbo 的其他很多远程调用协议中,如果输入验证出错,是直接将 `RpcException` 抛向客户端,而在 rest 中由于客户端经常是非 dubbo,甚至非 java 的系统,所以不便直接抛出 Java 异常。因此,目前我们将校验错误以 XML 的格式返回 + +```xml + + + getUserArgument0 + User ID must be greater than 1 + 0 + + +``` + +稍后也会支持其他数据格式的返回值。至于如何对验证错误消息作国际化处理,直接参考 bean validation 的相关文档即可。 + +如果你认为默认的校验错误返回格式不符合你的要求,可以如上面章节所述,添加自定义的 ExceptionMapper 来自由的定制错误返回格式。需要注意的是,这个 ExceptionMapper 必须用泛型声明来捕获 dubbo 的 RpcException,才能成功覆盖 dubbo rest 默认的异常处理策略。为了简化操作,其实这里最简单的方式是直接继承 dubbo rest 的 RpcExceptionMapper,并覆盖其中处理校验异常的方法即可 + +```java +public class MyValidationExceptionMapper extends RpcExceptionMapper { + + protected Response handleConstraintViolationException(ConstraintViolationException cve) { + ViolationReport report = new ViolationReport(); + for (ConstraintViolation cv : cve.getConstraintViolations()) { + report.addConstraintViolation(new RestConstraintViolation( + cv.getPropertyPath().toString(), + cv.getMessage(), + cv.getInvalidValue() == null ? "null" : cv.getInvalidValue().toString())); + } + // 采用json输出代替xml输出 + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(report).type(ContentType.APPLICATION_JSON_UTF_8).build(); + } +} +``` + +然后将这个 ExceptionMapper 添加到 XML 配置中即可: + +```xml + +``` diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/thrift.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/thrift.md deleted file mode 100644 index 66cc08932405..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/thrift.md +++ /dev/null @@ -1,61 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/reference-manual/protocol/thrift/ - - /zh-cn/docs3-v2/java-sdk/reference-manual/protocol/thrift/ - - /zh/overview/what/ecosystem/protocol/thrift/ -description: Thrift协议 -linkTitle: Thrift协议 -title: Thrift协议 -type: docs -weight: 7 ---- - - - - - - - -## 特性说明 -当前 dubbo 支持的 thrift 协议是对 thrift 原生协议的扩展,在原生协议的基础上添加了一些额外的头信息,比如 service name,magic number 等。`2.3.0` 以上版本支持。 - -[Thrift](http://thrift.apache.org) 是 Facebook 捐给 Apache 的一个 RPC 框架。 - -使用 dubbo thrift 协议同样需要使用 thrift 的 idl compiler 编译生成相应的 java 代码,后续版本中会在这方面做一些增强。 - -## 使用场景 - -适用于 SOA 标准 RPC 框架。 - -## 使用方式 -### 依赖 - -从 Dubbo 3 开始,Thrift 协议已经不再内嵌在 Dubbo 中,需要单独引入独立的[模块](/zh-cn/download/spi-extensions/#dubbo-rpc)。 -```xml - - org.apache.dubbo.extensions - dubbo-rpc-native-thrift - 1.0.0 - -``` - - -```xml - - org.apache.thrift - libthrift - 0.8.0 - -``` - -### 所有服务共用一个端口 - -与原生 Thrift 不兼容 -```xml - -``` - - [dubbo 项目中的示例代码](https://github.com/apache/dubbo/tree/master/dubbo-rpc/dubbo-rpc-thrift/src/test/java/org/apache/dubbo/rpc/protocol/thrift) - - -> Thrift 不支持 null 值,即:不能在协议中传递 null 值 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/tripe-rest-manual.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/tripe-rest-manual.md new file mode 100644 index 000000000000..db1bca0760a2 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/tripe-rest-manual.md @@ -0,0 +1,969 @@ +--- +aliases: + - /zh/docs3-v2/java-sdk/reference-manual/protocol/triple/rest/manual/ + - /zh-cn/docs3-v2/java-sdk/reference-manual/protocol/triple/rest/manual/ + - /zh-cn/overview/mannual/java-sdk/reference-manual/protocol/rest/ + - /zh-cn/overview/mannual/java-sdk/reference-manual/protocol/http/ +description: "本文是Triple Rest的用户使用手册" +linkTitle: triple-rest用户手册 +title: Triple Rest 用户手册 +type: docs +weight: 7 +--- + +{{% alert title="注意" color="warning" %}} +从 Dubbo 3.3 版本开始,原 Rest 协议已移至 Extensions 库,由 Triple 协议来对 Rest 提供更全面的支持,如需继续使用原 Rest 协议, +可引入对应 [dubbo-spi-extensions](https://github.com/apache/dubbo-spi-extensions/tree/master/dubbo-rpc-extensions/dubbo-rpc-rest) 库依赖 +{{% /alert %}} + +## 前言 + +从 Dubbo 3.3 版本开始,Triple 协议重用已有的 HTTP 协议栈,实现了全面的 REST 风格服务导出能力。无需使用泛化或网关层协议转换,无需配置,用户即可通过 HTTP 协议去中心化直接访问后端的 Triple +协议服务。同时,针对高级 REST 用法,如路径定制、输出格式定制和异常处理,提供了丰富的注解和 +SPI 扩展支持。其主要特性包括: + +- **Triple协议融合** + 重用Triple原有HTTP协议栈, 无需额外配置或新增端口,即可同时支持 HTTP/1、HTTP/2 和 HTTP/3 协议的访问。 +- **去中心化** + 可直接对外暴露 Rest API,不再依赖网关应用进行流量转发,从而提升性能,并降低因网关引发的稳定性风险。安全问题可通过应用内部扩展解决,这一实践已在淘宝内部的 MTOP 中得到验证。 +- **支持已有servlet设施** + 支持 Servlet API 和 Filter,用户可以重用现有基于 Servlet API 的安全组件。通过实现一个 Servlet Filter,即可集成 OAuth 和 Spring Security 等安全框架。 +- **多种方言** + 考虑到大部分用户习惯使用 SpringMVC 或 JAX-RS 进行 REST API 开发,Triple Rest 允许继续沿用这些方式定义服务,并支持大部分扩展和异常处理机制(具备原框架 80% 以上的功能)。对于追求轻量级的用户,可使用 + Basic 方言,Triple 的开箱即用 + REST 访问能力即基于此方言导出服务。 +- **扩展能力强** + 提供超过 20 个 扩展点,用户不仅可以轻松实现自定义方言,还能灵活定制参数获取、类型转换、错误处理等逻辑。 +- **开箱即用** + REST 能力开箱即用,只需启用 Triple 协议,即具备 REST 直接访问服务能力。 +- **高性能路由** + 路由部分采用优化的 [Radix Tree](https://github.com/apache/dubbo/blob/3.3/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/mapping/RadixTree.java) 和 + Zero Copy 技术,提升路由性能。 +- **OpenAPI无缝集成(TBD)** + 即将完成 OpenAPI 集成,开箱即用支持导出 OpenAPI Schema, 引入 Swagger 依赖可直接使用 Web UI 来进行服务测试。有了 OpenAPI Schema + 可使用 [Postman](https://www.postman.com/)、[Apifox](https://apifox.com/) 等API工具来管理和测试 + API,利用 OpenAPI 生态可轻松实现跨语言调用。未来会进一步支持 Schema First 的方式,先和前端团队一起定义 OpenAPI, 前端基于 OpenAPI 来生成调用代码和 Mock,后端基于 OpenAPI 来生成 Stub + 来开发服务,极大提升协同效率。 + + +## 快速开始 + +让我们从一个简单的例子开始了解 Triple Rest。您可以直接下载已有的示例项目以快速上手,假设您已经安装好 Java、Maven 和 Git + + +### 下载并运行示例 + +```bash +# 获取示例代码 +git clone --depth=1 https://github.com/apache/dubbo-samples.git +cd dubbo-samples/2-advanced/dubbo-samples-triple-rest/dubbo-samples-triple-rest-basic +# 直接运行 +mvn spring-boot:run +# 或打包后运行 +mvn clean package -DskipTests +java -jar target/dubbo-samples-triple-rest-basic-1.0.0-SNAPSHOT.jar +``` + +当然,也可以直接用IDE导入工程后直接执行 +`org.apache.dubbo.rest.demo.BasicRestApplication#main` 来运行,并通过下断点 debug 的方式来深入理解原理。 + + +### 示例代码 + +```java +// 服务接口 +package org.apache.dubbo.rest.demo; + +import org.apache.dubbo.remoting.http12.rest.Mapping; +import org.apache.dubbo.remoting.http12.rest.Param; + +public interface DemoService { + String hello(String name); + + @Mapping(path = "/hi", method = HttpMethods.POST) + String hello(User user, @Param(value = "c", type = ParamType.Header) int count); +} + +// 服务实现 +@DubboService +public class DemoServiceImpl implements DemoService { + @Override + public String hello(String name) { + return "Hello " + name; + } + + @Override + public String hello(User user, int count) { + return "Hello " + user.getTitle() + ". " + user.getName() + ", " + count; + } +} + +// 模型 +@Data +public class User { + private String title; + private String name; +} +``` + + + +### 测试基本服务 + +```bash +curl -v "http://127.0.0.1:8081/org.apache.dubbo.rest.demo.DemoService/hello?name=world" +# 输出如下 +#> GET /org.apache.dubbo.rest.demo.DemoService/hello?name=world HTTP/1.1 +#> Host: 127.0.0.1:8081 +#> User-Agent: curl/8.7.1 +#> Accept: */* +#> +#* Request completely sent off +#< HTTP/1.1 200 OK +#< content-type: application/json +#< alt-svc: h2=":8081" +#< content-length: 13 +#< +#"Hello world" +``` + +代码讲解:
可以看到输出了 "Hello world" ,有双引号是因为默认输出 content-type 为 application/json
通过这个例子可以了解 Triple 默认将服务导出到 +`/{serviceInterface}/{methodName}`路径,并支持通过url方式传递参数 + + +### 测试高级服务 + +```bash +curl -v -H "c: 3" -d 'name=Yang' "http://127.0.0.1:8081/org.apache.dubbo.rest.demo.DemoService/hi.txt?title=Mr" +# 输出如下 +#> POST /org.apache.dubbo.rest.demo.DemoService/hi.txt?title=Mr HTTP/1.1 +#> Host: 127.0.0.1:8081 +#> User-Agent: curl/8.7.1 +#> Accept: */* +#> c: 3 +#> Content-Length: 9 +#> Content-Type: application/x-www-form-urlencoded +#> +#* upload completely sent off: 9 bytes +#< HTTP/1.1 200 OK +#< content-type: text/plain +#< alt-svc: h2=":8081" +#< content-length: 17 +#< +#Hello Mr. Yang, 3 +``` + +代码讲解:
可以看到输出 Hello Mr. Yang, 3 ,没有双引号是因为通过指定后缀 txt 的方式要求用 `text/plain` 输出
通过这个例子可以了解如何通过 Mapping 注解来定制路径,通过 Param +注解来定制参数来源,并支持通过 post body 或 +url方式传递参数,详细说明参见: [Basic使用指南](#GdlnC) + + +### 观察日志 + +可以通过打开 debug 日志的方式来了解rest的启动和响应请求过程 + +```yaml +logging: + level: + "org.apache.dubbo.rpc.protocol.tri": debug + "org.apache.dubbo.remoting": debug +``` + +打开后可以观察到 Rest 映射注册和请求响应过程 + +``` +# 注册mapping +DEBUG o.a.d.r.p.t.TripleProtocol : [DUBBO] Register triple grpc mapping: 'org.apache.dubbo.rest.demo.DemoService' -> invoker[tri://192.168.2.216:8081/org.apache.dubbo.rest.demo.DemoService] + INFO .r.p.t.r.m.DefaultRequestMappingRegistry : [DUBBO] BasicRequestMappingResolver resolving rest mappings for ServiceMeta{interface=org.apache.dubbo.rest.demo.DemoService, service=DemoServiceImpl@2a8f6e6} at url [tri://192.168.2.216:8081/org.apache.dubbo.rest.demo.DemoService] +DEBUG .r.p.t.r.m.DefaultRequestMappingRegistry : [DUBBO] Register rest mapping: '/org.apache.dubbo.rest.demo.DemoService/hi' -> mapping=RequestMapping{name='DemoServiceImpl#hello', path=PathCondition{paths=[org.apache.dubbo.rest.demo.DemoService/hi]}, methods=MethodsCondition{methods=[POST]}}, method=MethodMeta{method=org.apache.dubbo.rest.demo.DemoService.hello(User, int), service=DemoServiceImpl@2a8f6e6} +DEBUG .r.p.t.r.m.DefaultRequestMappingRegistry : [DUBBO] Register rest mapping: '/org.apache.dubbo.rest.demo.DemoService/hello' -> mapping=RequestMapping{name='DemoServiceImpl#hello~S', path=PathCondition{paths=[org.apache.dubbo.rest.demo.DemoService/hello]}}, method=MethodMeta{method=org.apache.dubbo.rest.demo.DemoService.hello(String), service=DemoServiceImpl@2a8f6e6} + INFO .r.p.t.r.m.DefaultRequestMappingRegistry : [DUBBO] Registered 2 REST mappings for service [DemoServiceImpl@44627686] at url [tri://192.168.2.216:8081/org.apache.dubbo.rest.demo.DemoService] in 11ms + +# 请求响应 +DEBUG .a.d.r.p.t.r.m.RestRequestHandlerMapping : [DUBBO] Received http request: DefaultHttpRequest{method='POST', uri='/org.apache.dubbo.rest.demo.DemoService/hi.txt?title=Mr', contentType='application/x-www-form-urlencoded'} +DEBUG .r.p.t.r.m.DefaultRequestMappingRegistry : [DUBBO] Matched rest mapping=RequestMapping{name='DemoServiceImpl#hello', path=PathCondition{paths=[/org.apache.dubbo.rest.demo.DemoService/hi]}, methods=MethodsCondition{methods=[POST]}}, method=MethodMeta{method=org.apache.dubbo.rest.demo.DemoService.hello(User, int), service=DemoServiceImpl@2a8f6e6} +DEBUG .a.d.r.p.t.r.m.RestRequestHandlerMapping : [DUBBO] Content-type negotiate result: request='application/x-www-form-urlencoded', response='text/plain' +DEBUG .d.r.h.AbstractServerHttpChannelObserver : [DUBBO] Http response body is: '"Hello Mr. Yang, 3"' +DEBUG .d.r.h.AbstractServerHttpChannelObserver : [DUBBO] Http response headers sent: {:status=[200], content-type=[text/plain], alt-svc=[h2=":8081"], content-length=[17]} +``` + + + +## 通用功能 + + + +### 路径映射 + +兼容 SpringMVC 和 JAX-RS 的映射方式,相关文档: + +- [Spring Mapping Requests](https://docs.spring.io/spring-framework/reference/web/webmvc/mvc-controller/ann-requestmapping.html#mvc-ann-requestmapping-uri-templates) +- [Spring PathPattern](https://docs.spring.io/spring-framework/docs/6.1.12/javadoc-api/org/springframework/web/util/pattern/PathPattern.html) +- [Spring AntPathMatcher](https://docs.spring.io/spring-framework/docs/6.1.12/javadoc-api/org/springframework/util/AntPathMatcher.html) +- [JAX-RS Path and regular expression mappings](https://docs.jboss.org/resteasy/docs/6.2.7.Final/userguide/html/ch04.html) + +还支持通过实现 SPI `org.apache.dubbo.rpc.protocol.tri.rest.mapping.RequestMappingResolver` 来自定义路径映射 + + +#### 支持的模式 + +1. `books` 字符串常量,最基本的类型,匹配一个固定的段 +2. `?` 匹配一个字符 +3. `*` 匹配路径段中的零个或多个字符 +4. `**` 匹配直到路径末尾的零个或多个路径段 +5. `{spring}` 匹配一个路径段并将其捕获为名为 "spring" 的变量 +6. `{spring:[a-z]+}` 使用正则表达式 `[a-z]+` 匹配路径段,并将其捕获为名为 "spring" 的路径变量 +7. `{*spring}` 匹配直到路径末尾的零个或多个路径段,并将其捕获为名为 "spring" 的变量,如果写 `{*}` 表示不捕获 + + +#### 示例(来自Spring文档) + +- `/pages/t?st.html` — 匹配 `/pages/test.html` 以及 `/pages/tXst.html`,但不匹配 `/pages/toast.html` +- `/resources/*.png` — 匹配 `resources` 目录中的所有 `.png` 文件 +- `com/**/test.jsp` — 匹配 `com` 路径下的所有 `test.jsp` 文件 +- `org/springframework/**/*.jsp` — 匹配 `org/springframework` 路径下的所有 `.jsp` 文件 +- `/resources/**` — 匹配 `/resources/` 路径下的所有文件,包括 `/resources/image.png` 和 `/resources/css/spring.css` +- `/resources/{*path}` — 匹配 `/resources/` 下的所有文件,以及 `/resources`,并将其相对路径捕获在名为 "path" 的变量中;例如, + `/resources/image.png` 会匹配到 "path" → "/image.png",`/resources/css/spring.css` 会匹配到 "path" → "/css/spring.css" +- `/resources/{filename:\\w+}.dat` — 匹配 `/resources/spring.dat` 并将值 "spring" 分配给 `filename` 变量 +- `/{name:[a-z-]+}-{version:\\d\\.\\d\\.\\d}{ext:\\.[a-z]+}` — 匹配 `/example-2.1.5.html` 则 `name` 为 `example`, + `version` 为 `2.1.5`,`ext` 为 `.html` + +小技巧如果使用正则不希望跨段可以使用 `{name:[^/]+}` 来匹配 + + +#### 映射匹配完整流程 + +具体的匹配处理代码:[DefaultRequestMappingRegistry.java](https://github.com/apache/dubbo/blob/dubbo-3.3.0-beta.5/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/mapping/DefaultRequestMappingRegistry.java#L196) [RequestMapping.java](https://github.com/apache/dubbo/blob/dubbo-3.3.0-beta.5/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/mapping/RequestMapping.java#L127) + +1. 使用 `PathUtils.normalize` 对路径进行清洗,去掉诸如 `/one/../` `/one/./` 之类间接路径,保证一定已 `/` 开头 +2. 检查 `http method` 是否匹配 +3. 检查 `path` 是否匹配 +4. 检查 `paramter` 是否匹配(JAX-RS不支持) +5. 检查 `header` 是否匹配 +6. 检查 `content-type` 是否匹配(Consumes) +7. 检查 `accept` 是否匹配 (Produces) +8. 检查 `serviceGroup` 和 `serviceVersion` 是否匹配 +9. 检查 `method` 首字母签名是否匹配 +10. 未找到任何匹配项,如果尾 `/` 匹配开启并且路径 `/` 结尾则去掉尾 `/` 尝试从第2步开始匹配 +11. 未找到任何匹配项,如果扩展名匹配开启并且扩展名被支持,则去掉扩展名尝试从第2步开始匹配 +12. 如果最后一段路径包含 `~` 表示开启 method 首字母签名匹配,尝试从第2步开始匹配 +13. 如果候选项为0,匹配结束,返回null +14. 如果候选项为0,匹配结束,返回命中项 +15. 如果不止一个候选项,对候选项进行排序 +16. 对第一项和第二项进行顺序比较 +17. 结果为0表示无法确认最终匹配项,抛异常失败 +18. 第一项胜出,匹配结束,返回命中项 + + +#### 路径重复问题 + +与 Spring 不同,Spring 在路径完全相同时会直接报错并阻止启动,而 Triple Rest 具备开箱即用的特性,为了避免影响现有服务,默认只会打印 WARN 日志。在运行时,如果最终无法确定最高优先级的映射,才会抛出错误。 + + +### 入参类型 + +不同方言支持的入参类型不同,详情请参见各方言使用指南。
还支持通过实现 SPI +`org.apache.dubbo.rpc.protocol.tri.rest.argument.ArgumentResolver` 来自定义入参解析 + + +#### 通用类型参数 + +| 名称 | 说明 | Basic 注解 | SpringMVC注解 | JAX-RS注解 | 数组或集合处理方式 | Map处理方式 | +|----------------|---------------|-----------------------------|-------------------|--------------|----------------|-----------------| +| Param | Query或Form的参数 | @Param | @RequestParam | - | 多值 | 所有参数的Map | +| Query | url上带的参数 | - | - | @QueryParam | 多值 | 所有Query参数的Map | +| Form | form表单带的参数 | - | - | @FormParam | 多值 | 所有Form参数的Map | +| Header | HTTP头 | @Param(type=Header) | @RequestHeader | @HeaderParam | 多值 | 所有Header参数的Map | +| Cookie | Cookie值 | @Param(type=Cookie) | @CookieValue | @CookieParam | 多值 | 所有Cookie参数的Map | +| Attribute | Request属性 | @Param(type=Attribute) | @RequestAttribute | - | 多值 | 所有Attribute的Map | +| Part | Multipart文件 | @Param(type=Part) | @RequestHeader | @HeaderParam | 多值 | 所有Part的Map | +| Body | 请求body | @Param(type=Body) | @RequestBody | @Body | 尝试解析为数组或集合 | 尝试解析为目标类型 | +| PathVariable | path变量 | @Param(type=PathVariable) | @PathVariable | @PathParam | 单值数组或集合 | 单值Map | +| MatrixVariable | matrix变量 | @Param(type=MatrixVariable) | @MatrixVariable | @MatrixParam | 多值 | 单值Map | +| Bean | java bean | 无需注解 | @ModelAttribute | @BeanParam | 尝试解析为Bean数组或集合 | - | + + + +#### 特殊类型参数 + +| 类型 | 说明 | 激活条件 | +|-----------------------------------------------|---------------------------|-------------------| +| org.apache.dubbo.remoting.http12.HttpRequest | HttpRequest对象 | 默认激活 | +| org.apache.dubbo.remoting.http12.HttpResponse | HttpResponse对象 | 默认激活 | +| org.apache.dubbo.remoting.http12.HttpMethods | 请求Http方法 | 默认激活 | +| java.util.Locale | 请求Locale | 默认激活 | +| java.io.InputStream | 请求输入流 | 默认激活 | +| java.io.OutputStream | 响应输出流 | 默认激活 | +| javax.servlet.http.HttpServletRequest | Servlet HttpRequest对象 | 引入Servlet API jar | +| javax.servlet.http.HttpServletResponse | Servlet HttpResponse对象 | 同上 | +| javax.servlet.http.HttpSession | Servlet HttpSession对象 | 同上 | +| javax.servlet.http.Cookie | Servlet Cookie对象 | 同上 | +| java.io.Reader | Servlet Request Reader对象 | 同上 | +| java.io.Writer | Servlet Response Writer对象 | 同上 | + + + +#### 无注解参数 + +不同方言处理方式不同,请参见各方言使用说明 + + +#### 无入参方式获取 HTTP 输入输出参数 + +可通过 `RpcContext` 来获取 + +```java +// Dubbo http req/resp +HttpRequest request = RpcContext.getServiceContext().getRequest(HttpRequest.class); +HttpResponse response = RpcContext.getServiceContext().getRequest(HttpResponse.class); +// Servlet http req/resp +HttpServletRequest request = RpcContext.getServiceContext().getRequest(HttpServletRequest.class); +HttpServletResponse response = RpcContext.getServiceContext().getRequest(HttpServletResponse.class); +``` + +拿到request之后,通过 attribute +可以访问一些内置属性,参见:[RestConstants.java](https://github.com/apache/dubbo/blob/dubbo-3.3.0-beta.5/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/RestConstants.java#L40) + + +### 参数类型转换 + +默认支持大部分从 String 到目标类型的参数类型转换,主要包括以下几大类: + +- Jdk内置类型,包括基础类型和日期、Optional等 +- 数组类型 +- 集合类型 +- Map类型 + +同时也完整支持泛型类型,包括复杂嵌套,具体地实现代码参见: [GeneralTypeConverter.java](https://github.com/apache/dubbo/blob/dubbo-3.3.0-beta.5/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/argument/GeneralTypeConverter.java)
+还支持通过实现SPI +`org.apache.dubbo.rpc.protocol.tri.rest.argument.ArgumentConverter` 来自定义参数类型转换 + +| Source Type | Target Type | Description | Default Value | +|-------------|-------------------------|----------------------------------|---------------| +| `String` | `double` | Converts to a double | 0.0d | +| `String` | `float` | Converts to a float | 0.0f | +| `String` | `long` | Converts to a long | 0L | +| `String` | `int` | Converts to an integer | 0 | +| `String` | `short` | Converts to a short | 0 | +| `String` | `char` | Converts to a character | 0 | +| `String` | `byte` | Converts to a byte | 0 | +| `String` | `boolean` | Converts to a boolean | false | +| `String` | `BigInteger` | Converts to a BigInteger | null | +| `String` | `BigDecimal` | Converts to a BigDecimal | null | +| `String` | `Date` | Converts to a Date | null | +| `String` | `Calendar` | Converts to a Calendar | null | +| `String` | `Timestamp` | Converts to a Timestamp | null | +| `String` | `Instant` | Converts to an Instant | null | +| `String` | `ZonedDateTime` | Converts to a ZonedDateTime | null | +| `String` | `LocalDate` | Converts to a LocalDate | null | +| `String` | `LocalTime` | Converts to a LocalTime | null | +| `String` | `LocalDateTime` | Converts to a LocalDateTime | null | +| `String` | `ZoneId` | Converts to a ZoneId | null | +| `String` | `TimeZone` | Converts to a TimeZone | null | +| `String` | `File` | Converts to a File | null | +| `String` | `Path` | Converts to a Path | null | +| `String` | `Charset` | Converts to a Charset | null | +| `String` | `InetAddress` | Converts to an InetAddress | null | +| `String` | `URI` | Converts to a URI | null | +| `String` | `URL` | Converts to a URL | null | +| `String` | `UUID` | Converts to a UUID | null | +| `String` | `Locale` | Converts to a Locale | null | +| `String` | `Currency` | Converts to a Currency | null | +| `String` | `Pattern` | Converts to a Pattern | null | +| `String` | `Class` | Converts to a Class | null | +| `String` | `byte[]` | Converts to a byte array | null | +| `String` | `char[]` | Converts to a char array | null | +| `String` | `OptionalInt` | Converts to an OptionalInt | null | +| `String` | `OptionalLong` | Converts to an OptionalLong | null | +| `String` | `OptionalDouble` | Converts to an OptionalDouble | null | +| `String` | `Enum class` | Enum.valueOf | null | +| `String` | `Array` or `Collection` | Split by comma | null | +| `String` | `Specified class` | Try JSON String to Object | null | +| `String` | `Specified class` | Try construct with single String | null | +| `String` | `Specified class` | Try call static method `valueOf` | null | + + + +### 支持的Content-Type + +默认支持以下 Content-Type,提供相应的编码和解码功能。
还支持通过实现SPI +`org.apache.dubbo.remoting.http12.message.(HttpMessageDecoderFactory|HttpMessageEncoderFactory)`来扩展 + +| Media Type | Description | +|-------------------------------------|----------------------------| +| `application/json` | JSON format | +| `application/xml` | XML format | +| `application/yaml` | YAML format | +| `application/octet-stream` | Binary data | +| `application/grpc` | gRPC format | +| `application/grpc+proto` | gRPC with Protocol Buffers | +| `application/x-www-form-urlencoded` | URL-encoded form data | +| `multipart/form-data` | Form data with file upload | +| `text/json` | JSON format as text | +| `text/xml` | XML format as text | +| `text/yaml` | YAML format as text | +| `text/css` | CSS format | +| `text/javascript` | JavaScript format as text | +| `text/html` | HTML format | +| `text/plain` | Plain text | + + + +### 内容协商 + +支持完善的内容协商机制,可根据映射或输入来协商输出的 Content-Type,具体流程如下: + +1. 尝试读取 Mapping 指定的 mediaType,获取 Produces指定的 mediaType 列表,并将通配符匹配到合适的 Media Type。例如Spring的: + `@RequestMapping(produces = "application/json")` +2. 尝试通过 Accept 头查找 mediaType,解析请求的 `Accept` 头,并将通配符匹配到合适的 Media Type。例如: + `Accept: application/json` +3. 尝试通过 format 参数查找 mediaType,读取 format 参数值,做为文件后缀匹配到合适的 Media Type。例如 `/hello?format=yml` +4. 尝试通过请求路径的扩展名查找 mediaType,扩展名做为文件后缀匹配到合适的 Media Type。例如 `/hello.txt` +5. 尝试读取请求的 Content-Type 头做为 Media Type(两种form类型除外)。例如 `Content-Type: application/json` +6. 使用 `application/json` 兜底 + + +### CORS支持 + +提供完整的CORS支持,通过配置全局参数即可启用,默认行为和SpringMVC一致,同时在SpringMVC方言中,也支持通过 +`@CrossOrigin` 来做精细化配置。
支持的CORS 配置项参见:[8.4CORS配置](#NLQqj) + + +### 自定义HTTP输出 + +很多场景需要对HTTP输出进行定制,比如做302跳转,写Http头,为此 Triple Rest提供以下通用方案,同时也支持各方言的特定写法,详情参见各方言使用指南 + +- 返回值设置为: `org.apache.dubbo.remoting.http12.HttpResult` 可通过 `HttpResult#builder` 来构建 +- 抛出Payload异常: + `throws new org.apache.dubbo.remoting.http12.exception.HttpResultPayloadException(HttpResult)` 示例代码: + +```java +throw new HttpResult.found("https://a.com"). + +toPayload(); +``` + +此异常已避免填充错误栈,对性能无太大影响,并且不用考虑返回值逻辑,推荐用这个方式来定制输出 + +- 获取 HttpResponse 后自定义,实例代码: + +```java +HttpResponse response = RpcContext.getServiceContext().getRequest(HttpResponse.class); + +response. + +sendRedirect("https://a.com"); +response. + +setStatus(404); +response. + +outputStream(). + +write(data); +// 写完输出建议 commit 来避免被其他扩展改写 +response. + +commit(); +``` + +如果只是增加 `http header` 推荐用这个方式 + + +### 自定义JSON解析和输出 +支持Jackson、fastjson2、fastjson和gson等多种JSON框架,使用前请确保对应jar依赖已被引入 + +#### 指定使用的JSON框架 +```properties +dubbo.protocol.triple.rest.json-framework=jackson +``` + +#### 通过 JsonUtil SPI 定制 +可通过实现 SPI `org.apache.dubbo.common.json.JsonUtil` 方式来自定义JSON处理,具体可以参考 [org/apache/dubbo/common/json/impl](https://github.com/apache/dubbo/tree/3.3/dubbo-common/src/main/java/org/apache/dubbo/common/json/impl) 已有实现,建议继承现有实现并重写 + + +### 异常处理 + +未被处理的异常最终被转换成 `ErrorResponse` 类编码后输出: + +```java + +@Data +public class ErrorResponse { + /** + * http status code + */ + private String status; + + /** + * exception message + */ + private String message; +} +``` + +注意对于500及以上错误,为避免泄露服务端内部信息,默认只会输出 message "Internal Server Error",如果需要自定义 message 可创建继承自 +`org.apache.dubbo.remoting.http12.exception.HttpStatusException` 异常并重写 +`getDisplayMessage` 方法。
提供了以下通用方法来定制异常处理: + +- 参考 [9.2自定义异常返回结果](#zFD9A) 使用SPI 自定义全局异常处理 +- 使用 Dubbo的 Filter SPI 来加工转换异常,如果需要访问 Http 上下文,可继承 `org.apache.dubbo.rpc.protocol.tri.rest.filter.RestFilterAdapter` +- 使用 SPI `org.apache.dubbo.rpc.protocol.tri.rest.filter.RestFilter` 来转换异常,使用上更轻量并提供路径匹配配置能力 + +注意后2项只能拦截 invoke 链中出现的异常,如果在路径匹配阶段出现异常,只有有方法1能处理 + + +## Basic使用指南 + +示例参见:[dubbo-samples-triple-rest/dubbo-samples-triple-rest-basic](https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-triple-rest/dubbo-samples-triple-rest-basic) + + +### 路径映射 + +Basic做为开箱即用 Rest 映射,默认会将方法映射到: `/{contextPath}/{serviceInterface}/{methodName}` ,其中 +`/{contextPath}` 如果协议没有配置会忽略,即为:`/{serviceInterface}/{methodName}`
映射的自定义通过注解 +`org.apache.dubbo.remoting.http12.rest.Mapping` 来支持,属性说明如下: + +| 配置名 | 说明 | 默认行为 | +|------------|-------------------------------------|-------------| +| `value` | 映射的 URL 路径,可以是一个或多个路径。 | 空数组 | +| `path` | 映射的 URL 路径,与 `value` 相同,可以是一个或多个路径。 | 空数组 | +| `method` | 支持的 HTTP 方法列表,例如 `GET`、`POST` 等。 | 空数组(支持所有方法) | +| `params` | 请求必须包含的参数列表。 | 空数组 | +| `headers` | 请求必须包含的头部列表。 | 空数组 | +| `consumes` | 处理请求的内容类型(Content-Type),可以是一个或多个类型。 | 空数组 | +| `produces` | 生成响应的内容类型(Content-Type),可以是一个或多个类型。 | 空数组 | +| `enabled` | 是否启用该映射。 | `true`(启用) | + +- 属性支持用占位符方式配置:`@Mapping("${prefix}/hi")` +- 如果不希望特定服务或方法被 rest 导出,可以通过设置 `@Mapping(enabled = false)` 解决 + + +### 入参类型 + +通用入参见:[3.2入参类型](#kmCzf) + + +#### 无注解参数 + +Basic +的无注解参数由类:[FallbackArgumentResolver.java](https://github.com/apache/dubbo/blob/dubbo-3.3.0-beta.5/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/support/basic/FallbackArgumentResolver.java#L41) +支持,具体处理流程如下:
![rest-arg.jpg](/imgs/v3/manual/java/protocol/rest-arg.jpg) + + +## SpringMVC使用指南 + +示例参见:[dubbo-samples-triple-rest/dubbo-samples-triple-rest-springmvc](https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-triple-rest/dubbo-samples-triple-rest-springmvc) + + +### 路径映射 + +直接参考SpringMVC文档即可,支持绝大多数特性,[Mapping Requests :: Spring Framework](https://docs.spring.io/spring-framework/reference/web/webmvc/mvc-controller/ann-requestmapping.html#mvc-ann-requestmapping-uri-templates)
+注意无需 +`@Controller` 或 `@RestController` 注解,除了 `@RequestMapping` 还支持新的 `@HttpExchange` + + +### 入参类型 + + + +#### 通用入参 + +参见:[3.2入参类型](#kmCzf) + + +#### 注解类型参数 + +参见 [3.2.1通用类型参数](#dCgzz) + + +#### 特殊类型参数 + +| 类型 | 说明 | 激活条件 | +|----------------------------------------------------------|--------------------|---------------| +| org.springframework.web.context.request.WebRequest | WebRequest对象 | 引入SpringWeb依赖 | +| org.springframework.web.context.request.NativeWebRequest | NativeWebRequest对象 | 同上 | +| org.springframework.http.HttpEntity | Http实体 | 同上 | +| org.springframework.http.HttpHeaders | Http头 | 同上 | +| org.springframework.util.MultiValueMap | 多值Map | 同上 | + + + +#### 无注解参数 + +- 如果是基本类型 ( + 根据 [TypeUtils#isSimpleProperty](https://github.com/apache/dubbo/blob/dubbo-3.3.0-beta.5/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/util/TypeUtils.java#L105) + 判断),直接从Parameter中获取 +- 如果非基本类型,使用 [@ModelAttribute :: Spring Framework](https://docs.spring.io/spring-framework/reference/web/webmvc/mvc-controller/ann-methods/modelattrib-method-args.html) + 来绑定复杂 bean 类型参数 + + +### 参数类型转换 + +优先使用 Spring 的 `org.springframework.core.convert.ConversionService` 来转换参数,如果应用为spring boot应用则默认使用 +`mvcConversionService` 否则使用 +`org.springframework.core.convert.support.DefaultConversionService#getSharedInstance` 获取共享 +`ConversionService`
如果 `ConversionService` 不支持则会回退到通用类型转换:[3.3参数类型转换](#I56vX) + + +### 异常处理 + +除了支持 [3.8异常处理](#XeDPr) 中提到的方式,还支持 Spring +`@ExceptionHandler` 注解方式,[Exceptions :: Spring Framework](https://docs.spring.io/spring-framework/reference/web/webmvc/mvc-controller/ann-exceptionhandler.html) +,注意通过这种方式仅能处理方法调用时抛出的异常,其他异常无法捕获 + + +### CORS配置 + +除了支持 [8.4CORS配置](#NLQqj) 全局配置,还支持 Spring +`@CrossOrigin` 来精细化配置,[CORS :: Spring Framework](https://docs.spring.io/spring-framework/reference/web/webmvc-cors.html#mvc-cors-controller) + + +### 自定义HTTP输出 + +支持以下 Spring 自定义方式: + +1. 使用 `@ResponseStatus` 注解 +2. 返回 `org.springframework.http.ResponseEntity` 对象 + + +### 支持的扩展 + +- org.springframework.web.servlet.HandlerInterceptor
使用方式类似 [7.1使用 Filter 扩展](#xCEi3) + + +## JAX-RS使用指南 + +示例参见:[dubbo-samples-triple-rest/dubbo-samples-triple-rest-jaxrs](https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-triple-rest/dubbo-samples-triple-rest-jaxrs) + + +### 路径映射 + +Service需要显式添加注解@Path,方法需要添加@GET、@POST、@HEAD等请求方法注解
+直接参考Resteasy文档即可,支持绝大多数特性,[Chapter 4. Using @Path and @GET, @POST, etc](https://docs.jboss.org/resteasy/docs/6.2.7.Final/userguide/html/ch04.html) + + +### 入参类型 + + + +#### 通用入参 + +参见:[3.2入参类型](#kmCzf) + + +#### 注解类型参数 + +| 注解 | 参数位置 | 说明 | +|--------------|-------------|--------------------------------| +| @QueryParam | querystring | ?a=a&b=b对应的参数 | +| @HeaderParam | header | | +| @PathParam | path |
| +| @FormParam | form | body为key1=value2&key2=value2格式 | +| 无注解 | body | 不显式使用注解 | + + + +#### 特殊类型参数 + +| 类型 | 说明 | 激活条件 | +|---------------------------------|----------|------------| +| javax.ws.rs.core.Cookie | Cookie对象 | 引入Jax-rs依赖 | +| javax.ws.rs.core.Form | 表单对象 | 同上 | +| javax.ws.rs.core.HttpHeaders | Http头 | 同上 | +| javax.ws.rs.core.MediaType | 媒体类型 | 同上 | +| javax.ws.rs.core.MultivaluedMap | 多值Map | 同上 | +| javax.ws.rs.core.UriInfo | Uri信息 | 同上 | + + + +#### 无注解参数 + +- 如果是基本类型 ( + 根据 [TypeUtils#isSimpleProperty](https://github.com/apache/dubbo/blob/dubbo-3.3.0-beta.5/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/util/TypeUtils.java#L105) + 判断),直接从Parameter中获取 +- 如果非基本类型, 将其视为请求体 (body)来解码对象 + + +### 参数类型转换 + +可通过扩展自定义参数转换,扩展接口: + +``` +org.apache.dubbo.rpc.protocol.tri.rest.argument.ArgumentResolver +javax.ws.rs.ext.ParamConverterProvider +``` + + + +### 异常处理 + +可通过扩展自定义异常处理,扩展接口: + +``` +javax.ws.rs.ext.ExceptionMapper +org.apache.dubbo.remoting.http12.ExceptionHandler +``` + + + +### CORS配置 + +支持 [8.4CORS配置](#NLQqj) 全局配置 + + +### 自定义HTTP输出 + +支持以下 Jaxrs 自定义方式: + +- 返回 `javax.ws.rs.core.Response` 对象 + + +### 支持的扩展 + +1. javax.ws.rs.container.ContainerRequestFilter
请求过滤器,允许在请求到达资源方法之前对请求进行预处理。 +2. javax.ws.rs.container.ContainerResponseFilter
响应过滤器,允许在响应离开资源方法之后对响应进行后处理。 +3. javax.ws.rs.ext.ExceptionMapper
异常映射器,将抛出的异常映射为HTTP响应。 +4. javax.ws.rs.ext.ParamConverterProvider
参数转换器,允许将请求参数转换为资源方法的参数类型。 +5. javax.ws.rs.ext.ReaderInterceptor
读取拦截器,允许在读取请求实体时进行拦截和处理。 +6. javax.ws.rs.ext.WriterInterceptor
写入拦截器,允许在写入响应实体时进行拦截和处理。 + + +## Servlet使用指南 + +同时低版本javax和高版本jakarta servlet API,jakarta API 优先级更高,只需要引入jar即可使用HttpServletRequest和HttpServletResponse作为参数 + + +### 使用 Filter 扩展 + +方法1,实现 `Filter` 接口和 `org.apache.dubbo.rpc.protocol.tri.rest.filter.RestExtension` 接口,然后注册SPI + +```java +import org.apache.dubbo.rpc.protocol.tri.rest.filter.RestExtension; + +import javax.servlet.Filter; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; + +public class DemoFilter implements Filter, RestExtension { + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) { + chain.doFilter(request, response); + } + + @Override + public String[] getPatterns() { + return new String[]{"/demo/**", "!/demo/one"}; + } + + @Override + public int getPriority() { + return -200; + } +} +``` + +方法2,实现 `Supplier` 接口和 `org.apache.dubbo.rpc.protocol.tri.rest.filter.RestExtension` 接口,然后注册SPI + +```java +public class DemoFilter implements Supplier, RestExtension { + + private final Filter filter = new SsoFilter(); + + @Override + public Filter get() { + return filter; + } +} +``` + +这种方式对于重用已有 Filter 非常方便,甚至可以从 Spring Context 中获取 Filter 实例并注册 + +```java +public class DemoFilter implements Supplier, RestExtension { + + private final Filter filter = new SsoFilter(); + + public DemoFilter(FrameworkModel frameworkModel) { + SpringExtensionInjector injector = SpringExtensionInjector.get(frameworkModel.defaultApplication()); + filter = injector.getInstance(SsoFilter.class, null); + } + + @Override + public Filter get() { + return filter; + } +} +``` + + + +### HttpSession支持 + +实现 SPI `org.apache.dubbo.rpc.protocol.tri.rest.support.servlet.HttpSessionFactory` + + +### 尚不支持的特性 + +- Filter 中 wrap request 和 response对象不会生效,原因是 Rest支持的 过滤器种类很多,使用wrapper会导致反复嵌套,处理过于复杂 +- 不支持 `request.getRequestDispatcher` + + +### 安全配置 + +当 REST 服务直接暴露在公网时,存在被攻击的安全风险。因此在暴露服务之前,需要充分评估风险并选择合适的认证方式来保证安全性。Triple 提供了多种安全认证机制,同时用户也可以自行实现相应的扩展来对访问进行安全校验。 + +#### Basic 认证 + +要启用 Basic 认证,请修改以下配置: + +```yaml +dubbo: + provider: + auth: true + authenticator: basic + username: admin + password: admin +``` + +启用后,所有 HTTP 请求都需要通过 Basic 认证才能访问。 + +如果是 RPC 调用,还需要在消费者端配置相应的用户名和密码: + +```yaml +dubbo: + consumer: + auth: true + authenticator: basic + username: admin + password: admin +``` + +这样配置后,provider 和 consumer 之间的通信将使用 Basic 认证来保证安全性。请确保在生产环境中使用强密码,并考虑采用 HTTPS 来加密传输。 + +### 认证扩展 +#### 实现自定义 Authenticator +可通过 SPI `org.apache.dubbo.auth.spi.Authenticator` 来自定义认证,并通过配置 dubbo.provider.authenticator 来选择启用的 Authenticator + +#### 实现 HTTP 请求过滤 +可通过 SPI `org.apache.dubbo.rpc.HeaderFilter` 或 `org.apache.dubbo.rpc.protocol.tri.rest.filter.RestFilter` 来自定义 HTTP 过滤器逻辑 + +## 全局参数配置 + + + +### 大小写敏感 + +配置名:`dubbo.protocol.triple.rest.case-sensitive-match`
是否路径匹配应区分大小写。如果启用,映射到 `/users` 的方法不会匹配到 +`/Users`
默认为 `true` + + +### 尾匹配 + +配置名:`dubbo.protocol.triple.rest.trailing-slash-match`
是否路径匹配应匹配带有尾部斜杠的路径。如果启用,映射到 +`/users` 的方法也会匹配到 `/users/`
默认为 `true` + + +### 扩展名匹配 + +配置名:`dubbo.protocol.triple.rest.suffix-pattern-match`
是否路径匹配使用后缀模式匹配(.*) ,如果启用,映射到 +`/users` 的方法也会匹配到 `/users.*` ,后缀内容协商会被同时启用,媒体类型从URL后缀推断,例如 `.json` 对应 +`application/json`
默认为 `true` + + +### CORS配置 + +| 配置名 | 说明 | 默认值 | +|-----------------------------------------------------|-------------------------------------------------------|-------------------------| +| `dubbo.protocol.triple.rest.cors.allowed-origins` | 允许跨域请求的来源列表,可以是具体域名或特殊值 `*` 代表所有来源。 | 未设置(不允许任何来源) | +| `dubbo.protocol.triple.rest.cors.allowed-methods` | 允许的 HTTP 方法列表,例如 `GET`、`POST`、`PUT` 等,特殊值 `*` 代表所有方法。 | 未设置(仅允许 `GET` 和 `HEAD`) | +| `dubbo.protocol.triple.rest.cors.allowed-headers` | 预检请求中允许的请求头列表,特殊值 `*` 代表所有请求头。 | 未设置 | +| `dubbo.protocol.triple.rest.cors.exposed-headers` | 实际响应中可以暴露给客户端的响应头列表,特殊值 `*` 代表所有响应头。 | 未设置 | +| `dubbo.protocol.triple.rest.cors.allow-credentials` | 是否支持用户凭证。 | 未设置(不支持用户凭证) | +| `dubbo.protocol.triple.rest.cors.max-age` | 预检请求的响应可以被客户端缓存的时间(以秒为单位)。 | 未设置 | + + + +## 高级使用指南 + + + +### 支持的扩展点汇总 + +1. javax.servlet.Filter
Servlet API过滤器。 +2. org.apache.dubbo.rpc.protocol.tri.rest.support.servlet.HttpSessionFactory
用于在Servlet API中支持 HttpSession。 +3. javax.ws.rs.container.ContainerRequestFilter
用于在JAX-RS中实现请求过滤器,允许在请求到达资源方法之前对请求进行预处理。 +4. javax.ws.rs.container.ContainerResponseFilter
用于在JAX-RS中实现响应过滤器,允许在响应离开资源方法之后对响应进行后处理。 +5. javax.ws.rs.ext.ExceptionMapper
用于在JAX-RS中实现异常映射器,将抛出的异常映射为HTTP响应。 +6. javax.ws.rs.ext.ParamConverterProvider
用于在JAX-RS中提供参数转换器,允许将请求参数转换为资源方法的参数类型。 +7. javax.ws.rs.ext.ReaderInterceptor
用于在JAX-RS中实现读取拦截器,允许在读取请求实体时进行拦截和处理。 +8. javax.ws.rs.ext.WriterInterceptor
用于在JAX-RS中实现写入拦截器,允许在写入响应实体时进行拦截和处理。 +9. org.springframework.web.servlet.HandlerInterceptor
用于在Spring MVC中实现处理器拦截器。 +10. org.apache.dubbo.remoting.http12.ExceptionHandler
提供异常自定义处理机制。 +11. org.apache.dubbo.remoting.http12.message.HttpMessageAdapterFactory
提供HTTP消息的适配和转换功能。 +12. org.apache.dubbo.remoting.http12.message.HttpMessageDecoderFactory
提供HTTP消息的解码功能。 +13. org.apache.dubbo.remoting.http12.message.HttpMessageEncoderFactory
提供HTTP消息的编码功能。 +14. org.apache.dubbo.rpc.HeaderFilter
用于在Dubbo RPC中实现头部过滤器,允许对请求和响应的头部进行过滤和处理。 +15. org.apache.dubbo.rpc.protocol.tri.rest.filter.RestHeaderFilterAdapter
头部过滤器适配器,提供访问http输入输出能力。 +16. org.apache.dubbo.rpc.protocol.tri.rest.filter.RestFilterAdapter
Dubbo Filter Rest适配器,提供访问http输入输出能力。 +17. org.apache.dubbo.rpc.protocol.tri.route.RequestHandlerMapping
用于在Dubbo Triple中实现请求映射能力。 +18. org.apache.dubbo.rpc.protocol.tri.rest.mapping.RequestMappingResolver
用于解析REST请求映射。 +19. org.apache.dubbo.rpc.protocol.tri.rest.util.RestToolKit
提供REST相关的工具和实用程序。 +20. org.apache.dubbo.rpc.protocol.tri.rest.argument.ArgumentConverter
提供参数的类型转换功能。 +21. org.apache.dubbo.rpc.protocol.tri.rest.argument.ArgumentResolver
提供参数的解析功能。 +22. org.apache.dubbo.rpc.protocol.tri.rest.filter.RestFilter
提供REST请求和响应的过滤功能。 +23. org.apache.dubbo.rpc.protocol.tri.rest.filter.RestExtensionAdapter
提供RestExtension的adapt能力,将已有filter接口映射到RestFilter接口。 + + +### 自定义异常返回结果 + +通过 SPI `org.apache.dubbo.remoting.http12.ExceptionHandler` 来自定义异常处理逻辑 + +```java +public interface ExceptionHandler { + /** + * Resolves the log level for a given throwable. + */ + default Level resolveLogLevel(E throwable) { + return null; + } + + /** + * Handle the exception and return a result. + */ + default T handle(E throwable, RequestMetadata metadata, MethodDescriptor descriptor) { + return null; + } +} +``` + +实现 SPI 并将泛型 E 指定为需要处理的异常类型 + +- resolveLogLevel
Dubbo框架内部会打印Rest处理异常日志,可以通过实现这个方法来自定义需要打印的日志级别或忽略日志。 +- handle
如果返回结果不是 null ,则将直接输出返回结果,可以通过返回 + `org.apache.dubbo.remoting.http12.HttpResult` 来定制输出的 headers 和 status code。 + + +### 打开debug日志 + +```yaml +logging: + level: + "org.apache.dubbo.rpc.protocol.tri": debug + "org.apache.dubbo.remoting": debug +``` + +开启 debug 日志会输出详细的启动日志和请求响应日志,便于排查问题。 + + +### 打开verbose输出 + +```yaml +dubbo: + protocol: + triple: + verbose: true +``` + +开启 verbose 输出会将内部错误堆栈返回给调用方,并输出更多错误日志,便于排查问题。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/triple-3.3.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/triple-3.3.md new file mode 100644 index 000000000000..ff73d7ec5d9e --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/triple-3.3.md @@ -0,0 +1,276 @@ +--- +aliases: + - /zh/docs3-v2/java-sdk/reference-manual/protocol/triple/3.3/ + - /zh-cn/docs3-v2/java-sdk/reference-manual/protocol/triple/3.3/ +description: "本文介绍 triple 协议在 3.3 版本中的新特性" +linkTitle: tripe-3.3新特性 +title: Tripe 3.3 新特性 +type: docs +weight: 5 +--- + + + +## 全新的 Rest 支持 + + + +### 特性 + +在3.3版本中,基于现有 HTTP 协议栈,triple实现了全面的 REST 风格服务导出能力,无需使用泛化或网关层协议转换,无需配置,用户即可通过 HTTP 协议去中心化直接访问后端的 Triple 协议服务。同时,针对高级 +REST 用法,如路径定制、输出格式定制和异常处理,提供了丰富的注解和 +SPI 扩展支持。其主要特性包括: + +- **Triple协议融合** + 重用Triple原有HTTP协议栈, 无需额外配置或新增端口,即可同时支持 HTTP/1、HTTP/2 和 HTTP/3 协议的访问。 +- **去中心化** + 可直接对外暴露 Rest API,不再依赖网关应用进行流量转发,从而提升性能,并降低因网关引发的稳定性风险。安全问题可通过应用内部扩展解决,这一实践已在淘宝内部的 MTOP 中得到验证。 +- **支持已有servlet设施** + 支持 Servlet API 和 Filter,用户可以重用现有基于 Servlet API 的安全组件。通过实现一个 Servlet Filter,即可集成 OAuth 和 Spring Security 等安全框架。 +- **多种方言** + 考虑到大部分用户习惯使用 SpringMVC 或 JAX-RS 进行 REST API 开发,Triple Rest 允许继续沿用这些方式定义服务,并支持大部分扩展和异常处理机制(具备原框架 80% 以上的功能)。对于追求轻量级的用户,可使用 + Basic 方言,Triple 的开箱即用 + REST 访问能力即基于此方言导出服务。 +- **扩展能力强** + 提供超过 20 个 扩展点,用户不仅可以轻松实现自定义方言,还能灵活定制参数获取、类型转换、错误处理等逻辑。 +- **开箱即用** + REST 能力开箱即用,只需启用 Triple 协议,即具备 REST 直接访问服务能力。 +- **高性能路由** + 路由部分采用优化的 [Radix Tree](https://github.com/apache/dubbo/blob/3.3/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/mapping/RadixTree.java) 和 + Zero Copy 技术,提升路由性能。 +- **OpenAPI无缝集成(TBD)** + 即将完成 OpenAPI 集成,开箱即用支持导出 OpenAPI Schema, 引入 Swagger 依赖可直接使用 Web UI 来进行服务测试。有了 OpenAPI Schema + 可使用 [Postman](https://www.postman.com/)、[Apifox](https://apifox.com/) 等API工具来管理和测试 + API,利用 OpenAPI 生态可轻松实现跨语言调用。未来会进一步支持 Schema First 的方式,先和前端团队一起定义 OpenAPI, 前端基于 OpenAPI 来生成调用代码和 Mock,后端基于 OpenAPI 来生成 Stub + 来开发服务,极大提升协同效率。 + + +### 示例 + + + +###### 示例代码 + +```java +package org.apache.dubbo.rest.demo; + +import org.apache.dubbo.remoting.http12.rest.Mapping; +import org.apache.dubbo.remoting.http12.rest.Param; + +// 服务接口 +public interface DemoService { + String hello(String name); + + @Mapping(path = "/hi", method = HttpMethods.POST) + String hello(User user, @Param(value = "c", type = ParamType.Header) int count); +} + +// 服务实现 +@DubboService +public class DemoServiceImpl implements DemoService { + @Override + public String hello(String name) { + return "Hello " + name; + } + + @Override + public String hello(User user, int count) { + return "Hello " + user.getTitle() + ". " + user.getName() + ", " + count; + } +} + +// 模型 +@Data +public class User { + private String title; + private String name; +} +``` + + + +###### 下载运行示例 + +```bash +# 获取示例代码 +git clone --depth=1 https://github.com/apache/dubbo-samples.git +cd dubbo-samples/2-advanced/dubbo-samples-triple-rest/dubbo-samples-triple-rest-basic +# 运行 +mvn spring-boot:run +``` + + + +###### curl测试 + +```bash +curl -v "http://127.0.0.1:8081/org.apache.dubbo.rest.demo.DemoService/hello?name=world" +# 输出如下 +#> GET /org.apache.dubbo.rest.demo.DemoService/hello?name=world HTTP/1.1 +#> +#< HTTP/1.1 200 OK +#< content-type: application/json +#< content-length: 13 +#< +#"Hello world" +# +# 代码讲解 +# 可以看到输出了 "Hello world" ,有双引号是因为默认输出 content-type 为 application/json +# 通过这个例子可以了解 Triple 默认将服务导出到 /{serviceInterface}/{methodName}路径,并支持通过url方式传递参数 + +curl -v -H "c: 3" -d 'name=Yang' "http://127.0.0.1:8081/org.apache.dubbo.rest.demo.DemoService/hi.txt?title=Mr" +# 输出如下 +#> POST /org.apache.dubbo.rest.demo.DemoService/hi.txt?title=Mr HTTP/1.1 +#> c: 3 +#> Content-Length: 9 +#> Content-Type: application/x-www-form-urlencoded +#> +#< HTTP/1.1 200 OK +#< content-type: text/plain +#< content-length: 17 +#< +#Hello Mr. Yang, 3 +# +# 代码讲解 +# 可以看到输出 Hello Mr. Yang, 3 ,没有双引号是因为通过指定后缀 txt 的方式要求用 text/plain 输出 + #通过这个例子可以了解如何通过 Mapping 注解来定制路径,通过 Param 注解来定制参数来源,并支持通过 post body 或 url方式传递参数 +``` + + + +### 详情文档 + +请访问用户手册:[Tripe Rest Manual](../tripe-rest-manual/) + + +## 支持Servlet接入 + +在3.3版本中,可复用Spring Boot已有servlet监听端口来接入 HTTP 流量, 无需Netty监听新端口,简化部署,降低维护成本。通过减少对外部端口的依赖,有助于轻松通过企业防火墙和网关,简化网络部署,增强企业级应用的可维护性和安全性。 + + +### 示例 + + + +###### 下载运行示例 + +```bash +# 获取样例代码 +git clone --depth=1 https://github.com/apache/dubbo-samples.git +cd dubbo-samples/2-advanced/dubbo-samples-triple-servlet +# 直接运行 +mvn spring-boot:run +``` + + + +###### curl测试 + +```shell +curl --http2-prior-knowledge -v 'http://localhost:50052/org.apache.dubbo.demo.GreeterService/sayHelloAsync?request=world' +# 输出如下 +#* [HTTP/2] [1] OPENED stream for http://localhost:50052/org.apache.dubbo.demo.GreeterService/sayHelloAsync?request=world +#* [HTTP/2] [1] [:method: GET] +#* [HTTP/2] [1] [:scheme: http] +#* [HTTP/2] [1] [:authority: localhost:50052] +#* [HTTP/2] [1] [:path: /org.apache.dubbo.demo.GreeterService/sayHelloAsync?request=world] +#> +#* Request completely sent off +#< HTTP/2 200 +#< content-type: application/json +#< date: Sun, 25 Aug 2024 03:38:12 GMT +#< +#"Hello world" +``` + + + +### 详情文档 + +请访问:[how-to-enable-servlet-support-for-triple](https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-triple-servlet#how-to-enable-servlet-support-for-triple) +了解如何配置并启用 servlet 支持 + + +## 支持HTTP/3协议 + + + +### 特性 + +在3.3版本中,triple实现了对HTTP/3协议的支持,rpc 请求和 rest 请求均可通过 HTTP/3 协议传输,使用 HTTP/3 可以带来一下好处: + +- **提升性能** + 支持 HTTP/3 后,利用 QUIC 协议降低延迟,加快请求响应速度,特别是在高延迟或复杂网络环境中,能够显著提升服务的整体性能。 +- **增强可靠性** + HTTP/3 通过多路复用和连接迁移避免队头阻塞,即使在网络状况不佳时,也能保持连接的稳定性,确保服务的可靠交付。 +- **提高安全性** + HTTP/3 强制要求 TLS1.3 加密,相比传统HTTP/2 可选加密,提供了更安全的通信保障。 +- **适应弱网络环境** + 在高丢包率或带宽不稳定的情况下,HTTP/3 能够维持较高地连接质量和服务性能,提升在弱网络环境中的性能。 + +由于 HTTP/3 基于 QUIC 协议(UDP),可能会被防火墙或网关阻止。因此,triple 实现了 HTTP/3 协商能力并默认启用。连接首先通过 HTTP/2 建立,如果成功且服务端返回表示支持 HTTP/3 +的[Alt-Svc](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Alt-Svc) 头,客户端将自动切换到HTTP/3 + + +### 示例 + + + +###### 下载运行示例 + +```bash +# 获取样例代码 +git clone --depth=1 https://github.com/apache/dubbo-samples.git +cd dubbo-samples/2-advanced/dubbo-samples-triple-http3 +# 直接运行 +mvn spring-boot:run +``` + + + +###### curl测试 + +请注意,curl 需要升级到支持 HTTP/3 的新版本, 参见:[https://curl.se/docs/http3.html](https://curl.se/docs/http3.html) + +```shell + +curl --http3 -vk 'https://localhost:50052/org.apache.dubbo.demo.GreeterService/sayHelloAsync?request=world' +# 输出如下 +#* QUIC cipher selection: TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_CCM_SHA256 +#* Skipped certificate verification +#* using HTTP/3 +#* [HTTP/3] [0] OPENED stream for https://localhost:50052/org.apache.dubbo.demo.GreeterService/sayHelloAsync?request=world +#* [HTTP/3] [0] [:method: GET] +#* [HTTP/3] [0] [:scheme: https] +#* [HTTP/3] [0] [:authority: localhost:50052] +#* [HTTP/3] [0] [:path: /org.apache.dubbo.demo.GreeterService/sayHelloAsync?request=world] +#> +#* Request completely sent off +#< HTTP/3 200 +#< content-type: application/json +#< +#"Hello world" +``` + + + +### 性能对比 + +#### 丢包率对 QPS 的影响 + +![http3-qps.jpg](/imgs/v3/manual/java/protocol/http3-qps.jpg) + +#### 丢包率对 RT 的影响 + +![http3-rt.jpg](/imgs/v3/manual/java/protocol/http3-rt.jpg) + + + +### 架构图 + +![http3-arch.jpg](/imgs/v3/manual/java/protocol/http3-arch.jpg) + +### 详情文档 + +请访问:[how-to-enable-http3-support-for-triple](https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-triple-http3#how-to-enable-http3-support-for-triple) +了解如何配置并启用 HTTP/3 支持 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/triple.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/triple.md new file mode 100644 index 000000000000..5fccb7b7b3a8 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/triple.md @@ -0,0 +1,318 @@ +--- +aliases: + - /zh/docs3-v2/java-sdk/reference-manual/protocol/triple/overview/ + - /zh-cn/docs3-v2/java-sdk/reference-manual/protocol/triple/overview/ + - /zh-cn/overview/mannual/java-sdk/reference-manual/protocol/grpc/ + - /zh-cn/overview/mannual/java-sdk/reference-manual/protocol/triple/guide/ + - /zh-cn/overview/mannual/java-sdk/reference-manual/protocol/triple/migration + - /zh-cn/overview/mannual/java-sdk/reference-manual/protocol/triple/overview/ + - /zh-cn/overview/mannual/java-sdk/upgrades-and-compatibility/protobufinterface/ + - /zh-cn/overview/mannual/java-sdk/tasks/gateway/triple/ +description: "本文 triple 在 dubbo java 实现中的一些具体细节,配置方式、性能指标等" +linkTitle: triple +title: 协议概述 +type: docs +weight: 2 +--- + +请参考文档其他部分了解 [triple 协议规范规范](/zh-cn/overview/reference/protocols/triple-spec/) 和 [基本使用方式](/zh-cn/overview/mannual/java-sdk/tasks/protocols/triple/)。本文只展开 triple 协议 Java 实现中的一些具体细节内容。 + +## 编程模式 +使用 triple 协议时,开发者可以使用 `Java Interface`、`Protobuf(IDL)` 两种方式定义 RPC 服务,两种服务定义方式的协议能力是对等的,仅影响开发者的编程体验、序列化方式,具体选用那种开发模式,取决于使用者的业务背景。 + +### Java接口 +**适合于 Dubbo 老用户、没有跨语言诉求的开发团队,具备学习成本低的优势,[Dubbo2 老用户可以零成本切换到该协议]()**。 + +服务定义范例: +```java +public interface DemoService { + String sayHello(String name); +} +``` + +这种模式下,序列化方式可以选用 Hessian、JSON、Kryo、JDK、自定义扩展等任意编码协议。在使用体验上,可以说与老版本 dubbo 协议没有任何区别,只需要改一个 protocol 配置项即可,因此对于 dubbo 协议迁移到 triple 也会更平滑。 + +请通过【进阶学习 - 通信协议】查看 [java Interface + Triple 协议的具体使用示例]()。 + +### Protobuf + +使用 Protobuf(IDL) 的方式定义服务,**适合于当前或未来有跨语言诉求的开发团队,同一份 IDL 服务可同时用于 Java/Go/Node.js 等多语言微服务开发,劣势是学习成本较高**。 + +```Protobuf +syntax = "proto3"; +option java_multiple_files = true; +package org.apache.dubbo.springboot.demo.idl; + +message GreeterRequest { + string name = 1; +} +message GreeterReply { + string message = 1; +} + +service Greeter{ + rpc greet(GreeterRequest) returns (GreeterReply); +} +``` + +通过 [Dubbo 提供的 protoc 编译插件](/zh-cn/overview/mannual/java-sdk/tasks/protocols/triple/idl/#生成的代码无法编译),将以上 IDL 服务定义预编译为相关 stub 代码,其中就包含 Dubbo 需要的 Interface 接口定义,因此在后续编码上区别并不大,只不过相比于前面的用户自定义 Java Interface 模式,这里由插件自动帮我们生成 Interface 定义。 + +```java +// Generated by dubbo protoc plugin +public interface Greeter extends org.apache.dubbo.rpc.model.DubboStub { + String JAVA_SERVICE_NAME = "org.apache.dubbo.springboot.demo.idl.Greeter"; + String SERVICE_NAME = "org.apache.dubbo.springboot.demo.idl.Greeter"; + + org.apache.dubbo.springboot.demo.idl.GreeterReply greet(org.apache.dubbo.springboot.demo.idl.GreeterRequest request); + // more generated codes here... +} +``` + +Protobuf 模式支持序列化方式有 Protobuf Binary、Protobuf JSON 两种模式。最后,请通过【进阶学习 - 通信协议】查看 [Protobuf (IDL) + Triple 协议的具体使用示例]()。 + +#### 3. 我该使用哪种编程模式,如何选择? + +| | 是 | 否 | +| --- | --- | --- | +| 公司的业务是否有用 Java 之外的其他语言,跨语言互通的场景是不是普遍? | Protobuf | Java 接口 | +| 公司里的开发人员是否熟悉 Protobuf,愿意接受 Protobuf 的额外成本吗? | Protobuf | Java 接口 | +| 是否有标准 gRPC 互通诉求? | Protobuf | Java 接口 | +| 是不是 Dubbo2 老用户,想平滑迁移到 triple 协议? | Java 接口 | Protobuf | + +## Streaming流式通信 +#### 流实现原理 + +`Triple`协议的流模式 + +- 从协议层来说,`Triple` 是建立在 `HTTP2` 基础上的,所以直接拥有所有 `HTTP2` 的能力,故拥有了分 `streaming` 和全双工的能力。 + +- 框架层来说,`org.apache.dubbo.common.stream.StreamObserver` 作为流的接口提供给用户,用于入参和出参提供流式处理。框架在收发 stream data 时进行相应的接口调用, 从而保证流的生命周期完整。 + +#### 适用场景 +Streaming 是 Dubbo3 新提供的一种调用类型,在以下场景时建议使用流的方式: + +- 接口需要发送大量数据,这些数据无法被放在一个 RPC 的请求或响应中,需要分批发送,但应用层如果按照传统的多次 RPC 方式无法解决顺序和性能的问题,如果需要保证有序,则只能串行发送 +- 流式场景,数据需要按照发送顺序处理, 数据本身是没有确定边界的 +- 推送类场景,多个消息在同一个调用的上下文中被发送和处理 + +Stream 分为以下三种。 + +##### SERVER_STREAM(服务端流) +服务端流式 RPC 类似于 Unary RPC,不同之处在于服务端会响应客户端的请求并返回消息流。在发送完所有消息后(通常是多条消息),服务端会发送状态信息(状态代码和可选状态消息)和可选的尾部元数据给客户端,这写状态信息发送完后服务器端流就结束了。一旦客户端通过 StreamObserver 接收到了以上所有了服务器消息,流就完成了。 + +服务端流 + +##### CLIENT_STREAM(客户端流) +客户端流式 RPC 类似于 Unary RPC,不同之处在于客户端向服务器发送消息流(通常包含多条消息)而不是单个消息。服务器以单个消息(以及其状态详细信息和可选的尾部元数据)进行响应 - 通常但不一定是在接收到所有客户端消息之后。 + +客户端流 + +##### BIDIRECTIONAL_STREAM(双向流) +在双向流 RPC 中,客户端发起方法调用,服务端则接收客户端调用中的元数据、方法名称和截止日期,这样就启动了一次完整的双向流通道。服务器可以选择返回其初始元数据,或者等待客户端开始流式传输消息。 + +客户端和服务器端的流处理是特定于应用程序的。由于这两个流是独立的,客户端和服务器可以按任何顺序读取和写入消息。例如,服务器可以等到收到客户端的所有消息后再写消息,或者服务器和客户端可以玩“乒乓球”——服务器收到一个请求,然后发回一个响应,然后客户端根据响应发送另一个请求等等。 + +双向流 + +{{% alert title="流的语义保证" color="primary" %}} +- 提供消息边界,可以方便地对消息单独处理 +- 严格有序,发送端的顺序和接收端顺序一致 +- 全双工,发送不需要等待 +- 支持取消和超时 +{{% /alert %}} + +关于 Streaming 的具体使用示例,请参见 [Streaming 流式通信](../triple/streaming/)。 + +## REST 支持 +通过为 Java 接口增加注解,可以发布 rest 风格的 triple 服务,可在这里查看 具体代码示例 + +{{% alert title="流的语义保证" color="info" %}} +目前 rest 协议仅支持 `Java 接口` 服务定义模式,相比于 dubbo 和 triple 协议,rest 场景下我们需要为 Interface 增加注解,支持 Spring MVC、JAX_RS 两种注解。 +{{% /alert %}} + +如果你记得 triple 协议原生支持 cURL 访问,即类似 `org.apache.dubbo.springboot.demo.idl.Greeter/greet` 的访问模式。通过增加以上注解后,即可为 triple 服务额外增加 REST 风格访问支持,如 `demo/greet` 的 GET 请求。 + +### Spring Web注解 +Spring MVC 服务定义范例: +```java +@RestController +@RequestMapping("/demo") +public interface DemoService { + @GetMapping(value = "/hello") + String sayHello(); +} +``` + +### JAX-RS注解 +JAX-RS 服务定义范例: +```java +@Path("/demo") +public interface DemoService { + @GET + @Path("/hello") + String sayHello(); +} +``` + +## 异常类型传递 +Provider 端产生的业务异常需要作为响应值返回给 Consumer 客户端,消费端可以使用 `try catch` 捕获可能抛出的异常: + +```java +try { + greeterProxy.echo(REQUEST_MSG); +} catch (YourCustomizedException e) { + e.printStackTrace(); + } catch (RpcException e) { + e.printStackTrace(); +} +``` + +Dubbo 框架会在 provider 侧根据如下流程发送异常类型响应,不是所有业务异常都能原样返回,对于无法处理的异常类型,都会被框架封装成 `RpcException` 类型返回: + +![triple-exception](/imgs/blog/2022/12/19/triple/2.jpeg) + +## 附录 +### Protobuf与Java原生数据类型对比 + +对于计划从 Java 接口完全迁移到 Protobuf 的用户而言,这里的信息可供参考,用以了解类型迁移可能面临的限制,Protobuf 描述语言是否能完全描述 Java 数据类型。 + +本文对比了Protobuf和Java Interface这2种IDL的差异,帮助Dubbo协议开发者了解Protobuf,为后续转到Triple协议和Grpc协议做铺垫。 + +#### 1. 数据类型 + +##### 1.1. 基本类型 + +| ptoto类型 | java类型 | +| ---- | ---- | +double | double +float | float +int32 | int +int64 | long +uint32 | int[注] +uint64 | long[注] +sint32 | int +sint64 | long +fixed32 | int[注] +fixed64 | long[注] +sfixed32 | int +sfixed64 | long +bool | boolean +string | String +bytes | ByteString + +{{% alert title="注意" color="primary" %}} +在Java中,无符号的32位和64位整数使用它们的有符号对数来表示,顶部位只存储在符号位中。 +{{% /alert %}} + +#### 2. 复合类型 + +##### 2.1. 枚举 + +* 原始pb代码 + +```java. +enum TrafficLightColor { + TRAFFIC_LIGHT_COLOR_INVALID = 0; + TRAFFIC_LIGHT_COLOR_UNSET = 1; + TRAFFIC_LIGHT_COLOR_GREEN = 2; + TRAFFIC_LIGHT_COLOR_YELLOW = 3; + TRAFFIC_LIGHT_COLOR_RED = 4; +} +``` + +* 生成的java代码 + +![image](/imgs/docs/advanced/protobufinterface/124234531-b96c2c80-db46-11eb-8155-a77dbe059f07.png) + +> 枚举是常量,因此采用大写 +##### 2.2. 数组 + +* 原始pb代码 + +```java +message VipIDToRidReq { + repeated uint32 vipID = 1; +} +``` + +* 生成的java代码 + +![image](/imgs/docs/advanced/protobufinterface/124234564-c4bf5800-db46-11eb-94fc-a056af6089cb.png) + +> 底层实际上是1个ArrayList +##### 2.3. 集合 + +PB不支持无序、不重复的集合,只能 ``借用数组实现``,需要 ``自行去重``。 + +##### 2.4. 字典 + +* 原始pb代码 + +```java +message BatchOnlineRes { + map onlineMap = 1;//在线状态 +} +``` + +* 生成的java代码 + +![image](/imgs/docs/advanced/protobufinterface/124234654-e4568080-db46-11eb-9700-b30022ebee21.png) + +##### 2.5. 嵌套 + +* 原始pb代码 + +```java +message BatchAnchorInfoRes { + map list = 1; //用户信息map列表 +} +/* +* 对应接口的功能: 批量或单个获取用户信息 +*/ +message AnchorInfo { + uint32 ownerUid = 1 [json_name="uid"]; //用户id + string nickName = 2 [json_name="nn"]; //用户昵称 + string smallAvatar = 3 [json_name="savt"]; //用户头像全路径-小 + string middleAvatar = 4 [json_name="mavt"]; //用户头像全路径-中 + string bigAvatar = 5 [json_name="bavt"]; //用户头像全路径-大 + string avatar = 6 [json_name="avt"]; //用户头像 +} +``` + +* 生成的java代码 + +![image](/imgs/docs/advanced/protobufinterface/124234723-f89a7d80-db46-11eb-82d0-a8aee5322098.png) + +#### 3. 字段默认值 + +* 对于字符串,默认值为空字符串。 +* 对于字节,默认值为空字节。 +* 对于bools,默认值为false。 +* 对于数字类型,默认值为零。 +* 对于枚举,默认值为第一个定义的枚举值,它必须为0。 +* 对于消息字段,未设置字段。 它的确切值是语言相关的。 有关详细信息,请参阅生成的代码指南。 + +#### 4. 整体结构 + +| Feature | Java Interface | Protobuf | 备注 | +| ---- | ---- | ---- | ---- | +| 方法重载 | √ | × | | +| 泛型/模板化 | √ | × | | +| 方法继承 | √ | × | | +| 嵌套定义 | √ | 部分支持 | PB仅支持message和enum嵌套 | +| import文件 | √ | √ | | +| 字段为null | √ | × | | +| 多个入参 | √ | × | PB仅支持单入参 | +| 0个入参 | √ | × | PB必须有入参 | +| 0个出参 | √ | × | PB必须有出参 | +| 入参/出参为抽象类 | √ | × | PB的入参/出参必须为具象类 | +| 入参/出参为接口 | √ | × | PB的入参/出参必须为具象类 | +| 入参/出参为基础类型 | √ | × | PB的入参/出参必须为结构体 | + +#### 5. 社区资料 +* 社区主页地址:https://developers.google.cn/protocol-buffers/ +* 社区开源地址:https://github.com/google/protobuf +* 相关jar的maven:https://search.maven.org/search?q=com.google.protobuf + + + diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/triple.md.bak b/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/triple.md.bak new file mode 100644 index 000000000000..40727de64178 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/triple.md.bak @@ -0,0 +1,170 @@ +--- +aliases: + - /zh/docs3-v2/java-sdk/reference-manual/protocol/triple/overview/ + - /zh-cn/docs3-v2/java-sdk/reference-manual/protocol/triple/overview/ +description: 协议概述 +linkTitle: triple +title: 协议概述 +type: docs +weight: 2 +--- + + +## 概述说明 + +`Triple` 协议的格式和原理请参阅 [RPC 通信协议](/zh-cn/docs/concepts/rpc-protocol/) + +根据 Triple 设计的目标,`Triple` 协议有以下优势 + +- 具备跨语言交互的能力,传统的多语言多 SDK 模式和 Mesh 化跨语言模式都需要一种更通用易扩展的数据传输协议。 +- 提供更完善的请求模型,除了支持传统的 Request/Response 模型(Unary 单向通信),还支持 Stream(流式通信) 和 Bidirectional(双向通信)。 +- 易扩展、穿透性高,包括但不限于 Tracing / Monitoring 等支持,也应该能被各层设备识别,网关设施等可以识别数据报文,对 Service Mesh 部署友好,降低用户理解难度。 +- 完全兼容 grpc,客户端/服务端可以与原生grpc客户端打通。 +- 可以复用现有 grpc 生态下的组件, 满足云原生场景下的跨语言、跨环境、跨平台的互通需求。 + +当前使用其他协议的 Dubbo 用户,框架提供了兼容现有序列化方式的迁移能力,在不影响线上已有业务的前提下,迁移协议的成本几乎为零。 + +### GRPC +需要新增对接 grpc 服务的 Dubbo 用户,可以直接使用 Triple 协议来实现打通,不需要单独引入 grpc client 来完成,不仅能保留已有的 Dubbo 易用性,也能降低程序的复杂度和开发运维成本,不需要额外进行适配和开发即可接入现有生态。 + +### 网关接入 +对于需要网关接入的 Dubbo 用户,Triple 协议提供了更加原生的方式,让网关开发或者使用开源的 grpc 网关组件更加简单。网关可以选择不解析 payload ,在性能上也有很大提高。在使用 Dubbo 协议时,语言相关的序列化方式是网关的一个很大痛点,而传统的 HTTP 转 Dubbo 的方式对于跨语言序列化几乎是无能为力的。同时,由于 Triple 的协议元数据都存储在请求头中,网关可以轻松的实现定制需求,如路由和限流等功能。 + + +## 常见问题 + +### Q1 +protobuf 类找不到 + +由于 Triple 协议底层需要依赖 protobuf 协议进行传输,即使定义的服务接口不使用 protobuf 也需要在环境中引入 protobuf 的依赖。 + +```xml + + com.google.protobuf + protobuf-java + 3.19.4 + +``` + + + + + +Dubbo3 提供了 Triple(Dubbo3)、Dubbo2 协议,这是 Dubbo 框架的原生协议。除此之外,Dubbo3 也对众多第三方协议进行了集成,并将它们纳入 Dubbo 的编程与服务治理体系, +包括 gRPC、Thrift、JsonRPC、Hessian2、REST 等。以下重点介绍 Triple 与 Dubbo2 协议。 + +## 协议说明 + +Triple 协议是 Dubbo3 推出的主力协议。Triple 意为第三代,通过 Dubbo1.0/ Dubbo2.0 两代协议的演进,以及云原生带来的技术标准化浪潮,Dubbo3 新协议 Triple 应运而生。 + +### RPC 协议 + +协议是 RPC 的核心,它规范了数据在网络中的传输内容和格式。除必须的请求、响应数据外,通常还会包含额外控制数据,如单次请求的序列化方式、超时时间、压缩方式和鉴权信息等。 + +协议的内容包含三部分 +- 数据交换格式: 定义 RPC 的请求和响应对象在网络传输中的字节流内容,也叫作序列化方式 +- 协议结构: 定义包含字段列表和各字段语义以及不同字段的排列方式 +- 协议通过定义规则、格式和语义来约定数据如何在网络间传输。一次成功的 RPC 需要通信的两端都能够按照协议约定进行网络字节流的读写和对象转换。如果两端对使用的协议不能达成一致,就会出现鸡同鸭讲,无法满足远程通信的需求。 + +![协议选择](/imgs/v3/concepts/triple-protocol.png) + +RPC 协议的设计需要考虑以下内容: +- 通用性: 统一的二进制格式,跨语言、跨平台、多传输层协议支持 +- 扩展性: 协议增加字段、升级、支持用户扩展和附加业务元数据 +- 性能:As fast as it can be +- 穿透性:能够被各种终端设备识别和转发:网关、代理服务器等 + 通用性和高性能通常无法同时达到,需要协议设计者进行一定的取舍。 + +### HTTP/1.1 协议 + +比于直接构建于 TCP 传输层的私有 RPC 协议,构建于 HTTP 之上的远程调用解决方案会有更好的通用性,如WebServices 或 REST 架构,使用 HTTP + JSON 可以说是一个事实标准的解决方案。 + +选择构建在 HTTP 之上,有两个最大的优势: + +- HTTP 的语义和可扩展性能很好的满足 RPC 调用需求。 +- 通用性,HTTP 协议几乎被网络上的所有设备所支持,具有很好的协议穿透性。 + +但也存在比较明显的问题: + +- 典型的 Request – Response 模型,一个链路上一次只能有一个等待的 Request 请求。会产生 HOL。 +- Human Readable Headers,使用更通用、更易于人类阅读的头部传输格式,但性能相当差 +- 无直接 Server Push 支持,需要使用 Polling Long-Polling 等变通模式 + +### gRPC 协议 +上面提到了在 HTTP 及 TCP 协议之上构建 RPC 协议各自的优缺点,相比于 Dubbo 构建于 TCP 传输层之上,Google 选择将 gRPC 直接定义在 HTTP/2 协议之上。 +gRPC 的优势由HTTP2 和 Protobuf 继承而来。 + +- 基于 HTTP2 的协议足够简单,用户学习成本低,天然有 server push/ 多路复用 / 流量控制能力 +- 基于 Protobuf 的多语言跨平台二进制兼容能力,提供强大的统一跨语言能力 +- 基于协议本身的生态比较丰富,k8s/etcd 等组件的天然支持协议,云原生的事实协议标准 + +但是也存在部分问题 + +- 对服务治理的支持比较基础,更偏向于基础的 RPC 功能,协议层缺少必要的统一定义,对于用户而言直接用起来并不容易。 +- 强绑定 protobuf 的序列化方式,需要较高的学习成本和改造成本,对于现有的偏单语言的用户而言,迁移成本不可忽视 + +### Triple 协议 +最终我们选择了兼容 gRPC ,以 HTTP2 作为传输层构建新的协议,也就是 Triple。 + +容器化应用程序和微服务的兴起促进了针对负载内容优化技术的发展。 客户端中使用的传统通信协议( RESTFUL或其他基于 HTTP 的自定义协议)难以满足应用在性能、可维护性、扩展性、安全性等方便的需求。一个跨语言、模块化的协议会逐渐成为新的应用开发协议标准。自从 2017 年 gRPC 协议成为 CNCF 的项目后,包括 k8s、etcd 等越来越多的基础设施和业务都开始使用 gRPC 的生态,作为云原生的微服务化框架, Dubbo 的新协议也完美兼容了 gRPC。并且,对于 gRPC 协议中一些不完善的部分, Triple 也将进行增强和补充。 + +那么,Triple 协议是否解决了上面我们提到的一系列问题呢? + +- 性能上: Triple 协议采取了 metadata 和 payload 分离的策略,这样就可以避免中间设备,如网关进行 payload 的解析和反序列化,从而降低响应时间。 +- 路由支持上,由于 metadata 支持用户添加自定义 header ,用户可以根据 header 更方便的划分集群或者进行路由,这样发布的时候切流灰度或容灾都有了更高的灵活性。 +- 安全性上,支持双向TLS认证(mTLS)等加密传输能力。 +- 易用性上,Triple 除了支持原生 gRPC 所推荐的 Protobuf 序列化外,使用通用的方式支持了 Hessian / JSON 等其他序列化,能让用户更方便的升级到 Triple 协议。对原有的 Dubbo 服务而言,修改或增加 Triple 协议 只需要在声明服务的代码块添加一行协议配置即可,改造成本几乎为 0。 + +## 最终选择协议 + +![Triple 协议通信方式](/imgs/v3/concepts/triple.png) + +现状 + +- 1、完整兼容grpc、客户端/服务端可以与原生grpc客户端打通 + +- 2、目前已经经过大规模生产实践验证,达到生产级别 + +特点与优势 + +- 1、具备跨语言互通的能力,传统的多语言多 SDK 模式和 Mesh 化跨语言模式都需要一种更通用易扩展的数据传输格式。 + +- 2、提供更完善的请求模型,除了支持传统的 Request/Response 模型(Unary 单向通信),还支持 Stream(流式通信) 和 Bidirectional(双向通信)。 + +- 3、易扩展、穿透性高,包括但不限于 Tracing / Monitoring 等支持,也应该能被各层设备识别,网关设施等可以识别数据报文,对 Service Mesh 部署友好,降低用户理解难度。 + +- 4、多种序列化方式支持、平滑升级 + +- 5、支持 Java 用户无感知升级,不需要定义繁琐的 IDL 文件,仅需要简单的修改协议名便可以轻松升级到 Triple 协议 + +### Triple 协议内容介绍 + +基于 grpc 协议进行进一步扩展 + +- Service-Version → "tri-service-version" {Dubbo service version} +- Service-Group → "tri-service-group" {Dubbo service group} +- Tracing-ID → "tri-trace-traceid" {tracing id} +- Tracing-RPC-ID → "tri-trace-rpcid" {_span id _} +- Cluster-Info → "tri-unit-info" {cluster infomation} + +其中 Service-Version 跟 Service-Group 分别标识了 Dubbo 服务的 version 跟 group 信息,因为grpc的 path 申明了 service name 跟 method name,相比于 Dubbo 协议,缺少了version 跟 group 信息;Tracing-ID、Tracing-RPC-ID 用于全链路追踪能力,分别表示 tracing id 跟 span id 信息;Cluster-Info 表示集群信息,可以使用其构建一些如集群划分等路由相关的灵活的服务治理能力。 + +### Triple Streaming + +Triple协议相比传统的unary方式,多了目前提供的Streaming RPC的能力 + +- Streaming 用于什么场景呢? + +在一些大文件传输、直播等应用场景中, consumer或provider需要跟对端进行大量数据的传输,由于这些情况下的数据量是非常大的,因此是没有办法可以在一个RPC的数据包中进行传输,因此对于这些数据包我们需要对数据包进行分片之后,通过多次RPC调用进行传输,如果我们对这些已经拆分了的RPC数据包进行并行传输,那么到对端后相关的数据包是无序的,需要对接收到的数据进行排序拼接,相关的逻辑会非常复杂。但如果我们对拆分了的RPC数据包进行串行传输,那么对应的网络传输RTT与数据处理的时延会是非常大的。 + +为了解决以上的问题,并且为了大量数据的传输以流水线方式在consumer与provider之间传输,因此Streaming RPC的模型应运而生。 + +通过Triple协议的Streaming RPC方式,会在consumer跟provider之间建立多条用户态的长连接,Stream。同一个TCP连接之上能同时存在多个Stream,其中每条Stream都有StreamId进行标识,对于一条Stream上的数据包会以顺序方式读写。 + + +{{% alert title="总结" color="info" %}} +在API领域,最重要的趋势是标准化技术的崛起。Triple 协议是 Dubbo3 推出的主力协议。它采用分层设计,其数据交换格式基于Protobuf (Protocol Buffers) 协议开发,具备优秀的序列化/反序列化效率,当然还支持多种序列化方式,也支持众多开发语言。在传输层协议,Triple 选择了 HTTP/2,相较于 HTTP/1.1,其传输效率有了很大提升。此外HTTP/2作为一个成熟的开放标准,具备丰富的安全、流控等能力,同时拥有良好的互操作性。Triple 不仅可以用于Server端服务调用,也可以支持浏览器、移动App和IoT设备与后端服务的交互,同时 Triple协议无缝支持 Dubbo3 的全部服务治理能力。 + +在Cloud Native的潮流下,跨平台、跨厂商、跨环境的系统间互操作性的需求必然会催生基于开放标准的RPC技术,而gRPC顺应了历史趋势,得到了越来越广泛地应用。在微服务领域,Triple协议的提出与落地,是 Dubbo3 迈向云原生微服务的一大步。 +{{% /alert %}} + diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/triple/_index.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/triple/_index.md deleted file mode 100755 index fbd9fd793654..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/triple/_index.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/reference-manual/protocol/triple/ - - /zh-cn/docs3-v2/java-sdk/reference-manual/protocol/triple/ - - /zh/overview/what/ecosystem/protocol/triple/ - - /zh/docs3-v2/java-sdk/concepts-and-architecture/triple/ - - /zh-cn/docs3-v2/java-sdk/concepts-and-architecture/triple/ - - zh-cn/overview/mannual/java-sdk/concepts-and-architecture/triple/ -description: Triple协议 -linkTitle: Triple协议 -title: Triple协议 -type: docs -weight: 3 ---- - -## 协议说明 -Triple 是 Dubbo3 提出的基于 HTTP 的开放协议,旨在解决 Dubbo2 私有协议带来的互通性问题,Triple 基于 gRPC 和 gRPC-Web 设计而来,保留了两者的优秀设计,Triple 做到了完全兼容 gRPC 协议,并可同时运行在 HTTP/1 和 HTTP/2 之上。 - -* 相比于原有 Dubbo2 协议,Triple 有以下优势: - 1. 原生和 gRPC 协议互通。打通 gRPC 生态,降低从 gRPC 至 Dubbo 的迁移成本。 - 2. 增强多语言生态。避免因 CPP/C#/RUST 等语言的 Dubbo SDK 能力不足导致业务难以选型适配的问题。 - 3. 网关友好。网关无需参与序列化,方便用户从传统的 HTTP 转泛化 Dubbo 调用网关升级至开源或云厂商的 Ingress 方案。 - 4. 完善的异步和流式支持。带来从底层协议到上层业务的性能提升,易于构建全链路异步以及严格保证消息顺序的流式服务。 - - -* 相比于 gRPC 协议,Triple 有以下优势: - 1. 协议内置支持 HTTP/1,可以用 curl、浏览器直接访问你的 gRPC 服务 - 2. 保持性能与 grpc-java 在同一水平的同时,实现上更轻量、简单,协议部分只有几千行代码 - 3. 不绑定 IDL,支持 Java Interface 定义服务 - 4. 保持与官方 gRPC 库的 100% 兼容性的同时,与 Dubbo 的微服务治理体系无缝融合 - -更多关于 Triple 协议设计与协议规范,请参考 [triple协议规范](/zh-cn/overview/reference/protocols/triple/)。 -**目前 Java 和 Go 的 Dubbo SDK 已全面支持 Triple 协议。** 在阿里巴巴,Triple 协议广泛用于跨环境、跨语言、跨生态互通,已有数十万容器生产级使用。 - -## 使用方式 -Java SDK 支持 [IDL 生成 Stub](/zh-cn/overview/mannual/java-sdk/quick-start/idl) -和 [Java Interface](/zh-cn/overview/mannual/java-sdk/quick-start/idl) 两种方式,多语言、生态互通、流式需求推荐使用 IDL 方式,现有服务平滑升级推荐使用 -Interface 方式。 - -- Dubbo2 老用户如何从现有协议升级至 Triple(TBD) -- 新用户或业务参考 [Dubbo3 Triple Quick Start](/zh-cn/overview/mannual/java-sdk/quick-start/idl/) -- 深入了解 Triple 协议: [Dubbo3 Triple 协议设计与原理](https://github.com/apache/dubbo-awesome/blob/master/proposals/D0-triple.md) diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/triple/guide.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/triple/guide.md deleted file mode 100644 index c14bbe9a1d02..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/triple/guide.md +++ /dev/null @@ -1,290 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/reference-manual/protocol/triple/guide/ - - /zh-cn/docs3-v2/java-sdk/reference-manual/protocol/triple/guide/ -description: 协议使用方式 -linkTitle: 协议使用方式 -title: 协议使用方式 -type: docs -weight: 2 ---- - - - - - - -Triple 协议是 Dubbo3 的主力协议,完整兼容 gRPC over HTTP/2,并在协议层面扩展了负载均衡和流量控制相关机制。本文档旨在指导用户正确的使用 Triple 协议。 - -在开始前,需要决定服务使用的序列化方式,如果为新服务,推荐使用 protobuf 作为默认序列化,在性能和跨语言上的效果都会更好。如果是原有服务想进行协议升级,Triple 协议也已经支持其他序列化方式,如 Hessian / JSON 等 - - - -### Protobuf 方式 - -1. 编写 IDL 文件 -```protobuf - syntax = "proto3"; - - option java_multiple_files = true; - option java_package = "org.apache.dubbo.hello"; - option java_outer_classname = "HelloWorldProto"; - option objc_class_prefix = "HLW"; - - package helloworld; - - // The request message containing the user's name. - message HelloRequest { - string name = 1; - } - - // The response message containing the greetings - message HelloReply { - string message = 1; - } -``` - -2. 添加编译 protobuf 的 extension 和 plugin (以 maven 为例) -```xml - - - kr.motd.maven - os-maven-plugin - 1.6.1 - - - - - org.xolstice.maven.plugins - protobuf-maven-plugin - 0.6.1 - - com.google.protobuf:protoc:3.7.1:exe:${os.detected.classifier} - triple-java - build/generated/source/proto/main/java - - - - - compile - test-compile - - - - - -``` - -3. 构建/ 编译生成 protobuf Message 类 -```shell -mvn clean install -``` - -### Unary 方式 - -4. 编写 Java 接口 -```java - import org.apache.dubbo.hello.HelloReply; - import org.apache.dubbo.hello.HelloRequest; - - public interface IGreeter { - /** - *
-         *  Sends a greeting
-         * 
- */ - HelloReply sayHello(HelloRequest request); - - } -``` - -5. 创建 Provider -```java - public static void main(String[] args) throws InterruptedException { - ServiceConfig service = new ServiceConfig<>(); - service.setInterface(IGreeter.class); - service.setRef(new IGreeter1Impl()); - // 这里需要显示声明使用的协议为triple - service.setProtocol(new ProtocolConfig(CommonConstants.TRIPLE, 50051)); - service.setApplication(new ApplicationConfig("demo-provider")); - service.setRegistry(new RegistryConfig("zookeeper://127.0.0.1:2181")); - service.export(); - System.out.println("dubbo service started"); - new CountDownLatch(1).await(); - } - -``` - - -6. 创建 Consumer - -```java - public static void main(String[] args) throws IOException { - ReferenceConfig ref = new ReferenceConfig<>(); - ref.setInterface(IGreeter.class); - ref.setCheck(false); - ref.setProtocol(CommonConstants.TRIPLE); - ref.setLazy(true); - ref.setTimeout(100000); - ref.setApplication(new ApplicationConfig("demo-consumer")); - ref.setRegistry(new RegistryConfig("zookeeper://127.0.0.1:2181")); - final IGreeter iGreeter = ref.get(); - - System.out.println("dubbo ref started"); - try { - final HelloReply reply = iGreeter.sayHello(HelloRequest.newBuilder() - .setName("name") - .build()); - TimeUnit.SECONDS.sleep(1); - System.out.println("Reply:" + reply); - } catch (Throwable t) { - t.printStackTrace(); - } - System.in.read(); - } -``` - -7. 运行 Provider 和 Consumer ,可以看到请求正常返回 -```java -> Reply:message: "name" -``` - -### stream 方式 - -8. 编写 Java 接口 -```java - import org.apache.dubbo.hello.HelloReply; - import org.apache.dubbo.hello.HelloRequest; - - public interface IGreeter { - /** - *
-     	*  Sends greeting by stream
-     	* 
- */ - StreamObserver sayHello(StreamObserver replyObserver); - - } -``` - -9. 编写实现类 -```java - public class IStreamGreeterImpl implements IStreamGreeter { - - @Override - public StreamObserver sayHello(StreamObserver replyObserver) { - - return new StreamObserver() { - private List replyList = new ArrayList<>(); - - @Override - public void onNext(HelloRequest helloRequest) { - System.out.println("onNext receive request name:" + helloRequest.getName()); - replyList.add(HelloReply.newBuilder() - .setMessage("receive name:" + helloRequest.getName()) - .build()); - } - - @Override - public void onError(Throwable cause) { - System.out.println("onError"); - replyObserver.onError(cause); - } - - @Override - public void onCompleted() { - System.out.println("onComplete receive request size:" + replyList.size()); - for (HelloReply reply : replyList) { - replyObserver.onNext(reply); - } - replyObserver.onCompleted(); - } - }; - } - } -``` - -10. 创建 Provider - -```java - public class StreamProvider { - public static void main(String[] args) throws InterruptedException { - ServiceConfig service = new ServiceConfig<>(); - service.setInterface(IStreamGreeter.class); - service.setRef(new IStreamGreeterImpl()); - service.setProtocol(new ProtocolConfig(CommonConstants.TRIPLE, 50051)); - service.setApplication(new ApplicationConfig("stream-provider")); - service.setRegistry(new RegistryConfig("zookeeper://127.0.0.1:2181")); - service.export(); - System.out.println("dubbo service started"); - new CountDownLatch(1).await(); - } - } -``` - -11. 创建 Consumer - -```java - public class StreamConsumer { - public static void main(String[] args) throws InterruptedException, IOException { - ReferenceConfig ref = new ReferenceConfig<>(); - ref.setInterface(IStreamGreeter.class); - ref.setCheck(false); - ref.setProtocol(CommonConstants.TRIPLE); - ref.setLazy(true); - ref.setTimeout(100000); - ref.setApplication(new ApplicationConfig("stream-consumer")); - ref.setRegistry(new RegistryConfig("zookeeper://mse-6e9fda00-p.zk.mse.aliyuncs.com:2181")); - final IStreamGreeter iStreamGreeter = ref.get(); - - System.out.println("dubbo ref started"); - try { - - StreamObserver streamObserver = iStreamGreeter.sayHello(new StreamObserver() { - @Override - public void onNext(HelloReply reply) { - System.out.println("onNext"); - System.out.println(reply.getMessage()); - } - - @Override - public void onError(Throwable throwable) { - System.out.println("onError:" + throwable.getMessage()); - } - - @Override - public void onCompleted() { - System.out.println("onCompleted"); - } - }); - - streamObserver.onNext(HelloRequest.newBuilder() - .setName("tony") - .build()); - - streamObserver.onNext(HelloRequest.newBuilder() - .setName("nick") - .build()); - - streamObserver.onCompleted(); - } catch (Throwable t) { - t.printStackTrace(); - } - System.in.read(); - } - } -``` - -12. 运行 Provider 和 Consumer ,可以看到请求正常返回了 -```java -> onNext\ -> receive name:tony\ -> onNext\ -> receive name:nick\ -> onCompleted -``` - -### 其他序列化方式 -省略上文中的 1-3 步,指定 Provider 和 Consumer 使用的协议即可完成协议升级。 - -> 本文的示例可以在 [triple-samples](https://github.com/apache/dubbo-samples/tree/master/3-extensions/protocol/dubbo-samples-triple) 找到 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/triple/idl.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/triple/idl.md deleted file mode 100644 index 40c2cb2ffa78..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/triple/idl.md +++ /dev/null @@ -1,247 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/reference-manual/protocol/triple/idl/ - - /zh-cn/docs3-v2/java-sdk/reference-manual/protocol/triple/idl/ -description: IDL 方式使用 Triple -linkTitle: IDL 方式使用 Triple -title: IDL 方式使用 Triple -type: docs -weight: 2 ---- - - - - - - -这篇教程会通过从零构建一个简单的工程来演示如何基于 IDL 方式使用 Dubbo Triple - -## 前置条件 -- [JDK](https://jdk.java.net/) 版本 >= 8 -- 已安装 [Maven](https://maven.apache.org/) -- 已安装并启动 [Zookeeper](https://zookeeper.apache.org/) - -## 创建工程 -### 1. 创建一个空的 maven 工程 - ``` -$ mvn archetype:generate \ - -DgroupId=org.apache.dubbo \ - -DartifactId=tri-stub-demo \ - -DarchetypeArtifactId=maven-archetype-quickstart \ - -DarchetypeVersion=1.4 \ - -DarchetypeGroupId=org.apache.maven.archetypes \ - -Dversion=1.0-SNAPSHOT -``` -### 2. 切换到工程目录 -``` - $ cd tri-stub-demo -``` -### 3. 添加 Dubbo 依赖和插件 - -在 `pom.xml` 中设置 JDK 版本 -```xml - - UTF-8 - 1.8 - 1.8 - 3.1.7 - - - - - junit - junit - 4.13 - test - - - org.apache.dubbo - dubbo - ${dubbo.version} - - - org.apache.dubbo - dubbo-dependencies-zookeeper-curator5 - pom - ${dubbo.version} - - - com.google.protobuf - protobuf-java - 3.19.4 - - - - - - - kr.motd.maven - os-maven-plugin - 1.6.1 - - - - - org.xolstice.maven.plugins - protobuf-maven-plugin - 0.6.1 - - com.google.protobuf:protoc:3.19.4:exe:${os.detected.classifier} - - - dubbo - org.apache.dubbo - dubbo-compiler - ${dubbo.version} - org.apache.dubbo.gen.tri.Dubbo3TripleGenerator - - - - - - - compile - - - - - - -``` -### 4. 添加接口定义文件 - -`src/main/proto/hello.proto`,Dubbo 使用 [Protobuf](https://developers.google.com/protocol-buffers) 作为 IDL -```protobuf - syntax = "proto3"; - - option java_multiple_files = true; - option java_package = "org.apache.dubbo.hello"; - option java_outer_classname = "HelloWorldProto"; - option objc_class_prefix = "HLW"; - - package helloworld; - - message HelloRequest { - string name = 1; - } - - message HelloReply { - string message = 1; - } - service Greeter{ - rpc greet(HelloRequest) returns (HelloReply); - } - -``` -### 5. 编译 IDL -``` - $ mvn clean install -``` - 编译成功后,可以看到`target/generated-sources/protobuf/java` 目录下生成了代码文件 -``` - $ ls org/apache/dubbo/hello/ - DubboGreeterTriple.java HelloReply.java HelloRequest.java HelloWorldProto.java - Greeter.java HelloReplyOrBuilder.java HelloRequestOrBuilder.java -``` - -### 6. 添加服务端接口实现 - -`src/main/java/org/apache/dubbo/GreeterImpl.java` -```java - package org.apache.dubbo; - - import org.apache.dubbo.hello.DubboGreeterTriple; - import org.apache.dubbo.hello.HelloReply; - import org.apache.dubbo.hello.HelloRequest; - - public class GreeterImpl extends DubboGreeterTriple.GreeterImplBase { - @Override - public HelloReply greet(HelloRequest request) { - return HelloReply.newBuilder() - .setMessage("Hello," + request.getName() + "!") - .build(); - } - } -``` -### 7. 添加服务端启动类 -`src/main/java/org/apache/dubbo/MyDubboServer.java` -```java - package org.apache.dubbo; - - import org.apache.dubbo.common.constants.CommonConstants; - import org.apache.dubbo.config.ApplicationConfig; - import org.apache.dubbo.config.ProtocolConfig; - import org.apache.dubbo.config.RegistryConfig; - import org.apache.dubbo.config.ServiceConfig; - import org.apache.dubbo.config.bootstrap.DubboBootstrap; - import org.apache.dubbo.hello.Greeter; - - import java.io.IOException; - - public class MyDubboServer { - - public static void main(String[] args) throws IOException { - ServiceConfig service = new ServiceConfig<>(); - service.setInterface(Greeter.class); - service.setRef(new GreeterImpl()); - - DubboBootstrap bootstrap = DubboBootstrap.getInstance(); - bootstrap.application(new ApplicationConfig("tri-stub-server")) - .registry(new RegistryConfig("zookeeper://127.0.0.1:2181")) - .protocol(new ProtocolConfig(CommonConstants.TRIPLE, 50051)) - .service(service) - .start(); - System.out.println("Dubbo triple stub server started"); - System.in.read(); - } - } -``` - -### 8. 添加客户端启动类 -`src/main/java/org/apache/dubbo/MyDubboClient.java` -```java - package org.apache.dubbo; - - import org.apache.dubbo.common.constants.CommonConstants; - import org.apache.dubbo.config.ApplicationConfig; - import org.apache.dubbo.config.ReferenceConfig; - import org.apache.dubbo.config.RegistryConfig; - import org.apache.dubbo.config.bootstrap.DubboBootstrap; - import org.apache.dubbo.hello.Greeter; - import org.apache.dubbo.hello.HelloReply; - import org.apache.dubbo.hello.HelloRequest; - - public class MyDubboClient { - public static void main(String[] args) { - DubboBootstrap bootstrap = DubboBootstrap.getInstance(); - ReferenceConfig ref = new ReferenceConfig<>(); - ref.setInterface(Greeter.class); - ref.setProtocol(CommonConstants.TRIPLE); - ref.setProxy(CommonConstants.NATIVE_STUB); - ref.setTimeout(3000); - bootstrap.application(new ApplicationConfig("tri-stub-client")) - .registry(new RegistryConfig("zookeeper://127.0.0.1:2181")) - .reference(ref) - .start(); - - Greeter greeter = ref.get(); - HelloRequest request = HelloRequest.newBuilder().setName("Demo").build(); - HelloReply reply = greeter.greet(request); - System.out.println("Received reply:" + reply); - } - } -``` -### 9. 编译代码 -``` -$ mvn clean install -``` -### 10. 启动服务端 -``` -$ mvn org.codehaus.mojo:exec-maven-plugin:3.0.0:java -Dexec.mainClass="org.apache.dubbo.MyDubboServer" -Dubbo triple stub server started -``` -### 11. 打开新的终端,启动客户端 -``` -$ mvn org.codehaus.mojo:exec-maven-plugin:3.0.0:java -Dexec.mainClass="org.apache.dubbo.MyDubboClient" -Received reply:message: "Hello,Demo!" -``` \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/triple/migration.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/triple/migration.md deleted file mode 100644 index 34371fba4a9c..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/triple/migration.md +++ /dev/null @@ -1,102 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/reference-manual/protocol/triple/migration/ - - /zh-cn/docs3-v2/java-sdk/reference-manual/protocol/triple/migration/ -description: Dubbo2 协议迁移 -linkTitle: Dubbo2 协议迁移 -title: Dubbo2 协议迁移 -type: docs -weight: 10 ---- - - - - - - -## 迁移流程说明 - -Dubbo2 的用户使用 dubbo 协议 + 自定义序列化,如 hessian2 完成远程调用。 - -而 Grpc 的默认仅支持 Protobuf 序列化,对于 Java 语言中的多参数以及方法重载也无法支持。 - -Dubbo3 的之初就有一条目标是完美兼容 Dubbo2,所以为了 Dubbo2 能够平滑升级, Dubbo 框架侧做了很多工作来保证升级的无感,目前默认的序列化和 Dubbo2 保持一致为 `hessian2`。 - -所以,如果决定要升级到 Dubbo3 的 `Triple` 协议,只需要修改配置中的协议名称为 `tri` (注意: 不是 triple )即可。 - -接下来我们以一个使用 Dubbo2 协议的[工程](https://github.com/apache/dubbo-samples/tree/master/3-extensions/protocol/dubbo-samples-triple/src/main/java/org/apache/dubbo/sample/tri/migration)来举例,如何一步一步安全的升级。 - -1. 仅使用 `dubbo` 协议启动 `provider` 和 `consumer`,并完成调用。 -2. 仅使用 `tri` 协议启动 `provider` 和 `consumer`,并完成调用。 -3. 使用 `dubbo` 协议和 `tri` 协议 启动 `provider`,以 `dubbo` 协议启动 `consumer`,并完成调用。 - -### 定义服务 - -1. 定义接口 -```java -public interface IWrapperGreeter { - - //... - - /** - * 这是一个普通接口,没有使用 pb 序列化 - */ - String sayHello(String request); - -} -``` - -2. 实现类示例 -```java -public class IGreeter2Impl implements IWrapperGreeter { - - @Override - public String sayHello(String request) { - return "hello," + request; - } -} -``` - -### 仅使用 dubbo 协议 - -为保证兼容性,我们先将部分 provider 升级到 `dubbo3` 版本并使用 `dubbo` 协议。 - -使用 `dubbo` 协议启动一个 [`Provider`](https://github.com/apache/dubbo-samples/tree/master/3-extensions/protocol/dubbo-samples-triple/src/main/java/org/apache/dubbo/sample/tri/migration/ApiMigrationDubboProvider.java) 和 [`Consumer`](https://github.com/apache/dubbo-samples/tree/master/3-extensions/protocol/dubbo-samples-triple/src/main/java/org/apache/dubbo/sample/tri/migration/ApiMigrationDubboConsumer.java) 完成调用。 - -{{% alert title="输出结果" color="info" %}} -![result](/imgs/v3/migration/tri/dubbo3-tri-migration-dubbo-dubbo-result.png) -{{% /alert %}} - -### 仅使用 triple 协议 - -当所有的 consumer 都升级至支持 `Triple` 协议的版本后,provider 可切换至仅使用 `Triple` 协议启动 - -结构如图所示: -![strust](/imgs/v3/migration/tri/migrate-only-tri-strust.png) - -[Provider](https://github.com/apache/dubbo-samples/tree/master/3-extensions/protocol/dubbo-samples-triple/src/main/java/org/apache/dubbo/sample/tri/migration/ApiMigrationTriProvider.java) -和 [Consumer](https://github.com/apache/dubbo-samples/tree/master/3-extensions/protocol/dubbo-samples-triple/src/main/java/org/apache/dubbo/sample/tri/migration/ApiMigrationTriConsumer.java) 完成调用。 - - -{{% alert title="输出结果" color="info" %}} -![result](/imgs/v3/migration/tri/dubbo3-tri-migration-tri-tri-result.png) -{{% /alert %}} - -### 同时使用 dubbo 和 triple 协议 - -对于线上服务的升级,不可能一蹴而就同时完成 provider 和 consumer 升级, 需要按步操作, - -**第一步:保证业务稳定。** - -**第二步:provider 提供双协议的方式同时支持 dubbo + tri 两种协议的客户端。** - -结构如图所示: -![strust](/imgs/v3/migration/tri/migrate-dubbo-tri-strust.png) - -> 按照推荐升级步骤,provider 已经支持了 tri 协议,所以 dubbo3 的 consumer 可以直接使用 tri 协议 - -使用 `dubbo` 协议和 `triple` 协议启动[`Provider`](https://github.com/apache/dubbo-samples/tree/master/3-extensions/protocol/dubbo-samples-triple/src/main/java/org/apache/dubbo/sample/tri/migration/ApiMigrationBothProvider.java)和[`Consumer`](https://github.com/apache/dubbo-samples/tree/master/3-extensions/protocol/dubbo-samples-triple/src/main/java/org/apache/dubbo/sample/tri/migration/ApiMigrationBothConsumer.java) 完成调用。 - -{{% alert title="输出结果" color="info" %}} -![result](/imgs/v3/migration/tri/dubbo3-tri-migration-both-dubbo-tri-result.png) -{{% /alert %}} diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/triple/overview.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/triple/overview.md deleted file mode 100644 index 246db224d4dd..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/triple/overview.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/reference-manual/protocol/triple/overview/ - - /zh-cn/docs3-v2/java-sdk/reference-manual/protocol/triple/overview/ -description: 协议概述 -linkTitle: 协议概述 -title: 协议概述 -type: docs -weight: 1 ---- - - - - - - -## 概述说明 - -`Triple` 协议的格式和原理请参阅 [RPC 通信协议](/zh-cn/docs/concepts/rpc-protocol/) - -根据 Triple 设计的目标,`Triple` 协议有以下优势 - -- 具备跨语言交互的能力,传统的多语言多 SDK 模式和 Mesh 化跨语言模式都需要一种更通用易扩展的数据传输协议。 -- 提供更完善的请求模型,除了支持传统的 Request/Response 模型(Unary 单向通信),还支持 Stream(流式通信) 和 Bidirectional(双向通信)。 -- 易扩展、穿透性高,包括但不限于 Tracing / Monitoring 等支持,也应该能被各层设备识别,网关设施等可以识别数据报文,对 Service Mesh 部署友好,降低用户理解难度。 -- 完全兼容 grpc,客户端/服务端可以与原生grpc客户端打通。 -- 可以复用现有 grpc 生态下的组件, 满足云原生场景下的跨语言、跨环境、跨平台的互通需求。 - -当前使用其他协议的 Dubbo 用户,框架提供了兼容现有序列化方式的迁移能力,在不影响线上已有业务的前提下,迁移协议的成本几乎为零。 - -### GRPC -需要新增对接 grpc 服务的 Dubbo 用户,可以直接使用 Triple 协议来实现打通,不需要单独引入 grpc client 来完成,不仅能保留已有的 Dubbo 易用性,也能降低程序的复杂度和开发运维成本,不需要额外进行适配和开发即可接入现有生态。 - -### 网关接入 -对于需要网关接入的 Dubbo 用户,Triple 协议提供了更加原生的方式,让网关开发或者使用开源的 grpc 网关组件更加简单。网关可以选择不解析 payload ,在性能上也有很大提高。在使用 Dubbo 协议时,语言相关的序列化方式是网关的一个很大痛点,而传统的 HTTP 转 Dubbo 的方式对于跨语言序列化几乎是无能为力的。同时,由于 Triple 的协议元数据都存储在请求头中,网关可以轻松的实现定制需求,如路由和限流等功能。 - - -## 常见问题 - -### Q1 -protobuf 类找不到 - -由于 Triple 协议底层需要依赖 protobuf 协议进行传输,即使定义的服务接口不使用 protobuf 也需要在环境中引入 protobuf 的依赖。 - -```xml - - com.google.protobuf - protobuf-java - 3.19.4 - -``` \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/triple/pojo.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/triple/pojo.md deleted file mode 100644 index e73dc3be66e0..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/triple/pojo.md +++ /dev/null @@ -1,209 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/reference-manual/protocol/triple/pojo/ - - /zh-cn/docs3-v2/java-sdk/reference-manual/protocol/triple/pojo/ -description: POJO 方式使用 Triple -linkTitle: POJO 方式使用 Triple -title: POJO 方式使用 Triple -type: docs -weight: 2 ---- - - - - - - -这篇教程会通过从零构建一个简单的工程来演示如何基于 POJO 方式使用 Dubbo Triple, 在应用不改变已有接口定义的同时升级到 Triple 协议。 - - -### 实现原理 - -通过上面介绍的升级过程,我们可以很简单的通过修改协议类型来完成升级。框架是怎么帮我们做到这些的呢? - -通过对 `Triple` 协议的介绍,我们知道Dubbo3的 `Triple` 的数据类型是 `protobuf` 对象,那为什么非 `protobuf` 的 java 对象也可以被正常传输呢。 - -这里 Dubbo3 使用了一个巧妙的设计,首先判断参数类型是否为 `protobuf` 对象,如果不是。用一个 `protobuf` 对象将 `request` 和 `response` 进行 wrapper,这样就屏蔽了其他各种序列化带来的复杂度。在 `wrapper` 对象内部声明序列化类型,来支持序列化的扩展。 - -wrapper 的`protobuf`的 IDL如下: -```proto -syntax = "proto3"; - -package org.apache.dubbo.triple; - -message TripleRequestWrapper { - // hessian4 - // json - string serializeType = 1; - repeated bytes args = 2; - repeated string argTypes = 3; -} - -message TripleResponseWrapper { - string serializeType = 1; - bytes data = 2; - string type = 3; -} -``` - -对于请求,使用`TripleRequestWrapper`进行包装,对于响应使用`TripleResponseWrapper`进行包装。 - -> 对于请求参数,可以看到 args 被`repeated`修饰,这是因为需要支持 java 方法的多个参数。当然,序列化只能是一种。序列化的实现沿用 Dubbo2 实现的 spi - -### 前置条件 -- [JDK](https://jdk.java.net/) 版本 >= 8 -- 已安装 [Maven](https://maven.apache.org/) -- 已安装并启动 [Zookeeper](https://zookeeper.apache.org/) - -### 创建工程 -1. 首先创建一个空的 maven 工程 -``` -$ mvn archetype:generate \ - -DgroupId=org.apache.dubbo \ - -DartifactId=tri-pojo-demo \ - -DarchetypeArtifactId=maven-archetype-quickstart \ - -DarchetypeVersion=1.4 \ - -DarchetypeGroupId=org.apache.maven.archetypes \ - -Dversion=1.0-SNAPSHOT -``` -2. 切换到工程目录 -``` -$ cd tri-pojo-demo -``` -3. 在 `pom.xml` 中设置 JDK 版本,添加 Dubbo 依赖和插件 -```xml - - UTF-8 - 1.8 - 1.8 - - - - - junit - junit - 4.13 - test - - - org.apache.dubbo - dubbo - 3.0.8 - - - org.apache.dubbo - dubbo-dependencies-zookeeper-curator5 - pom - 3.0.8 - - - com.google.protobuf - protobuf-java - 3.19.4 - - -``` - -4. 添加接口定义`src/main/java/org/apache/dubbo/Greeter.java` -```java - package org.apache.dubbo; - - public interface Greeter { - String sayHello(String name); - } -``` -5. 添加服务端接口实现`src/main/java/org/apache/dubbo/GreeterImpl.java` -```java - package org.apache.dubbo; - - public class GreeterImpl implements Greeter { - @Override - public String sayHello(String name) { - return "Hello," + name + "!"; - } - } -``` -6. 添加服务端启动类 `src/main/java/org/apache/dubbo/MyDubboServer.java` -```java - package org.apache.dubbo; - - import org.apache.dubbo.common.constants.CommonConstants; - import org.apache.dubbo.config.ApplicationConfig; - import org.apache.dubbo.config.ProtocolConfig; - import org.apache.dubbo.config.RegistryConfig; - import org.apache.dubbo.config.ServiceConfig; - import org.apache.dubbo.config.bootstrap.DubboBootstrap; - - import java.io.IOException; - - public class MyDubboServer { - - public static void main(String[] args) throws IOException { - ServiceConfig service = new ServiceConfig<>(); - service.setInterface(Greeter.class); - service.setRef(new GreeterImpl()); - - DubboBootstrap bootstrap = DubboBootstrap.getInstance(); - bootstrap.application(new ApplicationConfig("tri-pojo-server")) - .registry(new RegistryConfig("zookeeper://127.0.0.1:2181")) - .protocol(new ProtocolConfig(CommonConstants.TRIPLE, 50051)) - .service(service) - .start(); - System.out.println("Dubbo triple pojo server started"); - System.in.read(); - } - } -``` - -7. 添加客户端启动类`src/main/java/org/apache/dubbo/MyDubboClient.java` -```java - package org.apache.dubbo; - - import org.apache.dubbo.common.constants.CommonConstants; - import org.apache.dubbo.config.ApplicationConfig; - import org.apache.dubbo.config.ReferenceConfig; - import org.apache.dubbo.config.RegistryConfig; - import org.apache.dubbo.config.bootstrap.DubboBootstrap; - - public class MyDubboClient { - public static void main(String[] args) { - DubboBootstrap bootstrap = DubboBootstrap.getInstance(); - ReferenceConfig ref = new ReferenceConfig<>(); - ref.setInterface(Greeter.class); - ref.setProtocol(CommonConstants.TRIPLE); - ref.setTimeout(3000); - bootstrap.application(new ApplicationConfig("tri-pojo-client")) - .registry(new RegistryConfig("zookeeper://127.0.0.1:2181")) - .reference(ref) - .start(); - - Greeter greeter = ref.get(); - String reply = greeter.sayHello("pojo"); - System.out.println("Received reply:" + reply); - } - } -``` - -8. 编译代码 -``` -$ mvn clean install -``` -9. 启动服务端 -``` -$ mvn org.codehaus.mojo:exec-maven-plugin:3.0.0:java -Dexec.mainClass="org.apache.dubbo.MyDubboServer" -``` -{{% alert title="输出结果" color="info" %}} -```shell -Dubbo triple pojo server started -``` -{{% /alert %}} - -10. 打开新的终端,启动客户端 -``` -$ mvn org.codehaus.mojo:exec-maven-plugin:3.0.0:java -Dexec.mainClass="org.apache.dubbo.MyDubboClient" -``` -{{% alert title="输出结果" color="info" %}} -```shell -Received reply:message: "Hello,Demo!" -``` -{{% /alert %}} diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/triple/streaming.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/triple/streaming.md deleted file mode 100644 index 2e24b02ed6bd..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/triple/streaming.md +++ /dev/null @@ -1,164 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/reference-manual/protocol/triple/streaming/ - - /zh-cn/docs3-v2/java-sdk/reference-manual/protocol/triple/streaming/ -description: Streaming 通信 -linkTitle: Streaming 通信 -title: Streaming 通信 -type: docs -weight: 10 ---- - - - - - -## 流实现原理 - -`Triple`协议的流模式 - -- 从协议层来说,`Triple` 是建立在 `HTTP2` 基础上的,所以直接拥有所有 `HTTP2` 的能力,故拥有了分 `stream` 和全双工的能力。 - -- 框架层来说,`StreamObserver` 作为流的接口提供给用户,用于入参和出参提供流式处理。框架在收发 stream data 时进行相应的接口调用, 从而保证流的生命周期完整。 - -## 流使用方式 - -### Stream 流 -Stream 是 Dubbo3 新提供的一种调用类型,在以下场景时建议使用流的方式: - -- 接口需要发送大量数据,这些数据无法被放在一个 RPC 的请求或响应中,需要分批发送,但应用层如果按照传统的多次 RPC 方式无法解决顺序和性能的问题,如果需要保证有序,则只能串行发送 -- 流式场景,数据需要按照发送顺序处理, 数据本身是没有确定边界的 -- 推送类场景,多个消息在同一个调用的上下文中被发送和处理 - -Stream 分为以下三种: -- SERVER_STREAM(服务端流) - ![SERVER_STREAM](/imgs/v3/migration/tri/migrate-server-stream.png) -- CLIENT_STREAM(客户端流) - ![CLIENT_STREAM](/imgs/v3/migration/tri/migrate-client-stream.png) -- BIDIRECTIONAL_STREAM(双向流) - ![BIDIRECTIONAL_STREAM](/imgs/v3/migration/tri/migrate-bi-stream.png) - -由于 `java` 语言的限制,BIDIRECTIONAL_STREAM 和 CLIENT_STREAM 的实现是一样的。 - -在 Dubbo3 中,流式接口以 `SteamObserver` 声明和使用,用户可以通过使用和实现这个接口来发送和处理流的数据、异常和结束。 - -对于 Dubbo2 用户来说,可能会对StreamObserver感到陌生,这是Dubbo3定义的一种流类型,Dubbo2 中并不存在 Stream 的类型,所以对于迁移场景没有任何影响。 - -{{% alert title="流的语义保证" color="primary" %}} -- 提供消息边界,可以方便地对消息单独处理 -- 严格有序,发送端的顺序和接收端顺序一致 -- 全双工,发送不需要等待 -- 支持取消和超时 -{{% /alert %}} - -### Protobuf 序列化的流 - -对于 `Protobuf` 序列化方式,推荐编写 `IDL` 使用 `compiler` 插件进行编译生成。生成的代码大致如下: -```java -public interface PbGreeter { - - static final String JAVA_SERVICE_NAME = "org.apache.dubbo.sample.tri.PbGreeter"; - static final String SERVICE_NAME = "org.apache.dubbo.sample.tri.PbGreeter"; - - static final boolean inited = PbGreeterDubbo.init(); - - //... - - void greetServerStream(org.apache.dubbo.sample.tri.GreeterRequest request, org.apache.dubbo.common.stream.StreamObserver responseObserver); - - org.apache.dubbo.common.stream.StreamObserver greetStream(org.apache.dubbo.common.stream.StreamObserver responseObserver); -} -``` - -## 非 Protobuf 序列化的流 -### api -```java -public interface IWrapperGreeter { - - StreamObserver sayHelloStream(StreamObserver response); - - void sayHelloServerStream(String request, StreamObserver response); -} -``` - -> Stream 方法的方法入参和返回值是严格约定的,为防止写错而导致问题,Dubbo3 框架侧做了对参数的检查, 如果出错则会抛出异常。 -> 对于 `双向流(BIDIRECTIONAL_STREAM)`, 需要注意参数中的 `StreamObserver` 是响应流,返回参数中的 `StreamObserver` 为请求流。 -### 实现类 -```java -public class WrapGreeterImpl implements WrapGreeter { - - //... - - @Override - public StreamObserver sayHelloStream(StreamObserver response) { - return new StreamObserver() { - @Override - public void onNext(String data) { - System.out.println(data); - response.onNext("hello,"+data); - } - - @Override - public void onError(Throwable throwable) { - throwable.printStackTrace(); - } - - @Override - public void onCompleted() { - System.out.println("onCompleted"); - response.onCompleted(); - } - }; - } - - @Override - public void sayHelloServerStream(String request, StreamObserver response) { - for (int i = 0; i < 10; i++) { - response.onNext("hello," + request); - } - response.onCompleted(); - } -} -``` - -### 调用方式 -```java -delegate.sayHelloServerStream("server stream", new StreamObserver() { - @Override - public void onNext(String data) { - System.out.println(data); - } - - @Override - public void onError(Throwable throwable) { - throwable.printStackTrace(); - } - - @Override - public void onCompleted() { - System.out.println("onCompleted"); - } -}); - - -StreamObserver request = delegate.sayHelloStream(new StreamObserver() { - @Override - public void onNext(String data) { - System.out.println(data); - } - - @Override - public void onError(Throwable throwable) { - throwable.printStackTrace(); - } - - @Override - public void onCompleted() { - System.out.println("onCompleted"); - } -}); -for (int i = 0; i < n; i++) { - request.onNext("stream request" + i); -} -request.onCompleted(); -``` diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/qos/_index.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/qos/_index.md index 82cc5cbf88fd..f2ed9eafcb95 100755 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/qos/_index.md +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/qos/_index.md @@ -3,8 +3,8 @@ aliases: - /zh/docs3-v2/java-sdk/reference-manual/qos/ - /zh-cn/docs3-v2/java-sdk/reference-manual/qos/ description: Dubbo QOS 操作指南 -linkTitle: QOS 操作手册 +linkTitle: 单机运维命令(QOS) title: QOS 操作手册 type: docs -weight: 3 +weight: 99 --- diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/qos/introduction/_index.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/qos/introduction/_index.md new file mode 100755 index 000000000000..173601f4eaaf --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/qos/introduction/_index.md @@ -0,0 +1,7 @@ +--- +description: "QoS 命令详解,包含对每个命令的使用方法、效果的详细说明" +linkTitle: 部分命令详解 +title: 包含对每个命令的使用方法、效果的详细说明 +type: docs +weight: 99 +--- diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/qos/command.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/qos/introduction/command.md similarity index 100% rename from content/zh-cn/overview/mannual/java-sdk/reference-manual/qos/command.md rename to content/zh-cn/overview/mannual/java-sdk/reference-manual/qos/introduction/command.md diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/qos/default_metrics.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/qos/introduction/default_metrics.md similarity index 100% rename from content/zh-cn/overview/mannual/java-sdk/reference-manual/qos/default_metrics.md rename to content/zh-cn/overview/mannual/java-sdk/reference-manual/qos/introduction/default_metrics.md diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/qos/introduction/logger-management.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/qos/introduction/logger-management.md new file mode 100644 index 000000000000..3f1f155c1fb4 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/qos/introduction/logger-management.md @@ -0,0 +1,103 @@ +--- +aliases: + - /zh/docs3-v2/java-sdk/reference-manual/qos/logger-management/ + - /zh-cn/docs3-v2/java-sdk/reference-manual/qos/logger-management/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/others/logger-management/ +description: 在 Dubbo 中运行时动态切换使用的日志框架 +linkTitle: 日志框架运行时管理 +title: 日志框架运行时管理 +type: docs +weight: 5 +--- + + + + + +{{% alert title="注意" color="primary" %}} + +自 `3.0.10` 开始,dubbo-qos 运行时管控支持查询日志配置以及动态修改使用的日志框架和日志级别。 + +通过 dubbo-qos 修改的日志配置不进行持久化存储,在应用重启后将会失效。 +{{% /alert %}} + +### 查询日志配置 + +命令:`loggerInfo` + +示例: +```bash +> telnet 127.0.0.1 22222 +> loggerInfo +``` + +输出: +``` +Trying 127.0.0.1... +Connected to localhost. +Escape character is '^]'. + ___ __ __ ___ ___ ____ + / _ \ / / / // _ ) / _ ) / __ \ + / // // /_/ // _ |/ _ |/ /_/ / +/____/ \____//____//____/ \____/ +dubbo>loggerInfo +Available logger adapters: [jcl, jdk, log4j, slf4j]. Current Adapter: [log4j]. Log level: INFO +``` + +### 修改日志级别 + +命令:`switchLogLevel {level}` + +level: `ALL`, `TRACE`, `DEBUG`, `INFO`, `WARN`, `ERROR`, `OFF` + +示例: +```bash +> telnet 127.0.0.1 22222 +> switchLogLevel WARN +``` + +输出: +``` +Trying 127.0.0.1... +Connected to localhost. +Escape character is '^]'. + ___ __ __ ___ ___ ____ + / _ \ / / / // _ ) / _ ) / __ \ + / // // /_/ // _ |/ _ |/ /_/ / +/____/ \____//____//____/ \____/ +dubbo>loggerInfo +Available logger adapters: [jcl, jdk, log4j, slf4j]. Current Adapter: [log4j]. Log level: INFO +dubbo>switchLogLevel WARN +OK +dubbo>loggerInfo +Available logger adapters: [jcl, jdk, log4j, slf4j]. Current Adapter: [log4j]. Log level: WARN``` +``` + +### 修改日志输出框架 + +命令:`switchLogger {loggerAdapterName}` + +loggerAdapterName: `slf4j`, `jcl`, `log4j`, `jdk`, `log4j2` + +示例: +```bash +> telnet 127.0.0.1 22222 +> switchLogger slf4j +``` + +输出: +``` +Trying 127.0.0.1... +Connected to localhost. +Escape character is '^]'. + ___ __ __ ___ ___ ____ + / _ \ / / / // _ ) / _ ) / __ \ + / // // /_/ // _ |/ _ |/ /_/ / +/____/ \____//____//____/ \____/ +dubbo>loggerInfo +Available logger adapters: [jcl, slf4j, log4j, jdk]. Current Adapter: [log4j]. Log level: INFO +dubbo>switchLogger slf4j +OK +dubbo>loggerInfo +Available logger adapters: [jcl, slf4j, log4j, jdk]. Current Adapter: [slf4j]. Log level: INFO +``` diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/qos/probe.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/qos/introduction/probe.md similarity index 82% rename from content/zh-cn/overview/mannual/java-sdk/reference-manual/qos/probe.md rename to content/zh-cn/overview/mannual/java-sdk/reference-manual/qos/introduction/probe.md index 7efc8d7040fc..dbb0cd0301d9 100644 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/qos/probe.md +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/qos/introduction/probe.md @@ -9,13 +9,6 @@ type: docs weight: 4 --- - - - - - -> 参考文档:[Kubernetes 生命周期探针](../../../advanced-features-and-usage/others/dubbo-kubernetes-probe/) - ### startup 命令 检测当前框架是否已经启动完毕 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/qos/introduction/profiler.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/qos/introduction/profiler.md new file mode 100644 index 000000000000..b92ad9bab81d --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/qos/introduction/profiler.md @@ -0,0 +1,83 @@ +--- +aliases: + - /zh/docs3-v2/java-sdk/reference-manual/qos/profiler/ + - /zh-cn/docs3-v2/java-sdk/reference-manual/qos/profiler/ + - /zh-cn/overview/mannual/java-sdk/reference-manual/qos/profiler/ +description: 性能采样命令 +linkTitle: 性能采样命令 +title: 性能采样命令 +type: docs +weight: 7 +--- + + + + + + +性能采样功能可以对 Dubbo 处理链路上的各处耗时进行检测,在出现超时的时候 `( usageTime / timeout > profilerWarnPercent * 100 )` 通过日志记录调用的耗时。 + +此功能分为 `simple profiler` 和 `detail profiler` 两个模式,其中 `simple profiler` 模式默认开启,`detail profiler` 模式默认关闭。 +`detail profiler` 相较 `simple profiler` 模式多采集了每个 filter 的处理耗时、协议上的具体耗时等。 +在 `simple profiler` 模式下如果发现 Dubbo 框架内部存在耗时长的情况,可以开启 `detail profiler` 模式,以便更好地排查问题。 + +> [请求耗时采样](../../../advanced-features-and-usage/performance/profiler/) + +### enableSimpleProfiler 命令 + +开启 `simple profiler` 模式,默认开启 + +``` +dubbo>enableSimpleProfiler +OK + +dubbo> +``` + +### disableSimpleProfiler 命令 + +关闭 `simple profiler` 模式,关闭后 `detail profiler` 也将不启用 + +``` +dubbo>disableSimpleProfiler +OK + +dubbo> +``` + +### enableDetailProfiler 命令 + +开启 `detail profiler` 模式,默认关闭,需要开启 `simple profiler` 模式才会真实开启 + +``` +dubbo>enableDetailProfiler +OK. This will cause performance degradation, please be careful! + +dubbo> +``` + +### disableDetailProfiler 命令 + +关闭 `detail profiler` 模式,关闭后不影响 `simple profiler` + +``` +dubbo>disableDetailProfiler +OK + +dubbo> +``` + +### setProfilerWarnPercent 命令 + +设置超时时间的警告百分比 + +命令:`setProfilerWarnPercent {profilerWarnPercent}` + +profilerWarnPercent: 超时时间的警告百分比,取值范围 0.0 ~ 1.0,默认值为 0.75 + +``` +dubbo>setProfilerWarnPercent 0.75 +OK + +dubbo> +``` diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/qos/introduction/router-snapshot.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/qos/introduction/router-snapshot.md new file mode 100644 index 000000000000..4c5c3e165189 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/qos/introduction/router-snapshot.md @@ -0,0 +1,119 @@ +--- +aliases: + - /zh/docs3-v2/java-sdk/reference-manual/qos/router-snapshot/ + - /zh-cn/docs3-v2/java-sdk/reference-manual/qos/router-snapshot/ + - /zh-cn/overview/mannual/java-sdk/reference-manual/qos/router-snapshot/ +description: 路由状态命令 +linkTitle: 路由状态命令 +title: 路由状态命令 +type: docs +weight: 8 +--- + + + + + + +Dubbo 的很多流量治理能力是基于 Router 进行实现的,在生产环境中,如果出现流量结果不符合预期的情况,可以通过路由状态命令来查看路由的状态,以此来定位可能存在的问题。 + +> [路由状态采集](../../../advanced-features-and-usage/performance/router-snapshot/) + +### getRouterSnapshot 命令 + +获取当前的每层路由的分组状态。(仅支持 StateRouter) + +命令:`getRouterSnapshot {serviceName}` + +`serviceName` 为需要采集的服务名,支持匹配 + +``` +dubbo>getRouterSnapshot com.dubbo.dubbointegration.BackendService +com.dubbo.dubbointegration.BackendService@2c2e824a +[ All Invokers:2 ] [ Valid Invokers: 2 ] + +MockInvokersSelector Total: 2 +[ Mocked -> Empty (Total: 0) ] +[ Normal -> 172.18.111.187:20880,172.18.111.183:20880 (Total: 2) ] + ↓ +StandardMeshRuleRouter not support + ↓ +TagStateRouter not support + ↓ +ServiceStateRouter not support + ↓ +AppStateRouter not support + ↓ +TailStateRouter End + + +dubbo> +``` + +### enableRouterSnapshot 命令 + +开启路由结果采集模式 + +命令:`enableRouterSnapshot {serviceName}` + +`serviceName` 为需要采集的服务名,支持匹配 + +``` +dubbo>enableRouterSnapshot com.dubbo.* +OK. Found service count: 1. This will cause performance degradation, please be careful! + +dubbo> +``` + +### disableRouterSnapshot 命令 + +关闭路由结果采集模式 + +命令:`disableRouterSnapshot {serviceName}` + +`serviceName` 为需要采集的服务名,支持匹配 + +``` +dubbo>disableRouterSnapshot com.dubbo.* +OK. Found service count: 1 + +dubbo> +``` + +### getEnabledRouterSnapshot 命令 + +获取当前已经开启采集的服务 + +``` +dubbo>getEnabledRouterSnapshot +com.dubbo.dubbointegration.BackendService + +dubbo> +``` + +### getRecentRouterSnapshot 命令 + +通过 qos 命令获取历史的路由状态。(最多存储 32 个结果) + +``` +dubbo>getRecentRouterSnapshot +1658224330156 - Router snapshot service com.dubbo.dubbointegration.BackendService from registry 172.18.111.184 on the consumer 172.18.111.184 using the dubbo version 3.0.9 is below: +[ Parent (Input: 2) (Current Node Output: 2) (Chain Node Output: 2) ] Input: 172.18.111.187:20880,172.18.111.183:20880 -> Chain Node Output: 172.18.111.187:20880,172.18.111.183:20880 + [ MockInvokersSelector (Input: 2) (Current Node Output: 2) (Chain Node Output: 2) Router message: invocation.need.mock not set. Return normal Invokers. ] Current Node Output: 172.18.111.187:20880,172.18.111.183:20880 + [ StandardMeshRuleRouter (Input: 2) (Current Node Output: 2) (Chain Node Output: 2) Router message: MeshRuleCache has not been built. Skip route. ] Current Node Output: 172.18.111.187:20880,172.18.111.183:20880 + [ TagStateRouter (Input: 2) (Current Node Output: 2) (Chain Node Output: 2) Router message: Disable Tag Router. Reason: tagRouterRule is invalid or disabled ] Current Node Output: 172.18.111.187:20880,172.18.111.183:20880 + [ ServiceStateRouter (Input: 2) (Current Node Output: 2) (Chain Node Output: 2) Router message: Directly return. Reason: Invokers from previous router is empty or conditionRouters is empty. ] Current Node Output: 172.18.111.187:20880,172.18.111.183:20880 + [ AppStateRouter (Input: 2) (Current Node Output: 2) (Chain Node Output: 2) Router message: Directly return. Reason: Invokers from previous router is empty or conditionRouters is empty. ] Current Node Output: 172.18.111.187:20880,172.18.111.183:20880 + +1658224330156 - Router snapshot service com.dubbo.dubbointegration.BackendService from registry 172.18.111.184 on the consumer 172.18.111.184 using the dubbo version 3.0.9 is below: +[ Parent (Input: 2) (Current Node Output: 2) (Chain Node Output: 2) ] Input: 172.18.111.187:20880,172.18.111.183:20880 -> Chain Node Output: 172.18.111.187:20880,172.18.111.183:20880 + [ MockInvokersSelector (Input: 2) (Current Node Output: 2) (Chain Node Output: 2) Router message: invocation.need.mock not set. Return normal Invokers. ] Current Node Output: 172.18.111.187:20880,172.18.111.183:20880 + [ StandardMeshRuleRouter (Input: 2) (Current Node Output: 2) (Chain Node Output: 2) Router message: MeshRuleCache has not been built. Skip route. ] Current Node Output: 172.18.111.187:20880,172.18.111.183:20880 + [ TagStateRouter (Input: 2) (Current Node Output: 2) (Chain Node Output: 2) Router message: Disable Tag Router. Reason: tagRouterRule is invalid or disabled ] Current Node Output: 172.18.111.187:20880,172.18.111.183:20880 + [ ServiceStateRouter (Input: 2) (Current Node Output: 2) (Chain Node Output: 2) Router message: Directly return. Reason: Invokers from previous router is empty or conditionRouters is empty. ] Current Node Output: 172.18.111.187:20880,172.18.111.183:20880 + [ AppStateRouter (Input: 2) (Current Node Output: 2) (Chain Node Output: 2) Router message: Directly return. Reason: Invokers from previous router is empty or conditionRouters is empty. ] Current Node Output: 172.18.111.187:20880,172.18.111.183:20880 + +··· + +dubbo> +``` diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/qos/security.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/qos/introduction/security.md similarity index 100% rename from content/zh-cn/overview/mannual/java-sdk/reference-manual/qos/security.md rename to content/zh-cn/overview/mannual/java-sdk/reference-manual/qos/introduction/security.md diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/qos/service-management.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/qos/introduction/service-management.md similarity index 100% rename from content/zh-cn/overview/mannual/java-sdk/reference-manual/qos/service-management.md rename to content/zh-cn/overview/mannual/java-sdk/reference-manual/qos/introduction/service-management.md diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/qos/logger-management.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/qos/logger-management.md deleted file mode 100644 index 4f42a9d00dd2..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/qos/logger-management.md +++ /dev/null @@ -1,102 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/reference-manual/qos/logger-management/ - - /zh-cn/docs3-v2/java-sdk/reference-manual/qos/logger-management/ -description: 在 Dubbo 中运行时动态切换使用的日志框架 -linkTitle: 日志框架运行时管理 -title: 日志框架运行时管理 -type: docs -weight: 5 ---- - - - - - -{{% alert title="注意" color="primary" %}} - -自 `3.0.10` 开始,dubbo-qos 运行时管控支持查询日志配置以及动态修改使用的日志框架和日志级别。 - -通过 dubbo-qos 修改的日志配置不进行持久化存储,在应用重启后将会失效。 -{{% /alert %}} - -### 查询日志配置 - -命令:`loggerInfo` - -示例: -```bash -> telnet 127.0.0.1 22222 -> loggerInfo -``` - -输出: -``` -Trying 127.0.0.1... -Connected to localhost. -Escape character is '^]'. - ___ __ __ ___ ___ ____ - / _ \ / / / // _ ) / _ ) / __ \ - / // // /_/ // _ |/ _ |/ /_/ / -/____/ \____//____//____/ \____/ -dubbo>loggerInfo -Available logger adapters: [jcl, jdk, log4j, slf4j]. Current Adapter: [log4j]. Log level: INFO -``` - -### 修改日志级别 - -命令:`switchLogLevel {level}` - -level: `ALL`, `TRACE`, `DEBUG`, `INFO`, `WARN`, `ERROR`, `OFF` - -示例: -```bash -> telnet 127.0.0.1 22222 -> switchLogLevel WARN -``` - -输出: -``` -Trying 127.0.0.1... -Connected to localhost. -Escape character is '^]'. - ___ __ __ ___ ___ ____ - / _ \ / / / // _ ) / _ ) / __ \ - / // // /_/ // _ |/ _ |/ /_/ / -/____/ \____//____//____/ \____/ -dubbo>loggerInfo -Available logger adapters: [jcl, jdk, log4j, slf4j]. Current Adapter: [log4j]. Log level: INFO -dubbo>switchLogLevel WARN -OK -dubbo>loggerInfo -Available logger adapters: [jcl, jdk, log4j, slf4j]. Current Adapter: [log4j]. Log level: WARN``` -``` - -### 修改日志输出框架 - -命令:`switchLogger {loggerAdapterName}` - -loggerAdapterName: `slf4j`, `jcl`, `log4j`, `jdk`, `log4j2` - -示例: -```bash -> telnet 127.0.0.1 22222 -> switchLogger slf4j -``` - -输出: -``` -Trying 127.0.0.1... -Connected to localhost. -Escape character is '^]'. - ___ __ __ ___ ___ ____ - / _ \ / / / // _ ) / _ ) / __ \ - / // // /_/ // _ |/ _ |/ /_/ / -/____/ \____//____//____/ \____/ -dubbo>loggerInfo -Available logger adapters: [jcl, slf4j, log4j, jdk]. Current Adapter: [log4j]. Log level: INFO -dubbo>switchLogger slf4j -OK -dubbo>loggerInfo -Available logger adapters: [jcl, slf4j, log4j, jdk]. Current Adapter: [slf4j]. Log level: INFO -``` diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/qos/overview.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/qos/overview.md index 337c4ff33dd3..2bdc5d25367a 100644 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/qos/overview.md +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/qos/overview.md @@ -2,7 +2,7 @@ aliases: - /zh/docs3-v2/java-sdk/reference-manual/qos/overview/ - /zh-cn/docs3-v2/java-sdk/reference-manual/qos/overview/ -description: dubbo 2.5.8 新版本增加了 QOS 模块,提供了新的 telnet 命令支持。 +description: "QoS 命令的设计目的、使用方法说明,包括如何开启、关闭 qos 命令等,支持 HTTP/Telnet 访问方式," linkTitle: QOS 概述 title: QOS 概述 type: docs @@ -10,11 +10,7 @@ weight: 1 --- - - - - -## 参数说明 +## 如何使用 QoS 提供了一些启动参数,来对启动进行配置,他们主要包括: | 参数 | 说明 | 默认值 | @@ -27,7 +23,6 @@ QoS 提供了一些启动参数,来对启动进行配置,他们主要包括 > 注意,从2.6.4/2.7.0开始,qos-accept-foreign-ip默认配置改为false,如果qos-accept-foreign-ip设置为true,有可能带来安全风险,请仔细评估后再打开。 -## 协议 ### telnet 与 http 协议 telnet 模块现在同时支持 http 协议和 telnet 协议,方便各种情况的使用 @@ -64,8 +59,6 @@ As Consumer side: dubbo> ``` -## 其他方式 - ### 端口 新版本的 telnet 端口 与 dubbo 协议的端口是不同的端口,默认为 `22222` @@ -147,8 +140,6 @@ dubbo.application.qos-anonymous-access-permission-level=PROTECTED 来允许匿名访问更高级别的权限的命令。 - - ``` ➜ ~ curl "localhost:22222/ls?arg1=xxx&arg2=xxxx" As Provider side: @@ -217,4 +208,4 @@ dubbo.application.qos-port=33333 dubbo.application.qos-accept-foreign-ip=false dubbo.application.qos-accept-foreign-ip-whitelist=123.12.10.13, 132.12.10.13/24 dubbo.application.qos-anonymous-access-permission-level=NONE -``` \ No newline at end of file + diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/qos/profiler.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/qos/profiler.md deleted file mode 100644 index 940b62fd7d42..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/qos/profiler.md +++ /dev/null @@ -1,82 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/reference-manual/qos/profiler/ - - /zh-cn/docs3-v2/java-sdk/reference-manual/qos/profiler/ -description: 性能采样命令 -linkTitle: 性能采样命令 -title: 性能采样命令 -type: docs -weight: 7 ---- - - - - - - -性能采样功能可以对 Dubbo 处理链路上的各处耗时进行检测,在出现超时的时候 `( usageTime / timeout > profilerWarnPercent * 100 )` 通过日志记录调用的耗时。 - -此功能分为 `simple profiler` 和 `detail profiler` 两个模式,其中 `simple profiler` 模式默认开启,`detail profiler` 模式默认关闭。 -`detail profiler` 相较 `simple profiler` 模式多采集了每个 filter 的处理耗时、协议上的具体耗时等。 -在 `simple profiler` 模式下如果发现 Dubbo 框架内部存在耗时长的情况,可以开启 `detail profiler` 模式,以便更好地排查问题。 - -> [请求耗时采样](../../../advanced-features-and-usage/performance/profiler/) - -### enableSimpleProfiler 命令 - -开启 `simple profiler` 模式,默认开启 - -``` -dubbo>enableSimpleProfiler -OK - -dubbo> -``` - -### disableSimpleProfiler 命令 - -关闭 `simple profiler` 模式,关闭后 `detail profiler` 也将不启用 - -``` -dubbo>disableSimpleProfiler -OK - -dubbo> -``` - -### enableDetailProfiler 命令 - -开启 `detail profiler` 模式,默认关闭,需要开启 `simple profiler` 模式才会真实开启 - -``` -dubbo>enableDetailProfiler -OK. This will cause performance degradation, please be careful! - -dubbo> -``` - -### disableDetailProfiler 命令 - -关闭 `detail profiler` 模式,关闭后不影响 `simple profiler` - -``` -dubbo>disableDetailProfiler -OK - -dubbo> -``` - -### setProfilerWarnPercent 命令 - -设置超时时间的警告百分比 - -命令:`setProfilerWarnPercent {profilerWarnPercent}` - -profilerWarnPercent: 超时时间的警告百分比,取值范围 0.0 ~ 1.0,默认值为 0.75 - -``` -dubbo>setProfilerWarnPercent 0.75 -OK - -dubbo> -``` diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/qos/qos-list.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/qos/qos-list.md new file mode 100644 index 000000000000..7be8be1602f8 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/qos/qos-list.md @@ -0,0 +1,53 @@ +--- +aliases: + - /zh-cn/overview/mannual/java-sdk/reference-manual/qos/command/ +description: "QoS 命令列表、命令大全。" +linkTitle: 命令列表 +title: QoS 命令列表,命令大全 +type: docs +weight: 2 +--- + +| QoS 命令 | 说明 | telnet 用法示例 | http 用法示例 | +| --- | --- | --- | --- | +| cd | 设定服务上下文,cd 之后所有的命令都是针对该服务 | cd org.demo.DemoService | http://localhost:22222/cd?service=org.demo.DemoService | +| count | 展示服务或方法调用次数。暂时只支持 dubbo 协议,不支持 triple 协议;RpcStatus 实现依赖 Active/Limit Filter,需改造 | count org.demo.DemoService

count org.demo.DemoService methodName | http://localhost:22222/count?service=org.demo.DemoService&method=methodName | +| disableDetailProfiler | 关闭 RPC 调用 profiler 工具(细粒度版本) | disableDetailProfiler | http://localhost:22222/disableDetailProfiler | +| disableRouterSnapshot | 关闭 RPC 请求 Router 路由结果跟踪 | disableRouterSnapshot | http://localhost:22222/disableRouterSnapshot | +| disableSimpleProfiler | 关闭 RPC 调用 profiler 工具(粗粒度版) | disableSimpleProfiler | http://localhost:22222/disableSimpleProfiler | +| enableDetailProfiler | 开启 RPC 调用 profiler 工具(细粒度版本) | enableDetailProfiler | http://localhost:22222/enableDetailProfiler | +| enableRouterSnapshot | 开启 RPC 请求 Router 路由结果跟踪,有助于跟踪路由规则执行是否符合预期 | enableRouterSnapshot org.demo.DemoService | http://localhost:22222/enableRouterSnapshot?service=org.demo.DemoService | +| enableSimpleProfiler | 开启 RPC 调用 profiler 工具(粗粒度版) | enableSimpleProfiler | http://localhost:22222/enableSimpleProfiler | +| getAddress | 查看某个服务的有效 ip 地址列表 | getAddress org.demo.DemoService | http://localhost:22222/getAddress?service=org.demo.DemoService | +| getConfig | dump 当前应用的有效配置 | getConfig | http://localhost:22222/getConfig | +| getEnabledRouterSnapshot | 查看当前 “启用 Router 路由结果跟踪” 的服务列表 | getEnabledRouterSnapshot | http://localhost:22222/getEnabledRouterSnapshot | +| getRecentRouterSnapshot | 查看最近 32 条 “Router 路由结果跟踪” 数据 | getRecentRouterSnapshot | http://localhost:22222/getRecentRouterSnapshot | +| gracefulShutdown | 从注册中心下线当前 ip 实例注册的所有服务,与offline的区别是,该命令会同时通过 tcp 连接告知所有消费方停止调用此实例。

如要恢复,请执行 online 上线所有服务 | gracefulShutdown | http://localhost:22222/gracefulShutdown | +| help | 帮助命令 | help | http://localhost:22222/help | +| invoke | 调用某个 RPC 服务 | invoke org.demo.DemoService.methodName(1234, "abcd", {"prop":"value"}) | ? | +| live | 检查当前进程/服务是否存活,可配置为 kubernetes liveness | live | http://localhost:22222/live | +| loggerInfo | 查看当前日志 logger 配置 | loggerInfo | http://localhost:22222/loggerInfo | +| ls | 查看当前所有服务列表 | ls | http://localhost:22222/ls | +| metrics | 查看 metrics 指标,需开启metrics 统计才能看到数据。什么粒度? | metrics | http://localhost:22222/metrics | +| metrics_default | 查看 metrics 指标 ,需开启metrics 统计才能看到数据。什么粒度? | metrics_default | http://localhost:22222/metrics_default | +| offline | 从注册中心下线某个或多个服务(包含应用级和接口级地址) | offline

offline org.demo.DemoService | http://localhost:22222/offline

http://localhost:22222/offline?service=org.demo.DemoService | +| offlineApp | 从注册中心下线某个或多个服务(仅应用级) | offlineApp

offlineApp org.demo.DemoService | http://localhost:22222/offlineApp?service=org.demo.DemoService | +| offlineInterface | 从注册中心下线某个或多个服务(仅接口级) | offlineInterface

offlineInterface org.demo.DemoService | http://localhost:22222/offlineInterface?service=org.demo.DemoService | +| online | 将一个或多个服务注册到注册中心(包含应用级和接口级地址) | online

online org.demo.DemoService | http://localhost:22222/online?service=org.demo.DemoService | +| onlineApp | 将一个或多个服务注册到注册中心(仅应用级) | onlineApp

onlineApp org.demo.DemoService | http://localhost:22222/onlineApp?service=org.demo.DemoService | +| onlineInterface | 将一个或多个服务注册到注册中心(仅接口级) | onlineInterface

onlineInterface org.demo.DemoService | http://localhost:22222/onlineInterface?service=org.demo.DemoService | +| ps | 查看当前进程信息,包括监听的端口等 | ps | http://localhost:22222/ps | +| publishMetadata | 发布或更新当前应用Metadata数据(可用于手动更新应用级服务发现元数据)。publishMetadata 10 表示延迟 10s 发布。在3.3.0之前版本的命令为 publish-metadata | publishMetadata

publishMetadata 10 | http://localhost:22222/publishMetadata | +| pwd | 查看当前服务上下文,与 cd 配合使用 | pwd | http://localhost:22222/pwd | +| quit | 退出当前 telnet 命令 | quit | 无 | +| ready | 检查当前进程/服务是否准备就绪对外服务,可配置为 kubernetes readiness | ready | http://localhost:22222/ready | +| select | 调用方法?和invoke的关系? | ? | http://localhost:22222/? | +| serializeCheckStatus | 检查当前在序列化白名单中的类列表 | serializeCheckStatus | http://localhost:22222/serializeCheckStatus | +| serializeWarnedClasses | 检查当前在序列化警告名单中的类列表 | serializeWarnedClasses | http://localhost:22222/serializeWarnedClasses | +| setProfilerWarnPercent | 控制序列化报警频率(仅限在警告名单中的类) | setProfilerWarnPercent 0.75 | http://localhost:22222/setProfilerWarnPercent?k=0.75 | +| shutdown | 尝试关闭当前 Dubbo 应用(销毁所有资源,重启前无法恢复) | shutdown | http://localhost:22222/shutdown | +| startup | 检查当前进程/服务是否已经正常启动,可配置为 kubernetes startup | startup | http://localhost:22222/startup | +| switchLogLevel | 动态调整日志级别 | switchLogLevel debug | http://localhost:22222/switchLogLevel?k=debug | +| switchLogger | 切换日志logger组件。可用 logger 组件,可通过 loggerInfo 查看(切换前请务必确保应用已经加入相关组件依赖) | switchLogger log4j2 | http://localhost:22222/switchLogger?k=log4j2 | +| version | 查看当前使用的 Dubbo 框架版本 | version | http://localhost:22222/version | + diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/qos/router-snapshot.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/qos/router-snapshot.md deleted file mode 100644 index 8a2c77a7498f..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/qos/router-snapshot.md +++ /dev/null @@ -1,118 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/reference-manual/qos/router-snapshot/ - - /zh-cn/docs3-v2/java-sdk/reference-manual/qos/router-snapshot/ -description: 路由状态命令 -linkTitle: 路由状态命令 -title: 路由状态命令 -type: docs -weight: 8 ---- - - - - - - -Dubbo 的很多流量治理能力是基于 Router 进行实现的,在生产环境中,如果出现流量结果不符合预期的情况,可以通过路由状态命令来查看路由的状态,以此来定位可能存在的问题。 - -> [路由状态采集](../../../advanced-features-and-usage/performance/router-snapshot/) - -### getRouterSnapshot 命令 - -获取当前的每层路由的分组状态。(仅支持 StateRouter) - -命令:`getRouterSnapshot {serviceName}` - -`serviceName` 为需要采集的服务名,支持匹配 - -``` -dubbo>getRouterSnapshot com.dubbo.dubbointegration.BackendService -com.dubbo.dubbointegration.BackendService@2c2e824a -[ All Invokers:2 ] [ Valid Invokers: 2 ] - -MockInvokersSelector Total: 2 -[ Mocked -> Empty (Total: 0) ] -[ Normal -> 172.18.111.187:20880,172.18.111.183:20880 (Total: 2) ] - ↓ -StandardMeshRuleRouter not support - ↓ -TagStateRouter not support - ↓ -ServiceStateRouter not support - ↓ -AppStateRouter not support - ↓ -TailStateRouter End - - -dubbo> -``` - -### enableRouterSnapshot 命令 - -开启路由结果采集模式 - -命令:`enableRouterSnapshot {serviceName}` - -`serviceName` 为需要采集的服务名,支持匹配 - -``` -dubbo>enableRouterSnapshot com.dubbo.* -OK. Found service count: 1. This will cause performance degradation, please be careful! - -dubbo> -``` - -### disableRouterSnapshot 命令 - -关闭路由结果采集模式 - -命令:`disableRouterSnapshot {serviceName}` - -`serviceName` 为需要采集的服务名,支持匹配 - -``` -dubbo>disableRouterSnapshot com.dubbo.* -OK. Found service count: 1 - -dubbo> -``` - -### getEnabledRouterSnapshot 命令 - -获取当前已经开启采集的服务 - -``` -dubbo>getEnabledRouterSnapshot -com.dubbo.dubbointegration.BackendService - -dubbo> -``` - -### getRecentRouterSnapshot 命令 - -通过 qos 命令获取历史的路由状态。(最多存储 32 个结果) - -``` -dubbo>getRecentRouterSnapshot -1658224330156 - Router snapshot service com.dubbo.dubbointegration.BackendService from registry 172.18.111.184 on the consumer 172.18.111.184 using the dubbo version 3.0.9 is below: -[ Parent (Input: 2) (Current Node Output: 2) (Chain Node Output: 2) ] Input: 172.18.111.187:20880,172.18.111.183:20880 -> Chain Node Output: 172.18.111.187:20880,172.18.111.183:20880 - [ MockInvokersSelector (Input: 2) (Current Node Output: 2) (Chain Node Output: 2) Router message: invocation.need.mock not set. Return normal Invokers. ] Current Node Output: 172.18.111.187:20880,172.18.111.183:20880 - [ StandardMeshRuleRouter (Input: 2) (Current Node Output: 2) (Chain Node Output: 2) Router message: MeshRuleCache has not been built. Skip route. ] Current Node Output: 172.18.111.187:20880,172.18.111.183:20880 - [ TagStateRouter (Input: 2) (Current Node Output: 2) (Chain Node Output: 2) Router message: Disable Tag Router. Reason: tagRouterRule is invalid or disabled ] Current Node Output: 172.18.111.187:20880,172.18.111.183:20880 - [ ServiceStateRouter (Input: 2) (Current Node Output: 2) (Chain Node Output: 2) Router message: Directly return. Reason: Invokers from previous router is empty or conditionRouters is empty. ] Current Node Output: 172.18.111.187:20880,172.18.111.183:20880 - [ AppStateRouter (Input: 2) (Current Node Output: 2) (Chain Node Output: 2) Router message: Directly return. Reason: Invokers from previous router is empty or conditionRouters is empty. ] Current Node Output: 172.18.111.187:20880,172.18.111.183:20880 - -1658224330156 - Router snapshot service com.dubbo.dubbointegration.BackendService from registry 172.18.111.184 on the consumer 172.18.111.184 using the dubbo version 3.0.9 is below: -[ Parent (Input: 2) (Current Node Output: 2) (Chain Node Output: 2) ] Input: 172.18.111.187:20880,172.18.111.183:20880 -> Chain Node Output: 172.18.111.187:20880,172.18.111.183:20880 - [ MockInvokersSelector (Input: 2) (Current Node Output: 2) (Chain Node Output: 2) Router message: invocation.need.mock not set. Return normal Invokers. ] Current Node Output: 172.18.111.187:20880,172.18.111.183:20880 - [ StandardMeshRuleRouter (Input: 2) (Current Node Output: 2) (Chain Node Output: 2) Router message: MeshRuleCache has not been built. Skip route. ] Current Node Output: 172.18.111.187:20880,172.18.111.183:20880 - [ TagStateRouter (Input: 2) (Current Node Output: 2) (Chain Node Output: 2) Router message: Disable Tag Router. Reason: tagRouterRule is invalid or disabled ] Current Node Output: 172.18.111.187:20880,172.18.111.183:20880 - [ ServiceStateRouter (Input: 2) (Current Node Output: 2) (Chain Node Output: 2) Router message: Directly return. Reason: Invokers from previous router is empty or conditionRouters is empty. ] Current Node Output: 172.18.111.187:20880,172.18.111.183:20880 - [ AppStateRouter (Input: 2) (Current Node Output: 2) (Chain Node Output: 2) Router message: Directly return. Reason: Invokers from previous router is empty or conditionRouters is empty. ] Current Node Output: 172.18.111.187:20880,172.18.111.183:20880 - -··· - -dubbo> -``` diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/registry/_index.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/registry/_index.md old mode 100644 new mode 100755 index ca74dbcdf409..7d24bc99fd54 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/registry/_index.md +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/registry/_index.md @@ -1,11 +1,10 @@ --- aliases: - - /zh/docs3-v2/java-sdk/reference-manual/registry/ - - /zh-cn/docs3-v2/java-sdk/reference-manual/registry/ - - /zh-cn/overview/what/ecosystem/registry/ -description: Dubbo 注册中心的基本使用和工作原理 -linkTitle: 注册中心 -title: 注册中心 + - /zh/docs3-v2/java-sdk/advanced-features-and-usage/others/ + - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/others/ +description: 注册中心 +linkTitle: 注册中心与服务发现 +title: 注册中心、服务发现与负载均衡 type: docs -weight: 6 +weight: 5 --- diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/registry/multicast/_index.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/registry/multicast/_index.md deleted file mode 100644 index 672a0904958c..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/registry/multicast/_index.md +++ /dev/null @@ -1,60 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/reference-manual/registry/multicast/ - - /zh-cn/docs3-v2/java-sdk/reference-manual/registry/multicast/ -description: Multicast 广播注册中心(限开发阶段使用)。 -linkTitle: Multicast -title: Multicast -type: docs -weight: 4 ---- - - - - - - -Multicast 注册中心不需要启动任何中心节点,只要广播地址一样,就可以互相发现。 - -![/user-guide/images/multicast.jpg](/imgs/user/multicast.jpg) - -## 1 使用说明 - -```xml - -``` - -或 - -```xml - -``` -#### 注意: -为了减少广播量,Dubbo 缺省使用单播发送提供者地址信息给消费者。 -如果一个机器上同时启了多个消费者进程,消费者需声明 `unicast=false`,否则只会有一个消费者能收到消息; 当服务者和消费者运行在同一台机器上,消费者同样需要声明`unicast=false`,否则消费者无法收到消息,导致No provider available for the service异常: - -```xml - - - -``` - -或 - -```xml - - - -``` - - -## 2 工作原理 - -### 2.1 基本流程 -0. 提供方启动时广播自己的地址 -1. 消费方启动时广播订阅请求 -2. 提供方收到订阅请求时,单播自己的地址给订阅者,如果设置了 `unicast=false`,则广播给订阅者 -3. 消费方收到提供方地址时,连接该地址进行 RPC 调用。 - -### 2.2 使用限制 -组播受网络结构限制,只适合小规模应用或开发阶段使用。组播地址段: 224.0.0.0 - 239.255.255.255 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/registry/multiple-registry.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/registry/multiple-registry.md new file mode 100644 index 000000000000..9c0a9e842745 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/registry/multiple-registry.md @@ -0,0 +1,193 @@ +--- +aliases: + - /zh/docs3-v2/java-sdk/reference-manual/registry/multiple-registry/ + - /zh-cn/docs3-v2/java-sdk/reference-manual/registry/multiple-registry/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/multi-registry/ +description: 本文介绍了 Dubbo 的多注册中心支持及使用场景,如何通过多注册/多订阅实现跨区域服务部署、服务迁移等,也描述了同机房有限等跨机房流量调度的实现方式。 +linkTitle: 多注册中心 +title: 多注册中心 +type: docs +weight: 6 +--- + +## 1 关联服务与多注册中心 + +### 1.1 全局默认注册中心 + +Dubbo 注册中心和服务是独立配置的,通常开发者不用设置服务和注册中心组件之间的关联关系,Dubbo 框架会将自动执行以下动作: +* 对于所有的 Service 服务,向所有全局默认注册中心注册服务地址。 +* 对于所有的 Reference 服务,从所有全局默认注册中心订阅服务地址。 + +```yml +# application.yml (Spring Boot) +dubbo + registries + beijingRegistry + address: zookeeper://localhost:2181 + shanghaiRegistry + address: zookeeper://localhost:2182 +``` + +```java +@DubboService +public class DemoServiceImpl implements DemoService {} + +@DubboService +public class HelloServiceImpl implements HelloService {} +``` + +以上以 Spring Boot 开发为例(XML、API 方式类似)配置了两个全局默认注册中心 beijingRegistry 和 shanghaiRegistry,服务 DemoService 与 HelloService 会分别注册到两个默认注册中心。 + +除了上面讲到的框架自动为服务设置全局注册中心之外,有两种方式可以灵活调整服务与多注册中心间的关联。 + +### 1.2 设置全局默认注册中心 +```yml +# application.yml (Spring Boot) +dubbo + registries + beijingRegistry + address: zookeeper://localhost:2181 + default: true + shanghaiRegistry + address: zookeeper://localhost:2182 + default: false +``` + +`default` 用来设置全局默认注册中心,默认值为 `true` 即被视作全局注册中心。未指定注册中心 id 的服务将自动注册或订阅全局默认注册中心。 + +### 1.3 显示关联服务与注册中心 + +通过在 Dubbo 服务定义组件上增加 registry 配置,将服务与注册中心关联起来。 + +```java +@DubboServiceregistry = {"beijingRegistry"} +public class DemoServiceImpl implements DemoService {} + +@DubboServiceregistry = {"shanghaiRegistry"} +public class HelloServiceImpl implements HelloService {} +``` + +增加以上配置后,DemoService 将只注册到 beijingRegistry,而 HelloService 将注册到 shanghaiRegistry。 + +## 2 多注册中心订阅 + +服务订阅由于涉及到地址聚合和路由选址,因此逻辑会更加复杂一些。从单个服务订阅的视角,如果存在多注册中心订阅的情况,则可以根据注册中心间的地址是否聚合分为两种场景。 + +### 2.1 多注册中心地址不聚合 + +```xml + + +``` + +如以上所示独立配置的注册中心组件,地址列表在消费端默认是完全隔离的,负载均衡选址要经过两步: +1. 注册中心集群间选址,选定一个集群 +2. 注册中心集群内选址,在集群内进行地址筛选 + +![multi-registris-no-aggregation](/imgs/v3/registry/no-aggregation.png) + +下面我们着重分析下如何控制 **注册中心集群间选址**,可选的策略有如下几种 +**随机** +每次请求都随机的分配到一个注册中心集群 + +> 随机的过程中会有可用性检查,即每个集群要确保至少有一个地址可用才有可能被选到。 + +**preferred 优先** +```xml + + +``` +如果有注册中心集群配置了 `preferred="true"`,则所有流量都会被路由到这个集群。 + +**weighted** +```xml + + +``` + +基于权重的随机负载均衡,以上集群间会有大概 10:1 的流量分布。 + +**同 zone 优先** +```xml + + +``` + +```java +RpcContext.getContext().setAttachment("registry_zone", "qingdao"); +``` + +根据 Invocation 中带的流量参数或者在当前节点通过 context 上下文设置的参数,流量会被精确的引导到对应的集群。 + +除了通过 RpcContext 参数设置 zone 外,还可以通过扩展 `org.apache.dubbo.rpc.ZoneDetector` 实现,以更灵活的方式确定当前请求的 zone 归属。RuleConverter + +### 2.2 多注册中心地址聚合 +```xml + +``` + +这里增加了一个特殊的 multiple 协议开头的注册中心,其中: +* `multiple://127.0.0.1:2181` 并没有什么具体含义,只是一个特定格式的占位符,地址可以随意指定 +* `reference-registry` 指定了要聚合的注册中心集群的列表,示例中有两个集群,分别是 `zookeeper://address11?backup=address12,address13` 和 `zookeeper://address21?backup=address22,address23`,其中还特别指定了集群分隔符 `separator=";"` + +如下图所示,不同注册中心集群的地址会被聚合到一个地址池后在消费端做负载均衡或路由选址。 + +![multi-registris-aggregation](/imgs/v3/registry/aggregation.png) + +在 3.1.0 版本及之后,还支持每个注册中心集群上设置特定的 attachments 属性,以实现对该注册中心集群下的地址做特定标记,后续配合 Router 组件扩展如 TagRouter 等就可以实现跨机房间的流量治理能力。 + +```xml + +``` + +增加 `attachments=zone=hangzhou,tag=middleware` 后,所有来自该注册中心的 URL 地址将自动携带 `zone` 和 `tag` 两个标识,方便消费端更灵活的做流量治理。 + +## 3 场景示例 + +### 3.1 场景一:跨区域注册服务 + +比如:中文站有些服务来不及在青岛部署,只在杭州部署,而青岛的其它应用需要引用此服务,就可以将服务同时注册到两个注册中心。 + +```xml + + + + +``` + +### 3.2 场景二:根据业务实现隔离 + +CRM 有些服务是专门为国际站设计的,有些服务是专门为中文站设计的。 + +```xml + + + + + + + +``` + +### 3.3 场景三:根据业务调用服务 + +CRM 需同时调用中文站和国际站的 PC2 服务,PC2 在中文站和国际站均有部署,接口及版本号都一样,但连的数据库不一样。 + +```xml + + + + + + + +``` + +如果只是测试环境临时需要连接两个不同注册中心,使用竖号分隔多个不同注册中心地址: + +```xml + + + + +``` diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/registry/multiple-registry/_index.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/registry/multiple-registry/_index.md deleted file mode 100644 index e2882aa86e6c..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/registry/multiple-registry/_index.md +++ /dev/null @@ -1,195 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/reference-manual/registry/multiple-registry/ - - /zh-cn/docs3-v2/java-sdk/reference-manual/registry/multiple-registry/ -description: 本文介绍了 Dubbo 的多注册中心支持及使用场景,如何通过多注册/多订阅实现跨区域服务部署、服务迁移等,也描述了同机房有限等跨机房流量调度的实现方式。 -linkTitle: 多注册中心 -title: 多注册中心 -type: docs -weight: 6 ---- - - - - - - -## 1 关联服务与多注册中心 - -### 1.1 全局默认注册中心 - -Dubbo 注册中心和服务是独立配置的,通常开发者不用设置服务和注册中心组件之间的关联关系,Dubbo 框架会将自动执行以下动作: -* 对于所有的 Service 服务,向所有全局默认注册中心注册服务地址。 -* 对于所有的 Reference 服务,从所有全局默认注册中心订阅服务地址。 - -```yml -# application.yml (Spring Boot) -dubbo - registries - beijingRegistry - address: zookeeper://localhost:2181 - shanghaiRegistry - address: zookeeper://localhost:2182 -``` - -```java -@DubboService -public class DemoServiceImpl implements DemoService {} - -@DubboService -public class HelloServiceImpl implements HelloService {} -``` - -以上以 Spring Boot 开发为例(XML、API 方式类似)配置了两个全局默认注册中心 beijingRegistry 和 shanghaiRegistry,服务 DemoService 与 HelloService 会分别注册到两个默认注册中心。 - -除了上面讲到的框架自动为服务设置全局注册中心之外,有两种方式可以灵活调整服务与多注册中心间的关联。 - -### 1.2 设置全局默认注册中心 -```yml -# application.yml (Spring Boot) -dubbo - registries - beijingRegistry - address: zookeeper://localhost:2181 - default: true - shanghaiRegistry - address: zookeeper://localhost:2182 - default: false -``` - -`default` 用来设置全局默认注册中心,默认值为 `true` 即被视作全局注册中心。未指定注册中心 id 的服务将自动注册或订阅全局默认注册中心。 - -### 1.3 显示关联服务与注册中心 - -通过在 Dubbo 服务定义组件上增加 registry 配置,将服务与注册中心关联起来。 - -```java -@DubboServiceregistry = {"beijingRegistry"} -public class DemoServiceImpl implements DemoService {} - -@DubboServiceregistry = {"shanghaiRegistry"} -public class HelloServiceImpl implements HelloService {} -``` - -增加以上配置后,DemoService 将只注册到 beijingRegistry,而 HelloService 将注册到 shanghaiRegistry。 - -## 2 多注册中心订阅 - -服务订阅由于涉及到地址聚合和路由选址,因此逻辑会更加复杂一些。从单个服务订阅的视角,如果存在多注册中心订阅的情况,则可以根据注册中心间的地址是否聚合分为两种场景。 - -### 2.1 多注册中心地址不聚合 - -```xml - - -``` - -如以上所示独立配置的注册中心组件,地址列表在消费端默认是完全隔离的,负载均衡选址要经过两步: -1. 注册中心集群间选址,选定一个集群 -2. 注册中心集群内选址,在集群内进行地址筛选 - -![multi-registris-no-aggregation](/imgs/v3/registry/no-aggregation.png) - -下面我们着重分析下如何控制 **注册中心集群间选址**,可选的策略有如下几种 -**随机** -每次请求都随机的分配到一个注册中心集群 - -> 随机的过程中会有可用性检查,即每个集群要确保至少有一个地址可用才有可能被选到。 - -**preferred 优先** -```xml - - -``` -如果有注册中心集群配置了 `preferred="true"`,则所有流量都会被路由到这个集群。 - -**weighted** -```xml - - -``` - -基于权重的随机负载均衡,以上集群间会有大概 10:1 的流量分布。 - -**同 zone 优先** -```xml - - -``` - -```java -RpcContext.getContext().setAttachment("registry_zone", "qingdao"); -``` - -根据 Invocation 中带的流量参数或者在当前节点通过 context 上下文设置的参数,流量会被精确的引导到对应的集群。 - -### 2.2 多注册中心地址聚合 -```xml - -``` - -这里增加了一个特殊的 multiple 协议开头的注册中心,其中: -* `multiple://127.0.0.1:2181` 并没有什么具体含义,只是一个特定格式的占位符,地址可以随意指定 -* `reference-registry` 指定了要聚合的注册中心集群的列表,示例中有两个集群,分别是 `zookeeper://address11?backup=address12,address13` 和 `zookeeper://address21?backup=address22,address23`,其中还特别指定了集群分隔符 `separator=";"` - -如下图所示,不同注册中心集群的地址会被聚合到一个地址池后在消费端做负载均衡或路由选址。 - -![multi-registris-aggregation](/imgs/v3/registry/aggregation.png) - -在 3.1.0 版本及之后,还支持每个注册中心集群上设置特定的 attachments 属性,以实现对该注册中心集群下的地址做特定标记,后续配合 Router 组件扩展如 TagRouter 等就可以实现跨机房间的流量治理能力。 - -```xml - -``` - -增加 `attachments=zone=hangzhou,tag=middleware` 后,所有来自该注册中心的 URL 地址将自动携带 `zone` 和 `tag` 两个标识,方便消费端更灵活的做流量治理。 - -## 3 场景示例 - -### 3.1 场景一:跨区域注册服务 - -比如:中文站有些服务来不及在青岛部署,只在杭州部署,而青岛的其它应用需要引用此服务,就可以将服务同时注册到两个注册中心。 - -```xml - - - - -``` - -### 3.2 场景二:根据业务实现隔离 - -CRM 有些服务是专门为国际站设计的,有些服务是专门为中文站设计的。 - -```xml - - - - - - - -``` - -### 3.3 场景三:根据业务调用服务 - -CRM 需同时调用中文站和国际站的 PC2 服务,PC2 在中文站和国际站均有部署,接口及版本号都一样,但连的数据库不一样。 - -```xml - - - - - - - -``` - -如果只是测试环境临时需要连接两个不同注册中心,使用竖号分隔多个不同注册中心地址: - -```xml - - - - -``` \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/registry/nacos.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/registry/nacos.md new file mode 100644 index 000000000000..98edcb84973d --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/registry/nacos.md @@ -0,0 +1,210 @@ +--- +aliases: + - /zh/docs3-v2/java-sdk/advanced-features-and-usage/performance/loadbalance/ + - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/performance/loadbalance/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/others/graceful-shutdown/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/consistent-hash/ +description: "通过示例演示如何使用 Nacos 作为注册中心实现自动服务发现。" +linkTitle: nacos +title: 使用 Nacos 作为注册中心实现自动服务发现 +type: docs +weight: 4 +--- + +本示例演示 Nacos 作为注册中心实现自动服务发现,示例基于 Spring Boot 应用展开,可在此查看 [完整示例代码](https://github.com/apache/dubbo-samples/tree/master/3-extensions/registry/dubbo-samples-nacos) + +## 1 基本配置 + +### 1.1 增加依赖 + +对于 Spring Boot 应用,可以使用如下 spring-boot-starter: +```xml + + org.apache.dubbo + dubbo-spring-boot-starter + 3.3.0 + + + org.apache.dubbo + dubbo-nacos-spring-boot-starter + 3.3.0 + +``` + +非 Spring Boot 用户,可以自行增加 dubbo、nacos-client 依赖: +```xml + + + org.apache.dubbo + dubbo + 3.3.0 + + + com.alibaba.nacos + nacos-client + 2.1.0 + + +``` + +### 1.2 Nacos 版本 +Nacos 版本映射关系: +| Dubbo | 推荐 Nacos 版本 | Nacos 兼容范围 | +| --- | --- | --- | +| 3.3.0 | 2.3.0 | 2.x | +| 3.2.21 | 2.1.0 | 2.x | +| 3.1.11 | 2.0.9 | 2.x | +| 3.0.10 | 2.0.9 | 2.x | +| 2.7.21 | 1.x最新版本 | 1.x | +| 2.6.0 | 1.x最新版本 | 1.x | + +### 1.3 配置并启用 Nacos + +```yaml +# application.yml (Spring Boot) +dubbo + registry + address: nacos://localhost:8848 +``` +或 +```properties +# dubbo.properties +dubbo.registry.address=nacos://localhost:8848 +``` +或 +```xml + +``` + +## 2 高级配置 + +### 2.1 认证 + +```yaml +# application.yml (Spring Boot) +dubbo + registry + address: nacos://localhost:8848?username=nacos&password=nacos +``` + +或 + +```properties +# dubbo.properties +dubbo.registry.address: nacos://nacos:nacos@localhost:8848 +``` + +### 2.2 自定义命名空间 + +```yaml +# application.yml (Spring Boot) +dubbo: + registry: + address: nacos://localhost:8848?namespace=5cbb70a5-xxx-xxx-xxx-d43479ae0932 +``` + +或者 + +```yaml +# application.yml (Spring Boot) +dubbo: + registry: + address: nacos://localhost:8848 + parameters.namespace: 5cbb70a5-xxx-xxx-xxx-d43479ae0932 +``` + +### 2.3 自定义分组 + +```yaml +# application.yml +dubbo: + registry: + address: nacos://localhost:8848 + group: dubbo +``` + +> 如果不配置的话,group 是由 Nacos 默认指定。group 和 namespace 在 Nacos 中代表不同的隔离层次,通常来说 namespace 用来隔离不同的用户或环境,group 用来对同一环境内的数据做进一步归组。 + +### 2.4 注册接口级消费者 +Dubbo 3.0.0 版本以后,增加了是否注册消费者的参数,如果需要将消费者注册到 nacos 注册中心上,需要将参数(register-consumer-url)设置为true,默认是false。 +```yaml +# application.yml +dubbo: + registry: + address: nacos://localhost:8848?register-consumer-url=true +``` +或者 +```yaml +# application.yml +dubbo: + registry: + address: nacos://localhost:8848 + parameters.register-consumer-url: true +``` + +### 2.5 更多配置 + +参数名 | 中文描述| 默认值 +---|---|--- +username|连接Nacos Server的用户名|nacos +paasword|连接Nacos Server的密码|nacos +backup|备用地址|空 +namespace|命名空间的ID|public +group|分组名称|DEFAULT_GROUP +register-consumer-url|是否注册消费端|false +com.alibaba.nacos.naming.log.filename|初始化日志文件名|naming.log +endpoint|连接Nacos Server指定的连接点,可参考[文档](https://nacos.io/zh-cn/blog/address-server.html)|空 +endpointPort|连接Nacos Server指定的连接点端口,可以参考[文档](https://nacos.io/zh-cn/blog/address-server.html)|空 +endpointQueryParams|endpoint查参数询|空 +isUseCloudNamespaceParsing|是否解析云环境中的namespace参数|true +isUseEndpointParsingRule|是否开启endpoint 参数规则解析|true +namingLoadCacheAtStart|启动时是否优先读取本地缓存|true +namingCacheRegistryDir|指定缓存子目录,位置为 .../nacos/{SUB_DIR}/naming|空 +namingClientBeatThreadCount|客户端心跳的线程池大小|机器的CPU数的一半 +namingPollingThreadCount|客户端定时轮询数据更新的线程池大小|机器的CPU数的一半 +namingRequestDomainMaxRetryCount|client通过HTTP向Nacos Server请求的重试次数|3 +namingPushEmptyProtection|在服务没有有效(健康)实例时,是否开启保护,开启后则会使用旧的服务实例|false +push.receiver.udp.port|客户端UDP的端口|空 + +在nacos-server@`1.0.0`版本后,支持客户端通过上报一些包含特定的元数据的实例到服务端来控制实例的一些行为。 + +参数名 | 中文描述| 默认值 +---|---|--- +preserved.heart.beat.timeout|该实例在不发送心跳后,从健康到不健康的时间(毫秒)|15000 +preserved.ip.delete.timeout|该实例在不发送心跳后,被服务端下掉该实例的时间(毫秒)|30000 +preserved.heart.beat.interval|该实例在客户端上报心跳的间隔时间(毫秒)|5000 +preserved.instance.id.generator|该实例的id生成策略,值为`snowflake`时,从0开始增加|simple +preserved.register.source|注册实例注册时服务框架类型(例如Dubbo,Spring Cloud等)|空 + + 这些参数都可以类似 `namespace` 的方式通过通过参数扩展配置到 Nacos,如 + + ```properties + dubbo.registry.parameters.preserved.heart.beat.timeout=5000 + ``` + +## 3 工作原理 + +在前面的一节中,我们讲解了应用级服务发现与接口级服务发现的区别,以下是两种模式在 Nacos 实现中的具体存储结构。 + +### 3.1 Dubbo2 注册数据 + +随后,重启您的 Dubbo 应用,Dubbo 的服务提供和消费信息在 Nacos 控制台中可以显示: + +![dubbo-registry-nacos-1.png](/imgs/blog/dubbo-registry-nacos-1.png) + +如图所示,服务名前缀为 `providers:` 的信息为服务提供者的元信息,`consumers:` 则代表服务消费者的元信息。点击“**详情**”可查看服务状态详情: + +![image-dubbo-registry-nacos-2.png](/imgs/blog/dubbo-registry-nacos-2.png) + +### 3.2 Dubbo3 注册数据 +应用级服务发现的 "服务名" 为应用名 + +> Dubbo3 默认采用 "应用级服务发现 + 接口级服务发现" 的双注册模式,因此会发现应用级服务(应用名)和接口级服务(接口名)同时出现在 Nacos 控制台,可以通过配置 `dubbo.registry.register-mode=instance/interface/all` 来改变注册行为。 + +### 3.3 客户端缓存 + +### 3.4 心跳检测 + +### 3.5 + + diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/registry/nacos/_index.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/registry/nacos/_index.md deleted file mode 100644 index 9a0d516bc251..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/registry/nacos/_index.md +++ /dev/null @@ -1,199 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/reference-manual/registry/nacos/ - - /zh-cn/docs3-v2/java-sdk/reference-manual/registry/nacos/ - - /zh-cn/overview/what/ecosystem/registry/nacos/ -description: Nacos 注册中心的基本使用和工作原理。 -linkTitle: Nacos -title: Nacos -type: docs -weight: 3 ---- - - - - - - -## 1 前置条件 -* 了解 [Dubbo 基本开发步骤](../../../quick-start/spring-boot/) -* 安装并启动 [Nacos 服务](https://nacos.io/zh-cn/docs/quick-start.html) ->当Dubbo使用`3.0.0`及以上版本时,需要使用Nacos `2.0.0`及以上版本。 - -## 2 使用说明 -在此查看[完整示例代码](https://github.com/apache/dubbo-samples/tree/master/3-extensions/registry/dubbo-samples-nacos/dubbo-samples-nacos-registry) - -### 2.1 增加依赖 -```xml - - - org.apache.dubbo - dubbo - 3.0.9 - - - com.alibaba.nacos - nacos-client - 2.1.0 - - - - -``` -增加 Dubbo 与 Nacos 依赖 - -> Dubbo `3.0.0` 及以上版本需 nacos-client `2.0.0` 及以上版本 - -### 2.2 配置并启用 Nacos - -```yaml -# application.yml (Spring Boot) -dubbo - registry - address: nacos://localhost:8848 -``` -或 -```properties -# dubbo.properties -dubbo.registry.address=nacos://localhost:8848 -``` -或 -```xml - -``` - -启用应用,查看注册后的效果或工作原理,请查看 [工作原理](#4-工作原理)。 - -## 3 高级配置 - -### 3.1 认证 - -```yaml -# application.yml (Spring Boot) -dubbo - registry - address: nacos://localhost:8848?username=nacos&password=nacos -``` - -或 - -```properties -# dubbo.properties -dubbo.registry.address: nacos://nacos:nacos@localhost:8848 -``` - -### 3.2 自定义命名空间 - -```yaml -# application.yml (Spring Boot) -dubbo: - registry: - address: nacos://localhost:8848?namespace=5cbb70a5-xxx-xxx-xxx-d43479ae0932 -``` - -或者 - -```yaml -# application.yml (Spring Boot) -dubbo: - registry: - address: nacos://localhost:8848 - parameters.namespace: 5cbb70a5-xxx-xxx-xxx-d43479ae0932 -``` - -### 3.3 自定义分组 - -```yaml -# application.yml -dubbo: - registry: - address: nacos://localhost:8848 - group: dubbo -``` - -> 如果不配置的话,group 是由 Nacos 默认指定。group 和 namespace 在 Nacos 中代表不同的隔离层次,通常来说 namespace 用来隔离不同的用户或环境,group 用来对同一环境内的数据做进一步归组。 - -### 3.4 注册接口级消费者 -Dubbo3.0.0版本以后,增加了是否注册消费者的参数,如果需要将消费者注册到nacos注册中心上,需要将参数(register-consumer-url)设置为true,默认是false。 -```yaml -# application.yml -dubbo: - registry: - address: nacos://localhost:8848?register-consumer-url=true -``` -或者 -```yaml -# application.yml -dubbo: - registry: - address: nacos://localhost:8848 - parameters.register-consumer-url: true - -``` - -### 3.5 更多配置 - -参数名 | 中文描述| 默认值 ----|---|--- -username|连接Nacos Server的用户名|nacos -paasword|连接Nacos Server的密码|nacos -backup|备用地址|空 -namespace|命名空间的ID|public -group|分组名称|DEFAULT_GROUP -register-consumer-url|是否注册消费端|false -com.alibaba.nacos.naming.log.filename|初始化日志文件名|naming.log -endpoint|连接Nacos Server指定的连接点,可参考[文档](https://nacos.io/zh-cn/blog/address-server.html)|空 -endpointPort|连接Nacos Server指定的连接点端口,可以参考[文档](https://nacos.io/zh-cn/blog/address-server.html)|空 -endpointQueryParams|endpoint查参数询|空 -isUseCloudNamespaceParsing|是否解析云环境中的namespace参数|true -isUseEndpointParsingRule|是否开启endpoint 参数规则解析|true -namingLoadCacheAtStart|启动时是否优先读取本地缓存|true -namingCacheRegistryDir|指定缓存子目录,位置为 .../nacos/{SUB_DIR}/naming|空 -namingClientBeatThreadCount|客户端心跳的线程池大小|机器的CPU数的一半 -namingPollingThreadCount|客户端定时轮询数据更新的线程池大小|机器的CPU数的一半 -namingRequestDomainMaxRetryCount|client通过HTTP向Nacos Server请求的重试次数|3 -namingPushEmptyProtection|在服务没有有效(健康)实例时,是否开启保护,开启后则会使用旧的服务实例|false -push.receiver.udp.port|客户端UDP的端口|空 - -在nacos-server@`1.0.0`版本后,支持客户端通过上报一些包含特定的元数据的实例到服务端来控制实例的一些行为。 - -参数名 | 中文描述| 默认值 ----|---|--- -preserved.heart.beat.timeout|该实例在不发送心跳后,从健康到不健康的时间(毫秒)|15000 -preserved.ip.delete.timeout|该实例在不发送心跳后,被服务端下掉该实例的时间(毫秒)|30000 -preserved.heart.beat.interval|该实例在客户端上报心跳的间隔时间(毫秒)|5000 -preserved.instance.id.generator|该实例的id生成策略,值为`snowflake`时,从0开始增加|simple -preserved.register.source|注册实例注册时服务框架类型(例如Dubbo,Spring Cloud等)|空 - - 这些参数都可以类似 `namespace` 的方式通过通过参数扩展配置到 Nacos,如 - - ```properties - dubbo.registry.parameters.preserved.heart.beat.timeout=5000 - ``` - -## 4 工作原理 - -以下仅为展示 Nacos 作为 Dubbo 注册中心的工作原理,Dubbo 服务运维建议使用 [Dubbo Admin](https://github.com/apache/dubbo-admin) - -### 4.1 Dubbo2 注册数据 - -随后,重启您的 Dubbo 应用,Dubbo 的服务提供和消费信息在 Nacos 控制台中可以显示: - -![dubbo-registry-nacos-1.png](/imgs/blog/dubbo-registry-nacos-1.png) - -如图所示,服务名前缀为 `providers:` 的信息为服务提供者的元信息,`consumers:` 则代表服务消费者的元信息。点击“**详情**”可查看服务状态详情: - -![image-dubbo-registry-nacos-2.png](/imgs/blog/dubbo-registry-nacos-2.png) - -### 4.2 Dubbo3 注册数据 -应用级服务发现的 "服务名" 为应用名 - - - -> Dubbo3 默认采用 "应用级服务发现 + 接口级服务发现" 的双注册模式,因此会发现应用级服务(应用名)和接口级服务(接口名)同时出现在 Nacos 控制台,可以通过配置 `dubbo.registry.register-mode=instance/interface/all` 来改变注册行为。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/registry/others/_index.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/registry/others/_index.md new file mode 100755 index 000000000000..11c5e2e0865b --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/registry/others/_index.md @@ -0,0 +1,10 @@ +--- +aliases: + - /zh/docs3-v2/java-sdk/advanced-features-and-usage/others/ + - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/others/ +description: 注册中心 +linkTitle: 扩展实现 +title: 注册中心、服务发现与负载均衡 +type: docs +weight: 100 +--- diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/registry/others/consul.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/registry/others/consul.md new file mode 100644 index 000000000000..406b76ed516a --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/registry/others/consul.md @@ -0,0 +1,53 @@ +--- +description: Consul 注册中心的基本使用和工作原理。 +linkTitle: Consul +title: Consul +type: docs +weight: 5 +--- + + +## 前置条件 +* 了解 [Dubbo 基本开发步骤](/zh-cn/overview/mannual/java-sdk/quick-start/starter/) +* 安装并启动 [Consul](http://consul.io) 服务 + +## 使用说明 + +### 添加依赖 + +从 Dubbo3 开始,consul 注册中国适配已经不再内嵌在 Dubbo 中,使用前需要单独引入独立的[模块](/zh-cn/download/spi-extensions/#dubbo-registry)。 + +```xml + + org.apache.dubbo.extensions + dubbo-registry-consul + 3.3.0 + +``` + +### 基本配置 +```xml + +``` + +或 + +```xml + +``` + +或 + +```xml + +``` + +或 + +```xml + +``` + +## 使用场景 + +使用 Consul 作为共享注册中心实现,可用于 [Dubbo 与 Spring Cloud 体系的互通或迁移](/zh-cn/blog/2023/10/07/微服务最佳实践零改造实现-spring-cloud-apache-dubbo-互通/) diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/registry/others/etcd.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/registry/others/etcd.md new file mode 100644 index 000000000000..aa8475231df5 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/registry/others/etcd.md @@ -0,0 +1,50 @@ +--- +description: Etcd 注册中心的基本使用和工作原理。 +linkTitle: Etcd +title: Etcd +type: docs +weight: 5 +--- + + + +## 前置条件 +* 了解 [Dubbo 基本开发步骤](/zh-cn/overview/mannual/java-sdk/quick-start/starter/) +* 安装并启动 Etcd 服务 + +## 使用说明 + +### 添加依赖 + +从 Dubbo3 开始,etcd 注册中心适配已经不再内嵌在 Dubbo 中,使用前需要单独引入独立的[模块](/zh-cn/download/spi-extensions/#dubbo-registry)。 + +```xml + + org.apache.dubbo.extensions + dubbo-registry-etcd + 3.3.0 + +``` + +### 基本配置 +```xml + +``` + +或 + +```xml + +``` + +或 + +```xml + +``` + +或 + +```xml + +``` \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/registry/others/multicast.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/registry/others/multicast.md new file mode 100644 index 000000000000..6abd7d91df08 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/registry/others/multicast.md @@ -0,0 +1,61 @@ +--- +aliases: + - /zh/docs3-v2/java-sdk/reference-manual/registry/multicast/ + - /zh-cn/docs3-v2/java-sdk/reference-manual/registry/multicast/ + - /zh-cn/overview/mannual/java-sdk/reference-manual/registry/multicast/ +description: Multicast 广播注册中心(限开发阶段使用)。 +linkTitle: Multicast +title: Multicast +type: docs +weight: 4 +--- + + + + + + +Multicast 注册中心不需要启动任何中心节点,只要广播地址一样,就可以互相发现。 + +![/user-guide/images/multicast.jpg](/imgs/user/multicast.jpg) + +## 1 使用说明 + +```xml + +``` + +或 + +```xml + +``` +#### 注意: +为了减少广播量,Dubbo 缺省使用单播发送提供者地址信息给消费者。 +如果一个机器上同时启了多个消费者进程,消费者需声明 `unicast=false`,否则只会有一个消费者能收到消息; 当服务者和消费者运行在同一台机器上,消费者同样需要声明`unicast=false`,否则消费者无法收到消息,导致No provider available for the service异常: + +```xml + + + +``` + +或 + +```xml + + + +``` + + +## 2 工作原理 + +### 2.1 基本流程 +0. 提供方启动时广播自己的地址 +1. 消费方启动时广播订阅请求 +2. 提供方收到订阅请求时,单播自己的地址给订阅者,如果设置了 `unicast=false`,则广播给订阅者 +3. 消费方收到提供方地址时,连接该地址进行 RPC 调用。 + +### 2.2 使用限制 +组播受网络结构限制,只适合小规模应用或开发阶段使用。组播地址段: 224.0.0.0 - 239.255.255.255 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/registry/others/redis.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/registry/others/redis.md new file mode 100644 index 000000000000..8a05e862de48 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/registry/others/redis.md @@ -0,0 +1,94 @@ +--- +aliases: + - /zh/docs3-v2/java-sdk/reference-manual/registry/redis/ + - /zh-cn/docs3-v2/java-sdk/reference-manual/registry/redis/ + - /zh-cn/overview/what/ecosystem/registry/redis/ + - /zh-cn/overview/mannual/java-sdk/reference-manual/registry/redis/ +description: Redis 注册中心的基本使用和工作原理。 +linkTitle: Redis +title: Redis +type: docs +weight: 5 +--- + + + +## 前置条件 +* 了解 [Dubbo 基本开发步骤](/zh-cn/overview/mannual/java-sdk/quick-start/starter/) +* 安装并启动 [Redis](http://redis.io) 服务 + +## 使用说明 + +### 添加依赖 + +从 Dubbo3 开始,redis 注册中心适配已经不再内嵌在 Dubbo 中,使用前需要单独引入独立的[模块](/zh-cn/download/spi-extensions/#dubbo-registry)。 + +```xml + + org.apache.dubbo.extensions + dubbo-registry-redis + 3.3.0 + +``` + +### 基本配置 +```xml + +``` + +或 + +```xml + +``` + +或 + +```xml + +``` + +或 + +```xml + +``` + +### 其他配置项 + +* 可通过 `` 设置 redis 中 key 的前缀,缺省为 `dubbo`。 +* 可通过 `` 设置 redis 集群策略,缺省为 `failover`: + * `failover`: 只写入和读取任意一台,失败时重试另一台,需要服务器端自行配置数据同步 + * `replicate`: 在客户端同时写入所有服务器,只读取单台,服务器端不需要同步,注册中心集群增大,性能压力也会更大 + + +## 工作原理 + +基于 Redis [^1] 实现的注册中心。 + +Redis 过期数据通过心跳的方式检测脏数据,服务器时间必须同步,并且对服务器有一定压力,否则过期检测会不准确 + +![/user-guide/images/dubbo-redis-registry.jpg](/imgs/user/dubbo-redis-registry.jpg) + +使用 Redis 的 Key/Map 结构存储数据结构: + +* 主 Key 为服务名和类型 +* Map 中的 Key 为 URL 地址 +* Map 中的 Value 为过期时间,用于判断脏数据,脏数据由监控中心删除 [^3] + +使用 Redis 的 Publish/Subscribe 事件通知数据变更: + +* 通过事件的值区分事件类型:`register`, `unregister`, `subscribe`, `unsubscribe` +* 普通消费者直接订阅指定服务提供者的 Key,只会收到指定服务的 `register`, `unregister` 事件 +* 监控中心通过 `psubscribe` 功能订阅 `/dubbo/*`,会收到所有服务的所有变更事件 + +调用过程: + +0. 服务提供方启动时,向 `Key:/dubbo/com.foo.BarService/providers` 下,添加当前提供者的地址 +1. 并向 `Channel:/dubbo/com.foo.BarService/providers` 发送 `register` 事件 +2. 服务消费方启动时,从 `Channel:/dubbo/com.foo.BarService/providers` 订阅 `register` 和 `unregister` 事件 +3. 并向 `Key:/dubbo/com.foo.BarService/consumers` 下,添加当前消费者的地址 +4. 服务消费方收到 `register` 和 `unregister` 事件后,从 `Key:/dubbo/com.foo.BarService/providers` 下获取提供者地址列表 +5. 服务监控中心启动时,从 `Channel:/dubbo/*` 订阅 `register` 和 `unregister`,以及 `subscribe` 和`unsubsribe `事件 +6. 服务监控中心收到 `register` 和 `unregister` 事件后,从 `Key:/dubbo/com.foo.BarService/providers` 下获取提供者地址列表 +7. 服务监控中心收到 `subscribe` 和 `unsubsribe` 事件后,从 `Key:/dubbo/com.foo.BarService/consumers` 下获取消费者地址列表 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/registry/overview.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/registry/overview.md new file mode 100644 index 000000000000..2fe82a1643fa --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/registry/overview.md @@ -0,0 +1,89 @@ +--- +aliases: + - /zh/docs3-v2/java-sdk/reference-manual/registry/overview/ + - /zh-cn/docs3-v2/java-sdk/reference-manual/registry/overview/ +description: "" +linkTitle: 注册中心概述 +title: 注册中心概述 +type: docs +weight: 1 +--- + + +注册中心是 Dubbo 服务治理的核心组件,Dubbo 依赖注册中心的协调实现服务(地址)发现,自动化的服务发现是微服务实现动态扩缩容、负载均衡、、流量治理的基础。Dubbo 的服务发现机制经历了 Dubbo2 时代的接口级服务发现、Dubbo3 时代的应用级服务发现,具体可参见 [服务发现机制](/zh-cn/overview/mannual/java-sdk/concepts-and-architecture/service-discovery/) 解析了解具体演进过程。 + +![service-discovery](/imgs/v3/feature/service-discovery/arc.png) + +## 基本使用 +开发应用时可以指定 Dubbo 注册中心(registry)组件,配置很简单,只需指定注册中心的集群地址即可: + +以 Spring Boot 开发为例,在 application.yml 增加 registry 配置项目 + +```yaml +dubbo + registry + address: {protocol}://{cluster-address} +``` +其中,protocol 为选择的配置中心类型,cluster-address 为访问注册中心的集群地址,如 + +`address: nacos://localhost:8848` + +如需集群格式地址可使用 backup 参数 + +`address: nacos://localhost:8848?backup=localshot:8846,localshot:8847` + +{{% alert title="流的语义保证" color="info" %}} +3.3.0 及之后的版本可不配置注册中心。而在 3.3.0 版本之前的 Dubbo 应用必须指定注册中心配置,即使不启用注册中心也要配置(可通过设置地址为空 address='N/A' )。 +{{% /alert %}} + +每个注册中心组件有自己特有的配置,可以用来控制命名空间、分组、鉴权等,具体可以参考 [registry 配置参考手册](/zh-cn/overview/mannual/java-sdk/reference-manual/config/properties/#registry)或通过 parameters 参数进行扩展。 + +## 配置中心与元数据中心 +配置中心、元数据中心是实现 Dubbo 高阶服务治理能力会依赖的组件,如流量管控规则等,相比于注册中心通常这两个组件的配置是可选的。 + +需要注意的是,**对于部分注册中心类型(如 Zookeeper、Nacos 等),Dubbo 会默认同时将其用作元数据中心和配置中心(建议保持默认开启状态)。** + +```yaml +dubbo + registry + address: nacos://localhost:8848 +``` + +框架解析后的默认行为: + +```yaml +dubbo + registry + address: nacos://localhost:8848 + config-center + address: nacos://localhost:8848 + metadata-report + address: nacos://localhost:8848 +``` + +如果您不想使用 nacos 作为配置中心,可以通过以下两个参数来调整或控制默认行为: + +```yaml +dubbo + registry + address: nacos://localhost:8848 + use-as-config-center: false + use-as-metadata-report: false + config-center + address: apollo://localhost:8848 +``` + +## 注册中心生态 +Dubbo 目前支持的主流注册中心实现包括: +* Zookeeper +* Nacos +* Redis +* Consul +* Etcd +* 更多实现 + +同时也支持 Kubernetes、Mesh 体系的服务发现,具体请参考 [使用教程 - kubernetes部署](http://localhost:1313/zh-cn/overview/mannual/java-sdk/tasks/deploy/) + +另外,[Dubbo 扩展生态](https://github.com/apache/dubbo-spi-extensions) 还提供了 Consul、Eureka、Etcd 等注册中心扩展实现。也欢迎通过 [registry spi 扩展](../../spi/) 贡献更多的注册中心实现到 Dubbo 生态。 + +Dubbo 还支持在一个应用中 [指定多个注册中心](../multiple-registry/),并将服务根据注册中心分组,这样做使得服务分组管理或服务迁移变得更容易。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/registry/overview/_index.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/registry/overview/_index.md deleted file mode 100644 index 9e2a4c1643ac..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/registry/overview/_index.md +++ /dev/null @@ -1,80 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/reference-manual/registry/overview/ - - /zh-cn/docs3-v2/java-sdk/reference-manual/registry/overview/ -description: "" -linkTitle: 注册中心概述 -title: 注册中心概述 -type: docs -weight: 1 ---- - - -注册中心是 Dubbo 服务治理的核心组件,Dubbo 依赖注册中心的协调实现服务(地址)发现,自动化的服务发现是微服务实现动态扩缩容、负载均衡、、流量治理的基础。Dubbo 的服务发现机制经历了 Dubbo2 时代的接口级服务发现、Dubbo3 时代的应用级服务发现,具体可参见 [服务发现机制](/zh-cn/overview/mannual/java-sdk/concepts-and-architecture/service-discovery/) 解析了解具体演进过程。 - -## 基本使用 -开发应用时必须指定 Dubbo 注册中心(registry)组件,配置很简单,只需指定注册中心的集群地址即可: - -以 Spring Boot 开发为例,在 application.yml 增加 registry 配置项目 - -```yaml -dubbo - registry - address: {protocol}://{cluster-address} -``` -其中,protocol 为选择的配置中心类型,cluster-address 为访问注册中心的集群地址,如 - -`address: nacos://localhost:8848` - -如需集群格式地址可使用 backup 参数 - -`address: nacos://localhost:8848?backup=localshot:8846,localshot:8847` - -> 应用必须指定 Dubbo 注册中心,即使不启用注册中心也要配置(可通过设置地址为空 address='N/A' )。 - -除了 其余根据每个配置中心的不同,可以参考 [registry 配置参考手册](/zh-cn/overview/mannual/java-sdk/reference-manual/config/properties/#registry)或通过 parameters 参数进行扩展。 - -## 配置中心与元数据中心 -配置中心、元数据中心是实现 Dubbo 高阶服务治理能力的基础组件,相比于注册中心通常这两个组件的配置是可选的。 - -为了兼容 2.6 及老版本的配置,对于部分注册中心类型(如 Zookeeper、Nacos 等),Dubbo 会同时将其用作元数据中心和配置中心。 - -```yaml -dubbo - registry - address: nacos://localhost:8848 -``` - -框架解析后的默认行为 - -```yaml -dubbo - registry - address: nacos://localhost:8848 - config-center - address: nacos://localhost:8848 - metadata-report - address: nacos://localhost:8848 -``` - -可以通过以下两个参数来调整或控制默认行为 - -```yaml -dubbo - registry - address: nacos://localhost:8848 - use-as-config-center: false - use-as-metadata-report: false -``` - -## 注册中心生态 -Dubbo 主干目前支持的主流注册中心实现包括 -* Zookeeper -* Nacos -* Redis - -同时也支持 Kubernetes、Mesh 体系的服务发现。 - -另外,[Dubbo 扩展生态](https://github.com/apache/dubbo-spi-extensions) 还提供了 Consul、Eureka、Etcd 等注册中心扩展实现。也欢迎通过 [registry spi 扩展](../../spi/) 贡献更多的注册中心实现到 Dubbo 生态。 - -Dubbo 还支持在一个应用中 [指定多个注册中心](../multiple-registry/),并将服务根据注册中心分组,这样做使得服务分组管理或服务迁移变得更容易。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/registry/redis/_index.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/registry/redis/_index.md deleted file mode 100644 index d211ae65dc9a..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/registry/redis/_index.md +++ /dev/null @@ -1,83 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/reference-manual/registry/redis/ - - /zh-cn/docs3-v2/java-sdk/reference-manual/registry/redis/ - - /zh-cn/overview/what/ecosystem/registry/redis/ -description: Redis 注册中心的基本使用和工作原理。 -linkTitle: Redis -title: Redis -type: docs -weight: 5 ---- - - - - - - -## 前置条件 -* 了解 [Dubbo 基本开发步骤](../../../quick-start/spring-boot/) -* 安装并启动 [Redis](http://redis.io) 服务 - -## 使用说明 - -```xml - -``` - -或 - -```xml - -``` - -或 - -```xml - -``` - -或 - -```xml - -``` - -## 选项 - -* 可通过 `` 设置 redis 中 key 的前缀,缺省为 `dubbo`。 -* 可通过 `` 设置 redis 集群策略,缺省为 `failover`: - * `failover`: 只写入和读取任意一台,失败时重试另一台,需要服务器端自行配置数据同步 - * `replicate`: 在客户端同时写入所有服务器,只读取单台,服务器端不需要同步,注册中心集群增大,性能压力也会更大 - - -## 工作原理 - -基于 Redis [^1] 实现的注册中心。 - -Redis 过期数据通过心跳的方式检测脏数据,服务器时间必须同步,并且对服务器有一定压力,否则过期检测会不准确 - -![/user-guide/images/dubbo-redis-registry.jpg](/imgs/user/dubbo-redis-registry.jpg) - -使用 Redis 的 Key/Map 结构存储数据结构: - -* 主 Key 为服务名和类型 -* Map 中的 Key 为 URL 地址 -* Map 中的 Value 为过期时间,用于判断脏数据,脏数据由监控中心删除 [^3] - -使用 Redis 的 Publish/Subscribe 事件通知数据变更: - -* 通过事件的值区分事件类型:`register`, `unregister`, `subscribe`, `unsubscribe` -* 普通消费者直接订阅指定服务提供者的 Key,只会收到指定服务的 `register`, `unregister` 事件 -* 监控中心通过 `psubscribe` 功能订阅 `/dubbo/*`,会收到所有服务的所有变更事件 - -调用过程: - -0. 服务提供方启动时,向 `Key:/dubbo/com.foo.BarService/providers` 下,添加当前提供者的地址 -1. 并向 `Channel:/dubbo/com.foo.BarService/providers` 发送 `register` 事件 -2. 服务消费方启动时,从 `Channel:/dubbo/com.foo.BarService/providers` 订阅 `register` 和 `unregister` 事件 -3. 并向 `Key:/dubbo/com.foo.BarService/consumers` 下,添加当前消费者的地址 -4. 服务消费方收到 `register` 和 `unregister` 事件后,从 `Key:/dubbo/com.foo.BarService/providers` 下获取提供者地址列表 -5. 服务监控中心启动时,从 `Channel:/dubbo/*` 订阅 `register` 和 `unregister`,以及 `subscribe` 和`unsubsribe `事件 -6. 服务监控中心收到 `register` 和 `unregister` 事件后,从 `Key:/dubbo/com.foo.BarService/providers` 下获取提供者地址列表 -7. 服务监控中心收到 `subscribe` 和 `unsubsribe` 事件后,从 `Key:/dubbo/com.foo.BarService/consumers` 下获取消费者地址列表 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/registry/service-discovery-application-vs-interface.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/registry/service-discovery-application-vs-interface.md new file mode 100644 index 000000000000..577d06b2cd9e --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/registry/service-discovery-application-vs-interface.md @@ -0,0 +1,390 @@ +--- +description: "本文介绍了 Dubbo 应用级服务发现与接口级服务发现的详细设计与实现。" +linkTitle: 应用级vs接口级 +title: 应用级服务发现 vs 接口级服务发现 +type: docs +weight: 6 +--- + +Dubbo3 目前支持,其中接口级服务发现 + +## 应用级服务发现 + +### 设计目标 +* 显著降低服务发现过程的资源消耗,包括提升注册中心容量上限、降低消费端地址解析资源占用等,使得 Dubbo3 框架能够支持更大规模集群的服务治理,实现无限水平扩容。 +* 适配底层基础设施服务发现模型,如 Kubernetes、Service Mesh 等。 + +### 对比接口级 +![interface-arc](/imgs/blog/proposals/discovery/arc.png) + +我们从 Dubbo 最经典的工作原理图说起,Dubbo 从设计之初就内置了服务地址发现的能力,Provider 注册地址到注册中心,Consumer 通过订阅实时获取注册中心的地址更新,在收到地址列表后,consumer 基于特定的负载均衡策略发起对 provider 的 RPC 调用。 + +在这个过程中: +* 每个 Provider 通过特定的 key 向注册中心注册本机可访问地址; +* 注册中心通过这个 key 对 provider 实例地址进行聚合; +* Consumer 通过同样的 key 从注册中心订阅,以便及时收到聚合后的地址列表; + +![interface-data1](/imgs/blog/proposals/discovery/interface-data1.png) + +这里,我们对接口级地址发现的内部数据结构进行详细分析。 + +首先,看右下角 provider 实例内部的数据与行为。Provider 部署的应用中通常会有多个 Service,也就是 Dubbo2 中的服务,每个 service 都可能会有其独有的配置,我们所讲的 service 服务发布的过程,其实就是基于这个服务配置生成地址 URL 的过程,生成的地址数据如图所示;同样的,其他服务也都会生成地址。 + +然后,看一下注册中心的地址数据存储结构,注册中心以 service 服务名为数据划分依据,将一个服务下的所有地址数据都作为子节点进行聚合,子节点的内容就是实际可访问的ip地址,也就是我们 Dubbo 中 URL,格式就是刚才 provider 实例生成的。 + +![interface-data2](/imgs/blog/proposals/discovery/interface-data2.png) + +这里把 URL 地址数据划分成了几份: +* 首先是实例可访问地址,主要信息包含 ip port,是消费端将基于这条数据生成 tcp 网络链接,作为后续 RPC 数据的传输载体 +* 其次是 RPC 元数据,元数据用于定义和描述一次 RPC 请求,一方面表明这条地址数据是与某条具体的 RPC 服务有关的,它的版本号、分组以及方法相关信息,另一方面表明 +* 下一部分是 RPC 配置数据,部分配置用于控制 RPC 调用的行为,还有一部分配置用于同步 Provider 进程实例的状态,典型的如超时时间、数据编码的序列化方式等。 +* 最后一部分是自定义的元数据,这部分内容区别于以上框架预定义的各项配置,给了用户更大的灵活性,用户可任意扩展并添加自定义元数据,以进一步丰富实例状态。 + +结合以上两页对于 Dubbo2 接口级地址模型的分析,以及最开始的 Dubbo 基本原理图,我们可以得出这么几条结论: +* 第一,地址发现聚合的 key 就是 RPC 粒度的服务 +* 第二,注册中心同步的数据不止包含地址,还包含了各种元数据以及配置 +* 得益于 1 与 2,Dubbo 实现了支持应用、RPC 服务、方法粒度的服务治理能力 + +这就是一直以来 Dubbo2 在易用性、服务治理功能性、可扩展性上强于很多服务框架的真正原因。 + +![interface-defect](/imgs/blog/proposals/discovery/interface-defect.png) + +一个事物总是有其两面性,Dubbo2 地址模型带来易用性和强大功能的同时,也给整个架构的水平可扩展性带来了一些限制。这个问题在普通规模的微服务集群下是完全感知不到的,而随着集群规模的增长,当整个集群内应用、机器达到一定数量时,整个集群内的各个组件才开始遇到规模瓶颈。在总结包括阿里巴巴、工商银行等多个典型的用户在生产环境特点后,我们总结出以下两点突出问题(如图中红色所示): +* 首先,注册中心集群容量达到上限阈值。由于所有的 URL 地址数据都被发送到注册中心,注册中心的存储容量达到上限,推送效率也随之下降。 +* 而在消费端这一侧,Dubbo2 框架常驻内存已超 40%,每次地址推送带来的 cpu 等资源消耗率也非常高,影响正常的业务调用。 + +为什么会出现这个问题?我们以一个具体 provider 示例进行展开,来尝试说明为何应用在接口级地址模型下容易遇到容量问题。 +青蓝色部分,假设这里有一个普通的 Dubbo Provider 应用,该应用内部定义有 10 个 RPC Service,应用被部署在 100 个机器实例上。这个应用在集群中产生的数据量将会是 “Service 数 * 机器实例数”,也就是 10 * 100 = 1000 条。数据被从两个维度放大: +* 从地址角度。100 条唯一的实例地址,被放大 10 倍 +* 从服务角度。10 条唯一的服务元数据,被放大 100 倍 + +### 详细设计 + +![app-principle](/imgs/blog/proposals/discovery/app-principle.png) + +面对这个问题,在 Dubbo3 架构下,我们不得不重新思考两个问题: +* 如何在保留易用性、功能性的同时,重新组织 URL 地址数据,避免冗余数据的出现,让 Dubbo3 能支撑更大规模集群水平扩容? +* 如何在地址发现层面与其他的微服务体系如 Kubernetes、Spring Cloud 打通? + +![app-data1](/imgs/blog/proposals/discovery/app-data1.png) + +Dubbo3 的应用级服务发现方案设计本质上就是围绕以上两个问题展开。其基本思路是:地址发现链路上的聚合元素也就是我们之前提到的 Key 由服务调整为应用,这也是其名称叫做应用级服务发现的由来;另外,通过注册中心同步的数据内容上做了大幅精简,只保留最核心的 ip、port 地址数据。 + +![app-data2](/imgs/blog/proposals/discovery/app-data2.png) + +这是升级之后应用级地址发现的内部数据结构进行详细分析。 +对比之前接口级的地址发现模型,我们主要关注橙色部分的变化。首先,在 provider 实例这一侧,相比于之前每个 RPC Service 注册一条地址数据,一个 provider 实例只会注册一条地址到注册中心;而在注册中心这一侧,地址以应用名为粒度做聚合,应用名节点下是精简过后的 provider 实例地址; + +![app-metadataservice](/imgs/blog/proposals/discovery/app-metadataservice.png) + +应用级服务发现的上述调整,同时实现了地址单条数据大小和总数量的下降,但同时也带来了新的挑战:我们之前 Dubbo2 强调的易用性和功能性的基础损失了,因为元数据的传输被精简掉了,如何精细的控制单个服务的行为变得无法实现。 + +针对这个问题,Dubbo3 的解法是引入一个内置的 MetadataService 元数据服务,由中心化推送转为 Consumer 到 Provider 的点对点拉取,在这个模式下,元数据传输的数据量将不在是一个问题,因此可以在元数据中扩展出更多的参数、暴露更多的治理数据。 + +![app-metadataservice](/imgs/blog/proposals/discovery/app-workflow.png) + +这里我们个重点看消费端 Consumer 的地址订阅行为,消费端从分两步读取地址数据,首先是从注册中心收到精简后的地址,随后通过调用 MetadataService 元数据服务,读取对端的元数据信息。在收到这两部分数据之后,消费端会完成地址数据的聚合,最终在运行态还原出类似 Dubbo2 的 URL 地址格式。因此从最终结果而言,应用级地址模型同时兼顾了地址传输层面的性能与运行层面的功能性。 + +以上就是的应用级服务发现背景、工作原理部分的所有内容。 + + +## 接口级服务发现 + +接口级服务发现在 Dubbo3 实现中被继续保留了下来,并且继续作为框架默认的服务发现模型,这主要是考虑对于老版本的兼容性。在未来版本中,我们会将默认模型切换为应用级别服务发现。 + +{{% alert title="解决接口级服务发现性能问题" color="info" %}} +如果您的集群规模足够大,已经遇到了接口级服务发现中的性能瓶颈问题,并且您暂时无法切换到应用级服务发现。可以暂时通过简化 URL 参数达到性能优化的目的。 +{{% /alert %}} + +### URL参数简化 +**设计目标与宗旨:** +1. 期望简化进入注册中心的 provider 和 consumer 配置数量。 +2. 期望将部分配置项以其他形式存储。这些配置项需要满足:不在服务调用链路上,同时这些配置项不在注册中心的核心链路上(服务查询,服务列表)。 + +Dubbo provider 中的服务配置项有接近 [30 个配置项](/zh-cn/docs/references/xml/dubbo-parameter)。 排除注册中心服务治理需要之外,很大一部分配置项是 provider 自己使用,不需要透传给消费者。这部分数据不需要进入注册中心,而只需要以 key-value 形式持久化存储。 + +Dubbo consumer 中的配置项也有 [20+个配置项](/zh-cn/docs/references/xml/dubbo-consumer)。在注册中心之中,服务消费者列表中只需要关注 application,version,group,ip,dubbo 版本等少量配置,其他配置也可以以 key-value 形式持久化存储。 +这些数据是以服务为维度注册进入注册中心,导致了数据量的膨胀,进而引发注册中心 (如 zookeeper) 的网络开销增大,性能降低。 + +{{% alert title="注意" color="warning" %}} +简化注册中心的配置,只在 2.7 之后的版本中进行支持。 +{{% /alert %}} + +以下是开启 provider 或者 consumer 简化配置之后,URL 中默认保留的配置项: + +**provider 侧:** + +| 源码静态变量 | URL Key | 说明 | +| ------ |---------------| ------ | +| APPLICATION_KEY | application | | +| CODEC_KEY | codec | | +| EXCHANGER_KEY | exchanger | | +| SERIALIZATION_KEY | serialization | | +| CLUSTER_KEY | cluster | | +| CONNECTIONS_KEY | connections | | +| DEPRECATED_KEY | deprecated | | +| GROUP_KEY | group | | +| LOADBALANCE_KEY | loadbalance | | +| MOCK_KEY | mock | | +| PATH_KEY | path | | +| TIMEOUT_KEY | timeout | | +| TOKEN_KEY | token | | +| VERSION_KEY | version | | +| WARMUP_KEY | warmup | | +| WEIGHT_KEY | weight | | +| DUBBO_VERSION_KEY | dubbo | | +| RELEASE_KEY | release | | +| SIDE_KEY | side | | + + +**consumer 侧:** + +| 源码静态变量 | URL Key | 说明 | +| ------ | ------ | ------ | +| APPLICATION_KEY | application | | +| VERSION_KEY | version | | +| GROUP_KEY | group | | +| DUBBO_VERSION_KEY | dubbo | | + +下面我们通过示例介绍如何开启 URL 简化模式使,所有内容都可以 [在 sample 中查看源码](https://github.com/dubbo/dubbo-samples/tree/master)。 + +#### 如何开启URL精简(示例使用方式) + +我们接下来从没开启 URL 精简的示例开始,分别对比开启 URL 精简的 Provider 和开启 URL 精简的 Consumer + +##### 未开启 URL 精简的示例 + +工程源码 [dubbo-samples-simplified-registry/dubbo-samples-simplified-registry-nosimple](https://github.com/apache/dubbo-samples/tree/master/3-extensions/registry/dubbo-samples-simplified-registry/dubbo-samples-simplified-registry-nosimple)。注意,跑 sample 前,先跑下 ZKClean 进行配置项清理。 + +dubbo-provider.xml + +``` + + + + +``` + +启动 provider 的 main 方法之后,查看 zookeeper 的叶子节点(路径为:/dubbo/org.apache.dubbo.samples.simplified.registry.nosimple.api.DemoService/providers 目录下)的内容 + +``` +dubbo://30.5.124.158:20880/org.apache.dubbo.samples.simplified.registry.nosimple.api.DemoService +?anyhost=true +&application=simplified-registry-xml-provider +&async=true +&dubbo=2.0.2 +&executes=4500 +&generic=false +&group=dubbo-simple +&interface=org.apache.dubbo.samples.simplified.registry.nosimple.api.DemoService +&methods=sayHello +&owner=vict +&pid=2767 +&retries=7 +&revision=1.2.3 +&side=provider +&timeout=5300 +×tamp=1542361152795 +&valid=true +&version=1.2.3 +``` + +从中能看到有:`executes`, `retries`, `owner`, `timeout`。但是这些字段不是每个都需要传递给 dubbo ops 或者 dubbo consumer。 同样的,consumer 也有这个问题,可以在例子中启动 Consumer 的 main 方法进行查看。 + + +##### 开启 URL 精简的示例 (XML模式) + +工程源码 [dubbo-samples-simplified-registry/dubbo-samples-simplified-registry-xml](https://github.com/apache/dubbo-samples/tree/master/3-extensions/registry/dubbo-samples-simplified-registry/dubbo-samples-simplified-registry-xml)。注意,跑 sample 前,先跑下 ZKClean 进行配置项清理。 + + +```properties +dubbo.registry.simplified=true +dubbo.registry.extra-keys=retries,owner +``` +和上面的 **现有功能 sample** 进行对比,上面的 sample 中,executes, retries, owner, timeout 四个配置项都进入了注册中心。但是本实例不是,配置情况分为: + +* 配置:dubbo.registry.simplified=true, 默认情况下,timeout 在默认的配置项列表,所以还是会进入注册中心; +* 配置:dubbo.registry.extra-keys=retries,owner , 所以 retries,owner 也会进入注册中心。 + +**1. provider 端** + +```xml + + + + + + + + +``` +得到的 zookeeper 的叶子节点的值 +``` +dubbo://30.5.124.149:20880/org.apache.dubbo.samples.simplified.registry.nosimple.api.DemoService +?application=simplified-registry-xml-provider +&dubbo=2.0.2 +&group=dubbo-simple +&owner=vict +&retries=7 +&timeout=5300 +×tamp=1542594503305 +&version=1.2.3 +``` + +**2. consumer 端** + +* 配置:dubbo.registry.simplified=true +* 默认情况:application,version,group,dubbo 在默认的配置项列表,所以还是会进入注册中心。 +```xml + + + + + + + + + + +``` +得到的 zookeeper 的叶子节点的值 +``` +consumer://30.5.124.149/org.apache.dubbo.samples.simplified.registry.nosimple.api.DemoService +?actives=6 +&application=simplified-registry-xml-consumer +&category=consumers +&check=false +&dubbo=2.0.2 +&group=dubbo-simple +&owner=vvv +&version=1.2.3 +``` + +##### 开启 URL 精简的示例(API 模式) + +工程源码 [dubbo-samples-simplified-registry/dubbo-samples-simplified-registry-annotation](https://github.com/apache/dubbo-samples/tree/master/3-extensions/registry/dubbo-samples-simplified-registry/dubbo-samples-simplified-registry-annotation)。注意,跑 sample 前,先跑下 ZKClean 进行配置项清理。 + +和上面 sample 中的 dubbo.properties 的效果是一致的。 + +* 默认情况:timeout 在默认的配置项列表,所以还是会进入注册中心; +* 配置: retries,owner 作为额外的 key 进入注册中心 , 所以 retries,owner 也会进入注册中心。 + + +**1. provider 端 bean 配置** + +```java +// 等同于dubbo.properties配置,用@Bean形式进行配置 +@Bean +public RegistryConfig registryConfig() { + RegistryConfig registryConfig = new RegistryConfig(); + registryConfig.setAddress("zookeeper://127.0.0.1:2181"); + registryConfig.setSimplified(true); + registryConfig.setExtraKeys("retries,owner"); + return registryConfig; +} +``` + +```java +// 暴露服务 +@Service(version = "1.1.8", group = "d-test", executes = 4500, retries = 7, owner = "victanno", timeout = 5300) +public class AnnotationServiceImpl implements AnnotationService { + @Override + public String sayHello(String name) { + System.out.println("async provider received: " + name); + return "annotation: hello, " + name; + } +} +``` + +**2. Consumer 配置** + +和上面 sample 中 **consumer 端配置** 是一样的。 + +默认情况: application,version,group,dubbo 在默认的配置项列表,所以还是会进入注册中心。 + +#### consumer 端 bean 配置 +```java +@Bean +public RegistryConfig registryConfig() { + RegistryConfig registryConfig = new RegistryConfig(); + registryConfig.setAddress("zookeeper://127.0.0.1:2181"); + registryConfig.setSimplified(true); + return registryConfig; + } +``` + +消费服务 + +```java +@Component("annotationAction") +public class AnnotationAction { + + @Reference(version = "1.1.8", group = "d-test", owner = "vvvanno", retries = 4, actives = 6, timeout = 4500) + private AnnotationService annotationService; + public String doSayHello(String name) { + return annotationService.sayHello(name); + } +} +``` + +> 注意: 如果一个应用中既有 provider 又有 consumer,那么配置需要合并成如下 + +```java +@Bean +public RegistryConfig registryConfig() { + RegistryConfig registryConfig = new RegistryConfig(); + registryConfig.setAddress("zookeeper://127.0.0.1:2181"); + registryConfig.setSimplified(true); + //只对provider生效 + registryConfig.setExtraKeys("retries,owner"); + return registryConfig; +} +``` + +### 定制URL参数 + +上面降到了两种控制 URL 中出现的参数的方法。 + +第一种是使用 `dubbo.properties`: + +```properties +dubbo.registry.simplified=true +dubbo.registry.extra-keys=retries,owner +``` + +第二种是通过 `RegistryConfig` 进行设置: + +```java +registryConfig.setSimplified(true); +registryConfig.setExtraKeys("retries,owner"); +``` + +还有第三种方法,就是通过扩展 `org.apache.dubbo.registry.integration.ServiceURLCustomizer` SPI,可以非常灵活的增加或减少 URL 中的参数: + +```java +@SPI(scope = APPLICATION) +public interface ServiceURLCustomizer extends Prioritized { + /** + * Customizes {@link URL the service url} + * + * @param serviceURL {@link URL the service url} + * @return new service url + */ + URL customize(URL serviceURL, ApplicationModel applicationModel); +} +``` + + + diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/registry/simple.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/registry/simple.md deleted file mode 100644 index 0664760ea6b0..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/registry/simple.md +++ /dev/null @@ -1,66 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/reference-manual/registry/simple/ - - /zh-cn/docs3-v2/java-sdk/reference-manual/registry/simple/ -description: Simple 注册中心参考手册 -linkTitle: Simple -title: Simple 注册中心 -type: docs -weight: 7 ---- - - - - - - -{{% pageinfo %}} 此功能在 Dubbo 2.7 中已移除,请迁移选择[其他注册中心](../)。 -{{% /pageinfo %}} - -Simple 注册中心本身就是一个普通的 Dubbo 服务,可以减少第三方依赖,使整体通讯方式一致。 - -## 配置 - -将 Simple 注册中心暴露成 Dubbo 服务: - -```xml - - - - - - - - - - - - - - -``` - -引用 Simple Registry 服务: - -```xml - -``` - -或者: - -```xml - -``` - -或者: - -```xml - -``` - -## 适用性说明 - -此 `SimpleRegistryService` 只是简单实现,不支持集群,可作为自定义注册中心的参考,但不适合直接用于生产环境。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/registry/zookeeper.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/registry/zookeeper.md new file mode 100644 index 000000000000..7e779fb8a3b5 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/registry/zookeeper.md @@ -0,0 +1,213 @@ +--- +aliases: + - /zh/docs3-v2/java-sdk/advanced-features-and-usage/performance/loadbalance/ + - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/performance/loadbalance/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/others/graceful-shutdown/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/consistent-hash/ +description: "通过示例演示如何使用 Zookeepoer 作为注册中心实现自动服务发现。" +linkTitle: zookeeper +title: 使用 Zookeeper 作为注册中心实现自动服务发现 +type: docs +weight: 3 +--- + +本示例演示 Zookeeper 作为注册中心实现自动服务发现,示例基于 Spring Boot 应用展开,可在此查看 [完整示例代码](https://github.com/apache/dubbo-samples/tree/master/3-extensions/registry/dubbo-samples-zookeeper) + +## 1 基本配置 +### 1.1 增加 Maven 依赖 +添加 dubbo、zookeeper 等依赖。`dubbo-spring-boot-starter` 将自动为应用增加 Zookeeper 相关客户端的依赖,减少用户使用 Zookeeper 成本,如使用中遇到版本兼容问题,用户也可以选择自行添加 Curator、Zookeeper Client 等依赖。 + +对于 Spring Boot 应用而言,可使用如下依赖: +```xml + + org.apache.dubbo + dubbo-spring-boot-starter + ${dubbo.version} + + + + org.apache.dubbo + dubbo-zookeeper-curator5-spring-boot-starter + ${dubbo.version} + + +``` + +其中,dubbo-zookeeper-spring-boot-starter 或 `dubbo-zookeeper-curator5-spring-boot-starter` 负责管理 zookeeper 相关依赖。 + + +{{% alert title="注意" color="info" %}} +如果您不使用 Spring Boot,也可以使用以下方式管理依赖 + +```xml + + + org.apache.dubbo + dubbo + ${dubbo.version} + + + + + org.apache.dubbo + dubbo-dependencies-zookeeper + ${dubbo.version} + pom + + + +``` +{{% /alert %}} + +### 1.2 选择 Zookeeper 版本 + +由于 Dubbo 使用 Curator 作为与 Zookeeper Server 交互的编程客户端,因此,要特别注意 Zookeeper Server 与 Dubbo 版本依赖的兼容性。 + +Dubbo 提供了 Zookeeper 依赖的辅助管理组件,开发者可根据当前使用的 Zookeeper Server 版本选择依赖版本: + +**1. 如果您是 Dubbo3 3.3 版本及以上用户,请根据如下表格选择组件:** + +| **Zookeeper Server 版本** | **Dubbo 依赖** | **Dubbo Starter 依赖(SpringBoot用户)** | +| --- | --- | --- | +| 3.4.x 及以下 | dubbo-dependencies-zookeeper | dubbo-zookeeper-spring-boot-starter | +| 3.5.x 及以上 | dubbo-dependencies-zookeeper-curator5 | dubbo-zookeeper-curator5-spring-boot-starter | + +**2. 如果您是 Dubbo3 3.2 及以下、Dubbo2 2.7.x 用户:** + +| **Zookeeper Server 版本** | **Dubbo 依赖** | **Dubbo Starter 依赖(SpringBoot用户)** | +| --- | --- | --- | +| 3.4.x 及以下 | dubbo-dependencies-zookeeper | 不支持(自行管理) | +| 3.5.x 及以上 | 不支持(自行管理) | 不支持(自行管理) | + +{{% alert title="注意" color="info" %}} +* Dubbo 3.3.0 版本开始正式支持 JDK 17,如果您使用 JDK 17,则必须选用 dubbo-dependencies-zookeeper-curator5 或 dubbo-zookeeper-curator5-spring-boot-starter 依赖,对应的 Zookeeper Server 推荐是 3.8.0 版本及以上。 +* 如果是自行管理 zookeeper 依赖,则须确保在项目中引入正确的 zookeeper、curator 版本依赖,可参考 Dubbo 3.3.0 版本中的 `dubbo-dependencies-zookeeper` 或 `dubbo-dependencies-zookeeper-curator5` 组件是如何实现的。 +{{% /alert %}} + + +### 1.3 配置并启用 Zookeeper +```yaml +# application.yml +dubbo + registry + address: zookeeper://localhost:2181 +``` +或 +```properties +# dubbo.properties +dubbo.registry.address=zookeeper://localhost:2181 +``` +或 +```xml + +``` + +`address` 是启用 zookeeper 注册中心唯一必须指定的属性,而在生产环境下,`address` 通常被指定为集群地址,如 + +`address=zookeeper://10.20.153.10:2181?backup=10.20.153.11:2181,10.20.153.12:2181` + +protocol 与 address 分开配置的模式也可以,如 + +`` + +## 2 高级配置 +### 2.1 认证与鉴权 + +如果 Zookeeper 开启认证,Dubbo 支持指定 username、password 的方式传入身份标识。 + +```yaml +# application.yml +dubbo + registry + address: zookeeper://localhost:2181 + username: hello + password: 1234 +``` + +也可以直接将参数扩展在 address 上 `address=zookeeper://hello:1234@localhost:2181` + +### 2.2 分组隔离 +通过指定 `group` 属性,可以在同一个 Zookeeper 集群内实现微服务地址的逻辑隔离。比如可以在一套集群内隔离出多套开发环境,在地址发现层面实现隔离。 + +```yaml +# application.yml +dubbo + registry + address: zookeeper://localhost:2181 + group: daily1 +``` + +### 2.3 其他扩展配置 +配置连接、会话过期时间 +```yaml +# application.yml +dubbo + registry + address: zookeeper://localhost:2181 + timeout: 30 * 1000* # 连接超时时间,默认 30s + session: 60 * 1000* # 会话超时时间,默认 60s +``` + +Zookeeper 注册中心还支持其他一些控制参数,具体可参见[Registry 配置项手册](../../config/properties#registry) + +## 3 工作原理 +在前面的一节中,我们讲解了应用级服务发现与接口级服务发现的区别,在 Zookeeper 实现中,它们的存储结构也存在较大差异。总体来说,Zookeeper 注册中心实现支持以下高可用能力: + +* 当提供者出现断电等异常停机时,注册中心能自动删除提供者信息 +* 当注册中心重启时,能自动恢复注册数据,以及订阅请求 +* 当会话过期时,能自动恢复注册数据,以及订阅请求 +* 当设置 `registry.check=false` 时,记录失败注册和订阅请求,后台定时重试 + +### 3.1 接口级节点结构 + +![/user-guide/images/zookeeper.jpg](/imgs/user/zookeeper.jpg) + +流程: +* 服务提供者启动时: 向 `/dubbo/com.foo.BarService/providers` 目录下写入自己的 URL 地址。 +* 服务消费者启动时: 订阅 `/dubbo/com.foo.BarService/providers` 目录下的提供者 URL 地址。并向 `/dubbo/com.foo.BarService/consumers` 目录下写入自己的 URL 地址 +* 监控中心启动时: 订阅 `/dubbo/com.foo.BarService` 目录下的所有提供者和消费者 URL 地址。 + +可通过 `registry.group` 设置 zookeeper 的根节点,不配置将使用默认的 `/dubbo` 根节点。 + +### 3.2 应用级节点结构 + +#### 3.2.1 地址列表 + + +应用级服务发现的地址结构比接口级更精简,它以应用名为粒度分发地址列表。服务提供者启动时,向 `/services/app` 目录下写入自己的 URL 地址,相比于接口级别的 URL,应用级别的 URL 更简单,只包含一些实例级别的参数,如 `tri://ip:port?region=hangzhou`。 + +可通过 `registry.group` 设置 zookeeper 的根节点,如设置 `registry.group=dubbo` 后,地址根节点变为 `/dubbo`。不配置将使用默认的 `/services` 根节点。在与 Spring Cloud Gateway 共用情况下,使用 `/services` 根节点会导致 dubbo 地址被 gateway 消费,此时可考虑设置独立 group。 + +{{% alert title="注意" color="info" %}} +在应用级服务发现模型中,接口级别的配置信息由消费者与提供者之间自行协商同步,不再由注册中心负责同步,从而大大减少了注册中心地址同步压力。 +{{% /alert %}} + +#### 3.2.2 接口应用映射 +在应用级服务发现中,zookeeper 注册中心还会存储一份额外的元数据,用于解决 `接口名到应用名` 之间的映射关系,其存储结构如下: + + + +service1 节点的 value 值是应用列表,可通过 `get /dubbo/mapping/service1` 查看:app1,app2 + +#### 3.2.3 元数据 +如果您用的是应用级服务发现的集中式元数据模式(默认是点对点的元数据模式,可通过 `dubbo.registry.metadata-type=remote` 开启)。在开启集中式元数据模式后,zookeeper 中还会发现以下节点内容: + + + +每个 revision 下是该应用的部署元数据信息,包含完整的接口服务列表及其配置信息。 + + + diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/registry/zookeeper/_index.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/registry/zookeeper/_index.md deleted file mode 100644 index e0ae4594904d..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/registry/zookeeper/_index.md +++ /dev/null @@ -1,142 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/reference-manual/registry/zookeeper/ - - /zh-cn/docs3-v2/java-sdk/reference-manual/registry/zookeeper/ - - /zh-cn/overview/what/ecosystem/registry/zookeeper/ -description: Zookeeper 注册中心的基本使用和工作原理。 -linkTitle: Zookeeper -title: Zookeeper -type: docs -weight: 2 ---- - - - - - - -## 1 前置条件 -* 了解 [Dubbo 基本开发步骤](../../../quick-start/spring-boot/) -* 安装并启动 [Zookeeper](https://zookeeper.apache.org/) - -## 2 使用说明 -在此查看[完整示例代码](https://github.com/apache/dubbo-samples/tree/master/3-extensions/registry/dubbo-samples-zookeeper) - -### 2.1 增加 Maven 依赖 -```xml - - 3.0.8 - - - - - org.apache.dubbo - dubbo - ${dubbo.version} - - - - org.apache.dubbo - dubbo-dependencies-zookeeper - ${dubbo.version} - pom - - -``` - -`dubbo-dependencies-zookeeper` 将自动为应用增加 Zookeeper 相关客户端的依赖,减少用户使用 Zookeeper 成本,如使用中遇到版本兼容问题,用户也可以不使用 `dubbo-dependencies-zookeeper`,而是自行添加 Curator、Zookeeper Client 等依赖。 - -由于 Dubbo 使用 Curator 作为与 Zookeeper Server 交互的编程客户端,因此,要特别注意 Zookeeper Server 与 Dubbo 版本依赖的兼容性 - -|Zookeeper Server 版本|Dubbo 版本|Dubbo Zookeeper 依赖包|说明| -|-----|-----|-----|-----| -|3.4.x 及以下|3.0.x 及以上|dubbo-dependencies-zookeeper|传递依赖 Curator 4.x 、Zookeeper 3.4.x| -|3.5.x 及以上|3.0.x 及以上|dubbo-dependencies-zookeeper-curator5|传递依赖 Curator 5.x 、Zookeeper 3.7.x| -|3.4.x 及以上|2.7.x 及以下|dubbo-dependencies-zookeeper|传递依赖 Curator 4.x 、Zookeeper 3.4.x| -|3.5.x 及以上|2.7.x 及以下|无|须自行添加 Curator、Zookeeper 等相关客户端依赖| - -### 2.2 配置并启用 Zookeeper -```yaml -# application.yml -dubbo - registry - address: zookeeper://localhost:2181 -``` -或 -```properties -# dubbo.properties -dubbo.registry.address=zookeeper://localhost:2181 -``` -或 -```xml - -``` - -`address` 是启用 zookeeper 注册中心唯一必须指定的属性,而在生产环境下,`address` 通常被指定为集群地址,如 - -`address=zookeeper://10.20.153.10:2181?backup=10.20.153.11:2181,10.20.153.12:2181` - -protocol 与 address 分开配置的模式也可以,如 - -`` - -## 3 高级配置 -### 3.1 认证与鉴权 - -如果 Zookeeper 开启认证,Dubbo 支持指定 username、password 的方式传入身份标识。 - -```yaml -# application.yml -dubbo - registry - address: zookeeper://localhost:2181 - username: hello - password: 1234 -``` - -也可以直接将参数扩展在 address 上 `address=zookeeper://hello:1234@localhost:2181` - -### 3.2 分组隔离 -通过指定 `group` 属性,可以在同一个 Zookeeper 集群内实现微服务地址的逻辑隔离。比如可以在一套集群内隔离出多套开发环境,在地址发现层面实现隔离。 - -```yaml -# application.yml -dubbo - registry - address: zookeeper://localhost:2181 - group: daily1 -``` -### 3.3 其他扩展配置 -配置连接、会话过期时间 -```yaml -# application.yml -dubbo - registry - address: zookeeper://localhost:2181 - timeout: 30 * 1000* # 连接超时时间,默认 30s - session: 60 * 1000* # 会话超时时间,默认 60s -``` - -Zookeeper 注册中心还支持其他一些控制参数,具体可参见[Registry 配置项手册](../../config/properties#registry) - -## 4 工作原理 -### 4.1 Dubbo2 节点结构 - -![/user-guide/images/zookeeper.jpg](/imgs/user/zookeeper.jpg) - -流程: -* 服务提供者启动时: 向 `/dubbo/com.foo.BarService/providers` 目录下写入自己的 URL 地址。 -* 服务消费者启动时: 订阅 `/dubbo/com.foo.BarService/providers` 目录下的提供者 URL 地址。并向 `/dubbo/com.foo.BarService/consumers` 目录下写入自己的 URL 地址 -* 监控中心启动时: 订阅 `/dubbo/com.foo.BarService` 目录下的所有提供者和消费者 URL 地址。 - -支持以下功能: - -* 当提供者出现断电等异常停机时,注册中心能自动删除提供者信息 -* 当注册中心重启时,能自动恢复注册数据,以及订阅请求 -* 当会话过期时,能自动恢复注册数据,以及订阅请求 -* 当设置 `` 时,记录失败注册和订阅请求,后台定时重试 -* 可通过 `` 设置 zookeeper 登录信息 -* 可通过 `` 设置 zookeeper 的根节点,不配置将使用默认的根节点。 -* 支持 `*` 号通配符 ``,可订阅服务的所有分组和所有版本的提供者 - -### 4.2 Dubbo3 节点结构 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/routing-rule/_index.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/routing-rule/_index.md new file mode 100755 index 000000000000..840914e19f5b --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/routing-rule/_index.md @@ -0,0 +1,7 @@ +--- +description: "Dubbo 路由规则详解,包括条件路由、动态配置、标签路由等,可以使用这些路由规则实现流量按比例转发、金丝雀发布、流量灰度、权重调整等能力。" +linkTitle: 路由规则 +title: 路由规则 +type: docs +weight: 99 +--- diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/_index.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/_index.md index c6df0c31e52e..f084c4cd4e2a 100644 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/_index.md +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/_index.md @@ -1,9 +1,10 @@ --- aliases: - /zh/overview/what/ecosystem/serialization/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/serialization/ description: "Dubbo 序列化使用指南" -linkTitle: 序列化 +linkTitle: 序列化协议 title: 序列化 type: docs -weight: 20 +weight: 1 --- diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/dubbo/_index.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/dubbo/_index.md new file mode 100644 index 000000000000..b0a1217260b0 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/dubbo/_index.md @@ -0,0 +1,9 @@ +--- +aliases: + - /zh/overview/what/ecosystem/serialization/ +description: "dubbo 协议支持的序列化协议" +linkTitle: dubbo +title: dubbo 协议支持的序列化 +type: docs +weight: 3 +--- diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/avro.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/dubbo/avro.md similarity index 97% rename from content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/avro.md rename to content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/dubbo/avro.md index 5008648014ff..685c34c98160 100644 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/avro.md +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/dubbo/avro.md @@ -15,6 +15,7 @@ weight: 5 Avro是一种远程过程调用和数据序列化框架,是在Apache的Hadoop项目之内开发的。它使用JSON来定义数据类型和通讯协议,使用压缩二进制格式来序列化数据。它主要用于Hadoop,它可以为持久化数据提供一种序列化格式,并为Hadoop节点间及从客户端程序到Hadoop服务的通讯提供一种电报格式。 + ## 2 使用方式 ### 2.1 添加依赖 @@ -24,7 +25,7 @@ Avro是一种远程过程调用和数据序列化框架,是在Apache的Hadoop org.apache.dubbo.extensions dubbo-serialization-avro - 1.0.1 + 3.3.0 org.apache.avro @@ -63,4 +64,3 @@ dubbo.reference.com.demo.DemoService.serialization=avro -``` diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/fastjson.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/dubbo/fastjson.md similarity index 88% rename from content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/fastjson.md rename to content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/dubbo/fastjson.md index 0e7f295b0504..344d72ce39c4 100644 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/fastjson.md +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/dubbo/fastjson.md @@ -1,7 +1,7 @@ --- aliases: - - /zh/overview/what/ecosystem/serialization/fastjson/ - - /zh-cn/overview/what/ecosystem/serialization/fastjson/ + - /zh/overview/what/ecosystem/serialization/fastjson/ + - /zh-cn/overview/what/ecosystem/serialization/fastjson/ description: "本文介绍 Fastjson 序列化" linkTitle: Fastjson title: Fastjson @@ -24,7 +24,7 @@ Fastjson 是一个 Java 库,可用于将 Java 对象转换为其 JSON 表示 org.apache.dubbo.extensions dubbo-serialization-fastjson - 1.0.1 + 3.3.0 com.alibaba @@ -64,3 +64,5 @@ dubbo.reference.com.demo.DemoService.serialization=fastjson ``` + +## 3 支持的rpc协议 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/fastjson2.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/dubbo/fastjson2.md similarity index 99% rename from content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/fastjson2.md rename to content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/dubbo/fastjson2.md index a521eec2e409..1ab5961dad38 100644 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/fastjson2.md +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/dubbo/fastjson2.md @@ -6,7 +6,7 @@ description: "本文介绍 Fastjson2 序列化" linkTitle: Fastjson2 title: Fastjson2 type: docs -weight: 2 +weight: 3 --- @@ -70,3 +70,4 @@ dubbo.reference.com.demo.DemoService.serialization=fastjson2 ``` + diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/dubbo/fst.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/dubbo/fst.md new file mode 100644 index 000000000000..3a3096fb2f0b --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/dubbo/fst.md @@ -0,0 +1,154 @@ +--- +aliases: + - /zh/overview/what/ecosystem/serialization/fst/ + - /zh-cn/overview/what/ecosystem/serialization/fst/ +description: "本文介绍 FST 序列化" +linkTitle: FST +title: FST +type: docs +weight: 6 +--- + +## 1 介绍 + +FST序列化全称是Fast Serialization,它是对Java序列化的替换实现。既然前文中提到Java序列化的两点严重不足,在FST中得到了较大的改善,FST的特征如下: + +1. 比JDK提供的序列化提升了10倍,体积也减少 3-4 倍多 +2. 支持堆外Maps,和堆外Maps的持久化 +3. 支持序列化为JSON + +## 2 使用方式 + +### 2.1 添加依赖 + +```xml + + + org.apache.dubbo.extensions + dubbo-serialization-fst + 3.3.0 + + + de.ruedigermoeller + fst + 3.0.3 + + +``` + +### 2.2 配置启用 + + +```yaml +# application.yml (Spring Boot) +dubbo: + protocol: + serialization: fst +``` +或 +```properties +# dubbo.properties +dubbo.protocol.serialization=fst + +# or +dubbo.consumer.serialization=fst + +# or +dubbo.reference.com.demo.DemoService.serialization=fst +``` +或 +```xml + + + + + + + +``` + +## 3 注册被序列化类 + +要让Kryo和FST完全发挥出高性能,最好将那些需要被序列化的类注册到dubbo系统中,实现如下 + +**回调接口** +```java +public class SerializationOptimizerImpl implements SerializationOptimizer { + + public Collection getSerializableClasses() { + List classes = new LinkedList(); + classes.add(BidRequest.class); + classes.add(BidResponse.class); + classes.add(Device.class); + classes.add(Geo.class); + classes.add(Impression.class); + classes.add(SeatBid.class); + return classes; + } +} +``` + +然后在XML配置中添加: + +```xml + +``` + +在注册这些类后,序列化的性能可能被大大提升,特别针对小数量的嵌套对象的时候。 + +当然,在对一个类做序列化的时候,可能还级联引用到很多类,比如Java集合类。 + +针对这种情况,我们已经自动将JDK中的常用类进行了注册,所以你不需要重复注册它们(当然你重复注册了也没有任何影响)。 + +包括 +``` +GregorianCalendar +InvocationHandler +BigDecimal +BigInteger +Pattern +BitSet +URI +UUID +HashMap +ArrayList +LinkedList +HashSet +TreeSet +Hashtable +Date +Calendar +ConcurrentHashMap +SimpleDateFormat +Vector +BitSet +StringBuffer +StringBuilder +Object +Object[] +String[] +byte[] +char[] +int[] +float[] +double[] +``` + +由于注册被序列化的类仅仅是出于性能优化的目的,所以即使你忘记注册某些类也没有关系。 + +事实上,即使不注册任何类,Kryo和FST的性能依然普遍优于hessian和dubbo序列化。 + +> 当然,有人可能会问为什么不用配置文件来注册这些类?这是因为要注册的类往往数量较多,导致配置文件冗长;而且在没有好的IDE支持的情况下,配置文件的编写和重构都比java类麻烦得多;最后,这些注册的类一般是不需要在项目编译打包后还需要做动态修改的。 + +> 另外,有人也会觉得手工注册被序列化的类是一种相对繁琐的工作,是不是可以用annotation来标注,然后系统来自动发现并注册。但这里annotation的局限是,它只能用来标注你可以修改的类,而很多序列化中引用的类很可能是你没法做修改的(比如第三方库或者JDK系统类或者其他项目的类)。另外,添加annotation毕竟稍微的“污染”了一下代码,使应用代码对框架增加了一点点的依赖性。 + +> 除了annotation,我们还可以考虑用其它方式来自动注册被序列化的类,例如扫描类路径,自动发现实现Serializable接口(甚至包括Externalizable)的类并将它们注册。当然,我们知道类路径上能找到Serializable类可能是非常多的,所以也可以考虑用package前缀之类来一定程度限定扫描范围。 + +> 当然,在自动注册机制中,特别需要考虑如何保证服务提供端和消费端都以同样的顺序(或者ID)来注册类,避免错位,毕竟两端可被发现然后注册的类的数量可能都是不一样的。 + +### 无参构造函数和Serializable接口 + +如果被序列化的类中不包含无参的构造函数,则在Kryo的序列化中,性能将会大打折扣,因为此时我们在底层将用Java的序列化来透明的取代Kryo序列化。所以,尽可能为每一个被序列化的类添加无参构造函数是一种最佳实践(当然一个java类如果不自定义构造函数,默认就有无参构造函数)。 + +另外,Kryo和FST本来都不需要被序列化的类实现Serializable接口,但我们还是建议每个被序列化类都去实现它,因为这样可以保持和Java序列化以及dubbo序列化的兼容性,另外也使我们未来采用上述某些自动注册机制带来可能。 + diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/gson.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/dubbo/gson.md similarity index 97% rename from content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/gson.md rename to content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/dubbo/gson.md index 8efdb1079668..cbadc5f3e9a2 100644 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/gson.md +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/dubbo/gson.md @@ -24,7 +24,7 @@ Gson是Google公司发布的一个开放源代码的Java库,主要用途为序 org.apache.dubbo.extensions dubbo-serialization-gson - 1.0.1 + 3.3.0 com.google.code.gson @@ -64,3 +64,4 @@ dubbo.reference.com.demo.DemoService.serialization=gson ``` + diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/dubbo/hessian.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/dubbo/hessian.md new file mode 100644 index 000000000000..2a98ff40eca4 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/dubbo/hessian.md @@ -0,0 +1,57 @@ +--- +aliases: + - /zh/overview/what/ecosystem/serialization/hessian/ + - /zh-cn/overview/what/ecosystem/serialization/hessian/ +description: "本文介绍 Hessian 序列化" +linkTitle: Hessian +title: Hessian +type: docs +weight: 2 +--- + + + +## 1 介绍 + +Hessian序列化是一种支持动态类型、跨语言、基于对象传输的网络协议,Java对象序列化的二进制流可以被其他语言(如,c++,python)。特性如下: + +1. 自描述序列化类型。不依赖外部描述文件或者接口定义,用一个字节表示常用的基础类型,极大缩短二进制流。 +2. 语言无关,支持脚本语言 +3. 协议简单,比Java原生序列化高效 +4. 相比hessian1,hessian2中增加了压缩编码,其序列化二进制流大小是Java序列化的50%,序列化耗时是Java序列化的30%,反序列化耗时是Java序列化的20%。 + +## 2 使用方式 + +在 Dubbo 框架中,当使用 dubbo 通信协议时,默认使用 Hessian2 作为序列化。 + +### 2.1 配置启用 + + +```yaml +# application.yml (Spring Boot) +dubbo: + protocol: + serialization: hessian2 +``` +或 +```properties +# dubbo.properties +dubbo.protocol.serialization=hessian2 + +# or +dubbo.consumer.serialization=hessian2 + +# or +dubbo.reference.com.demo.DemoService.serialization=hessian2 +``` +或 +```xml + + + + + + + +``` + diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/dubbo/kryo.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/dubbo/kryo.md new file mode 100644 index 000000000000..b9fb5fd37de0 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/dubbo/kryo.md @@ -0,0 +1,158 @@ +--- +aliases: + - /zh/overview/what/ecosystem/serialization/kryo/ + - /zh-cn/overview/what/ecosystem/serialization/kryo/ +description: "本文介绍 Kryo 序列化" +linkTitle: Kryo +title: Kryo +type: docs +weight: 8 +--- + + + + +## 1 介绍 + +Kryo是一种非常成熟的序列化实现,已经在Twitter、Groupon、Yahoo以及多个著名开源项目(如Hive、Storm)中广泛的使用。 + +## 2 使用方式 + +### 2.1 添加依赖 + +```xml + + + org.apache.dubbo.extensions + dubbo-serialization-kryo + 1.0.1 + + + com.esotericsoftware + kryo + 5.4.0 + + + de.javakaffee + kryo-serializers + 0.45 + + +``` + +### 2.2 配置启用 + + +```yaml +# application.yml (Spring Boot) +dubbo: + protocol: + serialization: kryo +``` +或 +```properties +# dubbo.properties +dubbo.protocol.serialization=kryo + +# or +dubbo.consumer.serialization=kryo + +# or +dubbo.reference.com.demo.DemoService.serialization=kryo +``` +或 +```xml + + + + + + + +``` + + +## 3 注册被序列化类 + +要让Kryo和FST完全发挥出高性能,最好将那些需要被序列化的类注册到dubbo系统中,实现如下 + +**回调接口** +```java +public class SerializationOptimizerImpl implements SerializationOptimizer { + + public Collection getSerializableClasses() { + List classes = new LinkedList(); + classes.add(BidRequest.class); + classes.add(BidResponse.class); + classes.add(Device.class); + classes.add(Geo.class); + classes.add(Impression.class); + classes.add(SeatBid.class); + return classes; + } +} +``` + +然后在XML配置中添加: + +```xml + +``` + +在注册这些类后,序列化的性能可能被大大提升,特别针对小数量的嵌套对象的时候。 + +当然,在对一个类做序列化的时候,可能还级联引用到很多类,比如Java集合类。 + +针对这种情况,我们已经自动将JDK中的常用类进行了注册,所以你不需要重复注册它们(当然你重复注册了也没有任何影响)。 + +包括 +``` +GregorianCalendar +InvocationHandler +BigDecimal +BigInteger +Pattern +BitSet +URI +UUID +HashMap +ArrayList +LinkedList +HashSet +TreeSet +Hashtable +Date +Calendar +ConcurrentHashMap +SimpleDateFormat +Vector +BitSet +StringBuffer +StringBuilder +Object +Object[] +String[] +byte[] +char[] +int[] +float[] +double[] +``` + +由于注册被序列化的类仅仅是出于性能优化的目的,所以即使你忘记注册某些类也没有关系。 + +事实上,即使不注册任何类,Kryo和FST的性能依然普遍优于hessian和dubbo序列化。 + +> 当然,有人可能会问为什么不用配置文件来注册这些类?这是因为要注册的类往往数量较多,导致配置文件冗长;而且在没有好的IDE支持的情况下,配置文件的编写和重构都比java类麻烦得多;最后,这些注册的类一般是不需要在项目编译打包后还需要做动态修改的。 + +> 另外,有人也会觉得手工注册被序列化的类是一种相对繁琐的工作,是不是可以用annotation来标注,然后系统来自动发现并注册。但这里annotation的局限是,它只能用来标注你可以修改的类,而很多序列化中引用的类很可能是你没法做修改的(比如第三方库或者JDK系统类或者其他项目的类)。另外,添加annotation毕竟稍微的“污染”了一下代码,使应用代码对框架增加了一点点的依赖性。 + +> 除了annotation,我们还可以考虑用其它方式来自动注册被序列化的类,例如扫描类路径,自动发现实现Serializable接口(甚至包括Externalizable)的类并将它们注册。当然,我们知道类路径上能找到Serializable类可能是非常多的,所以也可以考虑用package前缀之类来一定程度限定扫描范围。 + +> 当然,在自动注册机制中,特别需要考虑如何保证服务提供端和消费端都以同样的顺序(或者ID)来注册类,避免错位,毕竟两端可被发现然后注册的类的数量可能都是不一样的。 + +### 无参构造函数和Serializable接口 + +如果被序列化的类中不包含无参的构造函数,则在Kryo的序列化中,性能将会大打折扣,因为此时我们在底层将用Java的序列化来透明的取代Kryo序列化。所以,尽可能为每一个被序列化的类添加无参构造函数是一种最佳实践(当然一个java类如果不自定义构造函数,默认就有无参构造函数)。 + +另外,Kryo和FST本来都不需要被序列化的类实现Serializable接口,但我们还是建议每个被序列化类都去实现它,因为这样可以保持和Java序列化以及dubbo序列化的兼容性,另外也使我们未来采用上述某些自动注册机制带来可能。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/msgpack.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/dubbo/msgpack.md similarity index 97% rename from content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/msgpack.md rename to content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/dubbo/msgpack.md index 162b8407feb7..89c23d009dcc 100644 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/msgpack.md +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/dubbo/msgpack.md @@ -24,7 +24,7 @@ MessagePack是一种计算机数据交换格式。它是一种二进制形式, org.apache.dubbo.extensions dubbo-serialization-msgpack - 1.0.1 + 3.3.0 org.msgpack diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/fst.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/fst.md deleted file mode 100644 index 5fb4b2885a38..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/fst.md +++ /dev/null @@ -1,71 +0,0 @@ ---- -aliases: - - /zh/overview/what/ecosystem/serialization/fst/ - - /zh-cn/overview/what/ecosystem/serialization/fst/ -description: "本文介绍 FST 序列化" -linkTitle: FST -title: FST -type: docs -weight: 6 ---- - - - - -## 1 介绍 - -FST序列化全称是Fast Serialization,它是对Java序列化的替换实现。既然前文中提到Java序列化的两点严重不足,在FST中得到了较大的改善,FST的特征如下: - -1. 比JDK提供的序列化提升了10倍,体积也减少 3-4 倍多 -2. 支持堆外Maps,和堆外Maps的持久化 -3. 支持序列化为JSON - -## 2 使用方式 - -### 2.1 添加依赖 - -```xml - - - org.apache.dubbo.extensions - dubbo-serialization-fst - 1.0.1 - - - de.ruedigermoeller - fst - 3.0.3 - - -``` - -### 2.2 配置启用 - - -```yaml -# application.yml (Spring Boot) -dubbo: - protocol: - serialization: fst -``` -或 -```properties -# dubbo.properties -dubbo.protocol.serialization=fst - -# or -dubbo.consumer.serialization=fst - -# or -dubbo.reference.com.demo.DemoService.serialization=fst -``` -或 -```xml - - - - - - - -``` diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/hessian.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/hessian.md deleted file mode 100644 index e5f3b33d0ef3..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/hessian.md +++ /dev/null @@ -1,56 +0,0 @@ ---- -aliases: - - /zh/overview/what/ecosystem/serialization/hessian/ - - /zh-cn/overview/what/ecosystem/serialization/hessian/ -description: "本文介绍 Hessian 序列化" -linkTitle: Hessian -title: Hessian -type: docs -weight: 1 ---- - - - -## 1 介绍 - -Hessian序列化是一种支持动态类型、跨语言、基于对象传输的网络协议,Java对象序列化的二进制流可以被其他语言(如,c++,python)。特性如下: - -1. 自描述序列化类型。不依赖外部描述文件或者接口定义,用一个字节表示常用的基础类型,极大缩短二进制流。 -2. 语言无关,支持脚本语言 -3. 协议简单,比Java原生序列化高效 -4. 相比hessian1,hessian2中增加了压缩编码,其序列化二进制流大小是Java序列化的50%,序列化耗时是Java序列化的30%,反序列化耗时是Java序列化的20%。 - -## 2 使用方式 - -> Dubbo < 3.2.0 版本中,默认使用 Hessian2 作为默认序列化 - -### 2.1 配置启用 - - -```yaml -# application.yml (Spring Boot) -dubbo: - protocol: - serialization: hessian2 -``` -或 -```properties -# dubbo.properties -dubbo.protocol.serialization=hessian2 - -# or -dubbo.consumer.serialization=hessian2 - -# or -dubbo.reference.com.demo.DemoService.serialization=hessian2 -``` -或 -```xml - - - - - - - -``` diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/kryo.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/kryo.md deleted file mode 100644 index 66b16750e35a..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/kryo.md +++ /dev/null @@ -1,72 +0,0 @@ ---- -aliases: - - /zh/overview/what/ecosystem/serialization/kryo/ - - /zh-cn/overview/what/ecosystem/serialization/kryo/ -description: "本文介绍 Kryo 序列化" -linkTitle: Kryo -title: Kryo -type: docs -weight: 8 ---- - - - - -## 1 介绍 - -Kryo是一种非常成熟的序列化实现,已经在Twitter、Groupon、Yahoo以及多个著名开源项目(如Hive、Storm)中广泛的使用。 - -## 2 使用方式 - -### 2.1 添加依赖 - -```xml - - - org.apache.dubbo.extensions - dubbo-serialization-kryo - 1.0.1 - - - com.esotericsoftware - kryo - 5.4.0 - - - de.javakaffee - kryo-serializers - 0.45 - - -``` - -### 2.2 配置启用 - - -```yaml -# application.yml (Spring Boot) -dubbo: - protocol: - serialization: kryo -``` -或 -```properties -# dubbo.properties -dubbo.protocol.serialization=kryo - -# or -dubbo.consumer.serialization=kryo - -# or -dubbo.reference.com.demo.DemoService.serialization=kryo -``` -或 -```xml - - - - - - - -``` diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/protobuf.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/protobuf.md deleted file mode 100644 index 2ff703ed4ae6..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/protobuf.md +++ /dev/null @@ -1,59 +0,0 @@ ---- -aliases: - - /zh/overview/what/ecosystem/serialization/protobuf/ - - /zh-cn/overview/what/ecosystem/serialization/protobuf/ -description: "本文介绍 Protobuf 序列化" -linkTitle: Protobuf -title: Protobuf -type: docs -weight: 3 ---- - - - - -## 1 介绍 - -Protocol Buffers是一种开源跨平台的序列化数据结构的协议。其对于存储资料或在网络上进行通信的程序是很有用的。这个方法包含一个接口描述语言,描述一些数据结构,并提供程序工具根据这些描述产生代码,这些代码将用来生成或解析代表这些数据结构的字节流。 - -## 2 使用方式 - -### 2.1 引入依赖 -```xml - - org.apache.dubbo - dubbo-serialization-protobuf - 2.7.23 - -``` - -### 2.2 配置启用 - - -```yaml -# application.yml (Spring Boot) -dubbo: - protocol: - serialization: protobuf -``` -或 -```properties -# dubbo.properties -dubbo.protocol.serialization=protobuf - -# or -dubbo.consumer.serialization=protobuf - -# or -dubbo.reference.com.demo.DemoService.serialization=protobuf -``` -或 -```xml - - - - - - - -``` diff --git a/content/zh-cn/overview/mannual/java-sdk/upgrades-and-compatibility/serialization-upgrade.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/serialization-upgrade.md similarity index 95% rename from content/zh-cn/overview/mannual/java-sdk/upgrades-and-compatibility/serialization-upgrade.md rename to content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/serialization-upgrade.md index e96e90b2f87c..bfdb578304fa 100644 --- a/content/zh-cn/overview/mannual/java-sdk/upgrades-and-compatibility/serialization-upgrade.md +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/serialization-upgrade.md @@ -2,6 +2,7 @@ aliases: - /zh/docs3-v2/java-sdk/upgrades-and-compatibility/serialization-upgrade/ - /zh-cn/docs3-v2/java-sdk/upgrades-and-compatibility/serialization-upgrade/ + - /zh-cn/overview/mannual/java-sdk/upgrades-and-compatibility/serialization-upgrade/ description: 无损升级序列化协议指南 linkTitle: 序列化协议升级 title: 序列化协议升级 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/serialization.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/serialization.md new file mode 100644 index 000000000000..ef2199fed071 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/serialization.md @@ -0,0 +1,298 @@ +--- +aliases: + - /zh/docs3-v2/java-sdk/advanced-features-and-usage/performance/serialization/ + - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/performance/serialization/ +description: 在 Dubbo 中使用高效的 Java 序列化(Kryo 和 FST) +linkTitle: 序列化概述 +title: Dubbo 序列化机制介绍 +type: docs +weight: 1 +--- + +## 支持的协议列表 +以下是 Dubbo 框架支持的序列化协议列表,根据 `triple`、`dubbo` RPC 通信协议进行分类。 + +| RPC协议 | 编程模式 | 序列化协议 | 配置方式 | JDK版本 | 说明 | +| --- | --- | --- | --- | --- | --- | +| **triple** | IDL | protobuf、
protobuf-json | 默认值 | 8, 17, 21 | 使用 IDL 时的默认序列化方式,client 也可以选择 protobuf-json 序列化通信,无需额外配置 | +| | Java接口 | protobuf-wrapper | serialization="hessian" | 8, 17, 21 | 这种模式下采用的是两次序列化模式,即数据先被 hessian 序列化,再由 protobuf 序列化。

为了支持与 IDL 同等的调用模型,易用性较好但性能略有下降 | +| **dubbo** | Java接口 | hessian | 默认值,serialization="hessian" | 8, 17, 21 | dubbo 协议默认序列化方式,具备兼容性好、高性能、跨语言的优势(java、go、c/c++、php、python、.net) | +| | Java接口 | protostuff | serialization="protostuff" | 8 | A java serialization library with built-in support for forward-backward compatibility (schema evolution) and validation. | +| | Java接口 | gson | serialization="gson" | 8, 17, 21 | 谷歌推出的一款 json 序列化库 | +| | Java接口 | avro | serialization="avro" | 8, 17, 21 | 一款 Java 高性能序列化库 | +| | Java接口 | msgpack | serialization="msgpack" | 8, 17, 21 | 具备兼容性好,提供多语言(Java、C/C++、Python等)实现等优势| +| | Java接口 | kryo | serialization="kryo" | 8, 17, 21 | Kryo是一种非常成熟的序列化实现,已经在Twitter、Groupon、Yahoo以及多个著名开源项目(如Hive、Storm)中广泛的使用。 | +| | Java接口 | fastjson2 | serialization="fastjson2" | 8, 17, 21 | fastjson | +| | Java接口 | 更多扩展| | | [dubbo-spi-extensions](https://github.com/apache/dubbo-spi-extensions/tree/master/dubbo-serialization-extensions) | + +## 性能对比报告 + +序列化对于远程调用的响应速度、吞吐量、网络带宽消耗等起着至关重要的作用,是我们提升分布式系统性能的最关键因素之一。 + +具体请查看 [参考手册 - 性能基准报告](/zh-cn/overview/mannual/java-sdk/reference-manual/performance/)。 + +## 切换序列化协议 + +{{% alert title="注意" color="info" %}} +本文档适用的典型场景是 Dubbo 老用户:用户已经有大量系统运行在 Dubbo 之上,由于一些场景需要,必须将使用多年的序列化升级一个新的序列化协议。 +{{% /alert %}} + +在 `3.2.0` 及之后版本中, Dubbo 的服务端引入新的配置 `prefer-serialization`,该特性可以通过协商的方式将整个系统的序列化协议平滑的升级到一个全新协议。 + +### 切换步骤 + +序列化协议升级,需要分两步走: + +**1. 需要推动服务端的序列化协议升级,同时在服务端的暴露配置中需要添加 `prefer-serialization` 配置。** + +比如:升级前的序列化协议是 hessian2,升级的目标序列化协议是 Fastjson2 那么在服务端的暴露配置中就应该添加如下所示的配置: + +Spring Boot 应用 `application.properties` 配置文件中增加如下内容: + +```properties +dubbo.provider.prefer-serialization=fastjson2,hessian2 #这里定义了新的协议协商顺序 +dubbo.provider.serialization=hessian2 #这是之前的序列化协议 +``` + +或者,如果使用 xml 配置的话: + +```xml + +``` + +**2. 客户端和服务端都需要增加新的序列化实现必要依赖** + +如以上示例所示,需要确保消费端和提供端都增加 fastjson2 依赖: +```xml + + com.alibaba.fastjson2 + fastjson2 + ${fastjson2.version} + +``` + +{{% alert title="警告" color="warning" %}} +要使自动协商生效,需要确保: +* 消费者端、提供者端都是 3.2.x 及以上版本,否则配置不生效(继续使用老序列化协议) +* 消费者端、提供者端都加上了必须的序列化实现包依赖,否则不生效(继续使用老序列化协议,个别极端场景可能报错)。 +{{% /alert %}} + +### 实现原理 + +dubbo 客户端序列化协议是根据服务端的注册配置来选择的(即服务端的`serialization`配置)。在请求阶段 dubbo 会把客户端的序列化协议组装到请求头上,服务端在进行反序列化时会根据请求头来确定反序列化协议。所以,如果服务端和客户端的版本不一致就可能会出现客户端序列化不了的情况。 + +为了解决这个情况,`3.2.0` 在客户端序列化的时候会优先使用 `prefer-serialization` 配置的协议,如果不支持 `prefer-serialization` 相关的协议,才会使用 `serialization` 配置的协议。(可以把 `serialization` 理解为一个兜底的配置) + + +## 安全性 + +以上所有序列化方式中,protobuf 序列化具有最高的安全性,而对于其他序列化机制而言,我们要防止因为任意类序列化反序列化引发的 RCE 攻击。 + +### 类检查机制 +Dubbo 中的类检查机制可以以类似黑白名单的形式来保证序列化安全。该机制保证服务提供方和服务消费方类之间的兼容性和安全,防止由于类版本不匹配、方法签名不兼容或缺少类而可能发生的潜在问题。 + +{{% alert title="注意" color="warning" %}} +* Dubbo >= 3.1.6 引入此检查机制,对用户透明。 +* 目前序列化检查支持 Hessian2、Fastjson2 序列化以及泛化调用,其他的序列化方式暂不支持。 +* **3.1 版本中默认为 `WARN` 告警级别,3.2 版本中默认为 `STRICT` 严格检查级别,如您遇到问题可通过以下指引降低检查级别。** +{{% /alert %}} + + +#### 检查模式 +检查模式分为三个级别:`STRICT` 严格检查,`WARN` 告警,`DISABLE` 禁用。 +`STRICT` 严格检查:禁止反序列化所有不在允许序列化列表(白名单)中的类。 +`WARN` 告警:仅禁止序列化所有在不允许序列化列表中(黑名单)的类,同时在反序列化不在允许序列化列表(白名单)中类的时候通过日志进行告警。 +`DISABLE` 禁用:不进行任何检查。 + +> 3.1 版本中默认为 `WARN` 告警级别,3.2 版本中默认为 `STRICT` 严格检查级别,如您遇到问题可通过以下指引降低检查级别。 + +通过 ApplicationConfig 配置: +```java +ApplicationConfig applicationConfig = new ApplicationConfig(); +applicationConfig.setSerializeCheckStatus("STRICT"); +``` + +通过 Spring XML 配置: +```xml + +``` + +通过 Spring Properties / dubbo.properties 配置: +```properties +dubbo.application.serialize-check-status=STRICT +``` + +通过 System Property 配置: +```properties +-Ddubbo.application.serialize-check-status=STRICT +``` + +配置成功后可以在日志中看到如下的提示: +``` +INFO utils.SerializeSecurityManager: [DUBBO] Serialize check level: STRICT +``` + +注:在同一个进程(Dubbo Framework Model)下的多个应用如果同时配置不同的检查模式,最终会生效“最宽松”的级别。如两个 Spring Context 同时启动,一个配置为 `STRICT`,另外一个配置为 `WARN`,则最终生效 `WARN` 级别的配置。 + +#### Serializable 接口检查 + +Serializable 接口检查模式分为两个级别:`true` 开启,`false` 关闭。开启检查后会拒绝反序列化所有未实现 `Serializable` 的类。 + +Dubbo 中默认配置为 `true` 开启检查。 + +通过 ApplicationConfig 配置: +```java +ApplicationConfig applicationConfig = new ApplicationConfig(); +applicationConfig.setCheckSerializable(true); +``` + +通过 Spring XML 配置: +```xml + +``` + +通过 Spring Properties / dubbo.properties 配置: +```properties +dubbo.application.check-serializable=true +``` + +通过 System Property 配置: +```properties +-Ddubbo.application.check-serializable=true +``` + +配置成功后可以在日志中看到如下的提示: +``` +INFO utils.SerializeSecurityManager: [DUBBO] Serialize check serializable: true +``` + +注 1:在同一个进程(Dubbo Framework Model)下的多个应用如果同时配置不同的 Serializable 接口检查模式,最终会生效“最宽松”的级别。如两个 Spring Context 同时启动,一个配置为 `true`,另外一个配置为 `false`,则最终生效 `false` 级别的配置。 +注 2:目前暂未打通 Hessian2、Fastjson2 内置的 `Serializable` 检查配置。对于泛化调用,仅需要配置 `dubbo.application.check-serializable` 即可修改检查配置;对于 Hessian2 序列化,需要同时修改 `dubbo.application.check-serializable` 和 `dubbo.hessian.allowNonSerializable` 两个配置;对于 Fastjson2 序列化,目前暂不支持修改。 + +#### 自动扫描相关配置 + +Dubbo 类自动扫描机制共有两个配置项:`AutoTrustSerializeClass` 是否启用自动扫描和 `TrustSerializeClassLevel` 类信任层级。 + +简单来说,在开启类自动扫描之后,Dubbo 会通过 `ReferenceConfig` 和 `ServiceConfig` 自动扫描接口所有可能会用到的相关类,并且递归信任其所在的 package。 `TrustSerializeClassLevel` 类信任层级可以用来限制最终信任的 package 层级。如 `io.dubbo.test.pojo.User` 在 `TrustSerializeClassLevel` 配置为 `3` 的时候,最终会信任 `io.dubbo.test` 这个 package 下所有的类。 + +Dubbo 中默认配置 `AutoTrustSerializeClass` 为 `true` 启用扫描, `TrustSerializeClassLevel` 为 `3`。 + +通过 ApplicationConfig 配置: +```java +ApplicationConfig applicationConfig = new ApplicationConfig(); +applicationConfig.setAutoTrustSerializeClass(true); +applicationConfig.setTrustSerializeClassLevel(3); +``` + +通过 Spring XML 配置: +```xml + +``` + +通过 Spring Properties / dubbo.properties 配置: +```properties +dubbo.application.auto-trust-serialize-class=true +dubbo.application.trust-serialize-class-level=3 +``` + +通过 System Property 配置: +```properties +-Ddubbo.application.auto-trust-serialize-class=true +-Ddubbo.application.trust-serialize-class-level=3 +``` + +配置成功后可以通过 QoS 命令检查当前已经加载的可信类结果是否符合预期。 + +注:开启检查之后在启动的过程中会有一定的性能损耗。 + +#### 可信/不可信类自定义配置 + +除了 Dubbo 自动扫描类之外,也支持通过资源文件的方式配置可信/不可信类列表。 + +配置方式:在资源目录(resource)下定义以下文件。 + +```properties +# security/serialize.allowlist +io.dubbo.test +``` + +```properties +# security/serialize.blockedlist +io.dubbo.block +``` + +配置成功以后可以在日志看到以下提示: +```properties +INFO utils.SerializeSecurityConfigurator: [DUBBO] Read serialize allow list from file:/Users/albumen/code/dubbo-samples/99-integration/dubbo-samples-serialize-check/target/classes/security/serialize.allowlist +INFO utils.SerializeSecurityConfigurator: [DUBBO] Read serialize blocked list from file:/Users/albumen/code/dubbo-samples/99-integration/dubbo-samples-serialize-check/target/classes/security/serialize.blockedlist +``` + +配置优先级为:用户自定义可信类 = 框架内置可信类 > 用户自定义不可信类 = 框架内置不可信类 > 自动类扫描可信类。 + +#### 审计方式 + +Dubbo 支持通过 QoS 命令实时查看当前的配置信息以及可信/不可信类列表。目前共支持两个命令:`serializeCheckStatus` 查看当前配置信息,`serializeWarnedClasses` 查看实时的告警列表。 + +1. `serializeCheckStatus` 查看当前配置信息 + +通过控制台直接访问: +```bash +> telnet 127.0.0.1 22222 +Trying 127.0.0.1... +Connected to localhost. +Escape character is '^]'. + ___ __ __ ___ ___ ____ + / _ \ / / / // _ ) / _ ) / __ \ + / // // /_/ // _ |/ _ |/ /_/ / +/____/ \____//____//____/ \____/ +dubbo>serializeCheckStatus +CheckStatus: WARN + +CheckSerializable: true + +AllowedPrefix: +... + +DisAllowedPrefix: +... + + +dubbo> +``` + +通过 http 请求 json 格式结果: +```bash +> curl http://127.0.0.1:22222/serializeCheckStatus +{"checkStatus":"WARN","allowedPrefix":[...],"checkSerializable":true,"disAllowedPrefix":[...]} +``` + +2. `serializeWarnedClasses` 查看实时的告警列表 + +通过控制台直接访问: +```bash +> telnet 127.0.0.1 22222 +Trying 127.0.0.1... +Connected to localhost. +Escape character is '^]'. + ___ __ __ ___ ___ ____ + / _ \ / / / // _ ) / _ ) / __ \ + / // // /_/ // _ |/ _ |/ /_/ / +/____/ \____//____//____/ \____/ +dubbo>serializeWarnedClasses +WarnedClasses: +io.dubbo.test.NotSerializable +io.dubbo.test2.NotSerializable +io.dubbo.test2.OthersSerializable +org.apache.dubbo.samples.NotSerializable + + +dubbo> +``` + +通过 http 请求 json 格式结果: +```bash +> curl http://127.0.0.1:22222/serializeWarnedClasses +{"warnedClasses":["io.dubbo.test2.NotSerializable","org.apache.dubbo.samples.NotSerializable","io.dubbo.test.NotSerializable","io.dubbo.test2.OthersSerializable"]} +``` + +> 建议及时关注 `serializeWarnedClasses` 的结果,通过返回结果是否非空来判断是否受到攻击。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/triple/_index.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/triple/_index.md new file mode 100644 index 000000000000..d01699b5915b --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/triple/_index.md @@ -0,0 +1,9 @@ +--- +aliases: + - /zh/overview/what/ecosystem/serialization/ +description: "triple 协议支持的序列化协议" +linkTitle: triple +title: triple 协议支持的序列化 +type: docs +weight: 2 +--- diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/triple/protobuf.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/triple/protobuf.md new file mode 100644 index 000000000000..0a5f298a1e9c --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/triple/protobuf.md @@ -0,0 +1,85 @@ +--- +aliases: + - /zh-cn/overview/mannual/java-sdk/reference-manual/protocol/triple/idl/ +description: "本文介绍 protobuf 序列化,如何在 triple 协议场景下使用 protobuf、json 序列化。" +linkTitle: Protobuf +title: 如何在 triple 协议场景下使用 protobuf、json 序列化 +type: docs +weight: 1 +--- + +## 1 介绍 + +Protobuf(Protocol Buffers) 是由 Google 开发的一种轻量级、高效的数据交换格式,它被用于结构化数据的序列化、反序列化和传输。 相比于XML 和JSON 等文本格式,Protobuf 具有更小的数据体积、更快的解析速度和更强的可扩展性。 + +## 2 使用方式 +**在使用 [Protobuf(IDL) 开发 triple 通信服务](/zh-cn/overview/mannual/java-sdk/tasks/protocols/triple/idl/) 的时候,dubbo server 将自动启用 protobuf、protobuf-json 序列化模式支持。** + +### 2.1 添加依赖 +使用 triple + protobuf 模式,必须添加以下依赖: + +```xml + + + com.google.protobuf + protobuf-java + 3.19.6 + + > + + com.google.protobuf + protobuf-java-util + 3.19.6 + + +``` + +### 2.2 配置启用 +只要是基于 [Protobuf(IDL) 开发模式进行 triple 协议通信](/zh-cn/overview/mannual/java-sdk/tasks/protocols/triple/idl/) ,就会使用 protobuf 序列化,只要定义 protobuf 文件并启用 triple 协议即可。 + +当使用 cURL 访问 triple 服务时,是会启用 protobuf-json 序列化模式 + +```shell +curl \ + --header "Content-Type: application/json" \ + --data '{"name":"Dubbo"}' \ + http://localhost:50052/org.apache.dubbo.samples.tri.unary.Greeter/greet/ +``` + +protobuf 服务定义示例: + +```protobuf +syntax = "proto3"; +option java_multiple_files = true; +package org.apache.dubbo.samples.tri.unary; + +message GreeterRequest { + string name = 1; +} +message GreeterReply { + string message = 1; +} + +service Greeter{ + rpc greet(GreeterRequest) returns (GreeterReply); +} +``` + + +协议配置: + +```yaml +# application.yml (Spring Boot) +dubbo: + protocol: + name: tri +``` +或 +```properties +# dubbo.properties +dubbo.protocol.name=tri +``` + +或 +```xml + diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/triple/wrapper.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/triple/wrapper.md new file mode 100644 index 000000000000..fbf99f95373d --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/triple/wrapper.md @@ -0,0 +1,73 @@ +--- +aliases: + - /zh/overview/what/ecosystem/serialization/fastjson/ + - /zh-cn/overview/what/ecosystem/serialization/fastjson/ +description: "本文介绍基于 Java 接口模式开发 triple 服务时,底层的序列化机制实现。" +linkTitle: Protobuf Wrapper +title: 基于 Java 接口模式开发 triple 服务时,底层的序列化机制实现 +type: docs +weight: 2 +--- + +## 1 介绍 + +Dubbo 实现的 triple 协议易用性更好(不绑定 Protobuf),开发者可以继续使用 Java 接口 直接定义服务。对于期望平滑升级、没有多语言业务或者不熟悉 Protobuf 的用户而言,Java 接口方式是最简单的使用 triple 的方式。 + +以下介绍这种协议模式下的底层序列化细节:框架会用一个内置的 protobuf 对象将 request 和 response 进行包装(wrapper),**也就是对象会被序列化两次,第一次是使用如 `serialization=hessian` 指定的方式进行序列化,第二次是用 protobuf wrapper 对第一步中序列化后的 byte[] 进行包装后传输**。 + + +## 2 使用方式 + +**在使用 [Java 接口方式开发 triple 通信服务](/zh-cn/overview/mannual/java-sdk/tasks/protocols/triple/idl/) 的时候,dubbo server 将自动启用 protobuf、protobuf-json 序列化模式支持。** + +### 2.1 添加依赖 + +使用 triple 协议,必须先添加如下依赖: + +```xml + + + com.google.protobuf + protobuf-java + 3.19.6 + + > + + com.google.protobuf + protobuf-java-util + 3.19.6 + + +``` + +### 2.2 配置启用 +只要是基于 [Java 接口方式模式使用 triple 协议](/zh-cn/overview/mannual/java-sdk/tasks/protocols/triple/idl/) ,就会使用 protobuf wrapper 序列化,只要定义 Java 接口并启用 triple 协议即可: + +通过 Java 接口定义 Dubbo 服务: +```java +public interface GreetingsService { + String sayHi(String name); +} +``` + + +配置使用 triple 协议(如果要设置底层使用的序列化协议,需要继续设置 serialization,如 hessian、msgpack 等): + +```yaml +# application.yml (Spring Boot) +dubbo: + protocol: + name: tri + serialization: hessian +``` +或 +```properties +# dubbo.properties +dubbo.protocol.name=tri +dubbo.protocol.serialization=hessian +``` + +或 +```xml + + diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/spi/_index.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/spi/_index.md index 52179ca2edd5..fb4874fe8a70 100755 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/spi/_index.md +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/spi/_index.md @@ -3,8 +3,8 @@ aliases: - /zh/docs3-v2/java-sdk/reference-manual/spi/ - /zh-cn/docs3-v2/java-sdk/reference-manual/spi/ description: Dubbo SPI 扩展使用指南 -linkTitle: SPI 扩展使用手册 -title: SPI 扩展使用手册 +linkTitle: SPI插件扩展点 +title: SPI 插件扩展点使用手册 type: docs weight: 9 --- diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/_index.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/_index.md index b32007a261b2..d2046ecac384 100644 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/_index.md +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/_index.md @@ -2,9 +2,9 @@ aliases: - /zh/docs3-v2/java-sdk/reference-manual/spi/description/ - /zh-cn/docs3-v2/java-sdk/reference-manual/spi/description/ -description: Dubbo 通过 SPI 扩展实现方式 -linkTitle: Dubbo SPI 扩展实现说明 -title: Dubbo SPI 扩展实现说明 +description: "Dubbo SPI 插件定义及使用详细介绍。" +linkTitle: 部分重点SPI使用说明 +title: Dubbo SPI 插件定义及使用详细介绍 type: docs -weight: 2 +weight: 3 --- diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/spi/overview.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/spi/overview.md index 2bba9372c639..9ebf6e85627a 100644 --- a/content/zh-cn/overview/mannual/java-sdk/reference-manual/spi/overview.md +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/spi/overview.md @@ -3,107 +3,23 @@ aliases: - /zh/docs3-v2/java-sdk/reference-manual/spi/overview/ - /zh-cn/docs3-v2/java-sdk/reference-manual/spi/overview/ description: Dubbo 通过 SPI 机制提供了非常灵活的可扩展性 -linkTitle: Dubbo SPI 概述 +linkTitle: SPI 概述 title: Dubbo SPI 概述 type: docs weight: 1 --- +使用 IoC 容器帮助管理组件的生命周期、依赖关系注入等是很多开发框架的常用设计,Dubbo 中内置了一个轻量版本的 IoC 容器,用来管理框架内部的插件,实现包括插件实例化、生命周期、依赖关系自动注入等能力。 +感兴趣的读者可以了解: +* [Dubbo SPI 扩展体系的工作原理](/zh-cn/overview/mannual/java-sdk/reference-manual/architecture/dubbo-spi/) +* [Dubbo SPI 扩展使用示例](/zh-cn/overview/mannual/java-sdk/tasks/extensibility/spi/) +Dubbo 插件体系与 IoC 容器具有以下特点: +* **[核心组件均被定义为插件](../spi-list/),用户或二次开发者扩展非常简单。** 在无需改造框架内核的情况下,用户可以基于自身需求扩展如负载均衡、注册中心、通信协议、路由等策略。 +* **平等对待第三方扩展实现。** Dubbo 中所有内部实现和第三方实现都是平等的,用户可以基于自身业务需求替换 Dubbo 提供的原生实现。 +* **[插件依赖支持自动注入(IoC)](/zh-cn/overview/mannual/java-sdk/reference-manual/architecture/dubbo-spi/#23-ioc-机制)。** 如果插件实现依赖其他插件属性,则 Dubbo 框架会完成该依赖对象的自动注入,支持属性、构造函数等方式。 +* **[插件扩展实现支持 AOP 能力](/zh-cn/overview/mannual/java-sdk/reference-manual/architecture/dubbo-spi/#24-aop-机制)。** 框架可以自动发现扩展类的包装类,通过包装器模式对插件进行 AOP 增强。 +* **[支持插件自动激活](/zh-cn/overview/mannual/java-sdk/reference-manual/architecture/dubbo-spi/#25-activate激活条件)。** 通过为插件实现指定激活条件(通过注解参数等),框架可在运行时自动根据当前上下文决策是否激活该插件实现。 +* **[支持插件扩展排序](/zh-cn/overview/mannual/java-sdk/reference-manual/architecture/dubbo-spi/#26-扩展点排序)。** - - -## 扩展设计理念 - -可扩展性是任何一个系统所追求的,对于 Dubbo 来说是同样适用。 - -### 什么是可扩展性 - -可扩展性是一种设计理念,代表了我们对未来的一种预想,我们希望在现有的架构或设计基础上,当未来某些方面发生变化的时候,我们能够以最小的改动来适应这种变化。 - -### 可扩展性的优点 - -可扩展性的优点主要表现模块之间解耦,它符合开闭原则,对扩展开放,对修改关闭。当系统增加新功能时,不需要对现有系统的结构和代码进行修改,仅仅新增一个扩展即可。 - -### 扩展实现方式 - -一般来说,系统会采用 Factory、IoC、OSGI 等方式管理扩展(插件)生命周期。考虑到 Dubbo 的适用面,不想强依赖 Spring 等 IoC 容器。 -而自己造一个小的 IoC 容器,也觉得有点过度设计,所以选择最简单的 Factory 方式管理扩展(插件)。在 Dubbo 中,所有内部实现和第三方实现都是平等的。 - -### Dubbo 中的可扩展性 - -* 平等对待第三方的实现。在 Dubbo 中,所有内部实现和第三方实现都是平等的,用户可以基于自身业务需求,替换 Dubbo 提供的原生实现。 -* 每个扩展点只封装一个变化因子,最大化复用。每个扩展点的实现者,往往都只是关心一件事。如果用户有需求需要进行扩展,那么只需要对其关注的扩展点进行扩展就好,极大的减少用户的工作量。 - -## Dubbo 扩展的特性 - -Dubbo 中的扩展能力是从 JDK 标准的 SPI 扩展点发现机制加强而来,它改进了 JDK 标准的 SPI 以下问题: - -* JDK 标准的 SPI 会一次性实例化扩展点所有实现,如果有扩展实现初始化很耗时,但如果没用上也加载,会很浪费资源。 -* 如果扩展点加载失败,连扩展点的名称都拿不到了。比如:JDK 标准的 ScriptEngine,通过 getName() 获取脚本类型的名称,但如果 RubyScriptEngine 因为所依赖的 jruby.jar 不存在,导致 RubyScriptEngine 类加载失败,这个失败原因被吃掉了,和 ruby 对应不起来,当用户执行 ruby 脚本时,会报不支持 ruby,而不是真正失败的原因。 - -用户能够基于 Dubbo 提供的扩展能力,很方便基于自身需求扩展其他协议、过滤器、路由等。下面介绍下 Dubbo 扩展能力的特性。 - -* 按需加载。Dubbo 的扩展能力不会一次性实例化所有实现,而是用扩展类实例化,减少资源浪费。 -* 增加扩展类的 IOC 能力。Dubbo 的扩展能力并不仅仅只是发现扩展服务实现类,而是在此基础上更进一步,如果该扩展类的属性依赖其他对象,则 Dubbo 会自动的完成该依赖对象的注入功能。 -* 增加扩展类的 AOP 能力。Dubbo 扩展能力会自动的发现扩展类的包装类,完成包装类的构造,增强扩展类的功能。 -* 具备动态选择扩展实现的能力。Dubbo 扩展会基于参数,在运行时动态选择对应的扩展类,提高了 Dubbo 的扩展能力。 -* 可以对扩展实现进行排序。能够基于用户需求,指定扩展实现的执行顺序。 -* 提供扩展点的 Adaptive 能力。该能力可以使的一些扩展类在 consumer 端生效,一些扩展类在 provider 端生效。 - -从 Dubbo 扩展的设计目标可以看出,Dubbo 实现的一些例如动态选择扩展实现、IOC、AOP 等特性,能够为用户提供非常灵活的扩展能力。 - -## Dubbo 扩展加载流程 - -Dubbo 加载扩展的整个流程如下: - -![//imgs/v3/concepts/extension-load.png](/imgs/v3/concepts/extension-load.png) - -主要步骤为 4 个: -* 读取并解析配置文件 -* 缓存所有扩展实现 -* 基于用户执行的扩展名,实例化对应的扩展实现 -* 进行扩展实例属性的 IOC 注入以及实例化扩展的包装类,实现 AOP 特性 - -## 如何使用 Dubbo 扩展能力进行扩展 - -下面以扩展协议为例进行说明如何利用 Dubbo 提供的扩展能力扩展 Triple 协议。 - -(1) 在协议的实现 jar 包内放置文本文件:META-INF/dubbo/org.apache.dubbo.remoting.api.WireProtocol -```text -tri=org.apache.dubbo.rpc.protocol.tri.TripleHttp2Protocol -``` - -(2) 实现类内容 -```java -@Activate -public class TripleHttp2Protocol extends Http2WireProtocol { - // ... -} -``` - -说明下:Http2WireProtocol 实现了 WireProtocol 接口 - -(3) Dubbo 配置模块中,扩展点均有对应配置属性或标签,通过配置指定使用哪个扩展实现。比如: -```text - -``` - -从上面的扩展步骤可以看出,用户基本在黑盒下就完成了扩展。 - -## Dubbo 扩展的应用 - -Dubbo 的扩展能力非常灵活,在自身功能的实现上无处不在。 - -![//imgs/v3/concepts/extension-use.png](/imgs/v3/concepts/extension-use.png) - -Dubbo 扩展能力使得 Dubbo 项目很方便的切分成一个一个的子模块,实现热插拔特性。用户完全可以基于自身需求,替换 Dubbo 原生实现,来满足自身业务需求。 - -## Dubbo 扩展的使用场景 - -* 如果你需要自定义负载均衡策略,你可以使用 Dubbo 扩展能力。 -* 如果你需要实现自定义的注册中心,你可以使用 Dubbo 扩展能力。 -* 如果你需要实现自定义的过滤器,你可以使用 Dubbo 扩展能力。 - -Dubbo 扩展平等的对待内部实现和第三方实现。更多使用场景,参见 [SPI 扩展实现](../description/) diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/spi/spi-list.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/spi/spi-list.md new file mode 100644 index 000000000000..a82b65c5ecb1 Binary files /dev/null and b/content/zh-cn/overview/mannual/java-sdk/reference-manual/spi/spi-list.md differ diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/upgrades-and-compatibility/_index.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/upgrades-and-compatibility/_index.md new file mode 100755 index 000000000000..16e43cb651e0 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/upgrades-and-compatibility/_index.md @@ -0,0 +1,11 @@ +--- +aliases: + - /zh/docs3-v2/java-sdk/upgrades-and-compatibility/ + - /zh-cn/docs3-v2/java-sdk/upgrades-and-compatibility/ + - /zh-cn/overview/mannual/java-sdk/upgrades-and-compatibility/ +description: 升级和兼容性 +linkTitle: 升级和兼容性 +title: 升级和兼容性 +type: docs +weight: 200 +--- diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/upgrades-and-compatibility/migration-service-discovery.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/upgrades-and-compatibility/migration-service-discovery.md new file mode 100644 index 000000000000..21fad0da0910 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/upgrades-and-compatibility/migration-service-discovery.md @@ -0,0 +1,77 @@ +--- +aliases: + - /zh/docs3-v2/java-sdk/upgrades-and-compatibility/service-discovery/service-discovery-samples/ + - /zh-cn/docs3-v2/java-sdk/upgrades-and-compatibility/service-discovery/service-discovery-samples/ + - /zh-cn/overview/mannual/java-sdk/upgrades-and-compatibility/service-discovery/ +description: 本文具体说明了用户在升级到 Dubbo3 之后,如何快速开启应用级服务发现新特性,从接口级服务发现平滑迁移到应用级服务发现。 +linkTitle: 升级到应用级服务发现 +title: 升级到应用级服务发现 +type: docs +weight: 3 +--- + +{{% alert title="请注意" color="warning" %}} +* 本文档内容并不是升级 Dubbo3 必须的,您完全可以只升级框架并使用 [框架的服务发现默认行为](/zh-cn/overview/mannual/java-sdk/reference-manual/upgrades-and-compatibility/migration-service-discovery/#启用应用级服务发现)。 +* 本文档更适用于 Dubbo2 老用户,用于了解在升级到 Dubbo3 版本后,框架中的服务发现模型切换过程与工作原理。新用户请直接 [配置启用应用级服务发现](/zh-cn/overview/mannual/java-sdk/tasks/service-discovery/nacos/#13-配置并启用-nacos)。 +{{% /alert %}} + +对于 Dubbo2 老用户而言,在升级 Dubbo3 时有以下两个选择,而决策的考虑因素仅有一个:性能。 +1. 如果您的集群规模不算大,之前使用 Dubbo2 未遇到任何地址推送等性能问题,完全可以继续使用接口级别服务发现 +2. 如果您集群规模较大,之前使用 Dubbo2 遇到服务发现负载飙高等问题,则建议迁移到新的应用级服务发现 + +基于以上决策结论,请在升级 Dubbo3 框架时调整以下配置。 + +## 继续使用接口级服务发现 + +在升级到 Dubbo3 框架时,您需要调整应用配置如下,(仅仅是一个配置项调整,提供者应用必须配置、消费者应用可选): + +```xml + +``` + +或者 + +```yaml +dubbo: + application: + name: xxx + register-mode: interface #表示继续使用老版本服务发现模型,可选值 interface、instance、all +``` + +或者,以上是全局默认配置,可以根据每个注册中心来单独配置 + +```xml + +``` + +或者 + +```yaml +dubbo: + registry: + address: nacos://localhost:8848 + register-mode: interface #表示继续使用老版本服务发现模型,可选值 interface、instance、all +``` + +## 启用应用级服务发现(默认) +对于老用户而言,如果要启用应用级服务发现,就需要一个平滑迁移的过程。这时需要让新升级的 Dubbo3 应用进行双注册双订阅(当前框架默认行为,因此用户无需修改任何配置,以下内容均会自行发生,注意:未来版本可能切换为应用级单注册单订阅),以确保新老服务发现模型都能兼顾。 + +{{% alert title="请注意" color="warning" %}} +对于新用户而言,可以直接配置 `dubbo.application.register-mode=instance`,即在一开始就配置仅使用应用级服务发现。 +{{% /alert %}} + +### 提供者端注册行为 +在默认情况下,Dubbo3 框架会同时注册接口级、应用级两种服务发现地址,因此,集群中的新老应用都能够正常的发现改应用地址,并正常发起调用。如下图所示: + + +dubbo应用级服务发现 + +### 消费者端订阅行为 +在默认情况下,Dubbo3 框架具备同时发现 Dubbo2 与 Dubbo3 地址列表的能力。在默认情况下,如果集群中存在可以消费的 Dubbo3 的地址,将自动消费 Dubbo3 的地址,如果不存在新地址则自动消费 Dubbo2 的地址(Dubbo3 提供了开关来控制这个行为),具体如下图所示: + +dubbo应用级服务发现 + +### 状态收敛 + +关于以上双注册、双订阅行为的更多详细解释,以及如何尽快完成服务发现模型的收敛,请参考博客文章 [Dubbo3 服务发现平滑迁移步骤与原理](/zh-cn/blog/2024/05/13/如果从接口级服务发现平滑迁移到应用级服务发现/)。 + diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/upgrades-and-compatibility/migration-triple.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/upgrades-and-compatibility/migration-triple.md new file mode 100644 index 000000000000..de08662063f0 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/upgrades-and-compatibility/migration-triple.md @@ -0,0 +1,108 @@ +--- +aliases: + - /zh/docs3-v2/java-sdk/upgrades-and-compatibility/migration-triple/ + - /zh-cn/docs3-v2/java-sdk/upgrades-and-compatibility/migration-triple/ + - /zh-cn/overview/mannual/java-sdk/upgrades-and-compatibility/migration-triple/ +description: "如何平滑的从 dubbo 协议升级到 triple 协议。" +linkTitle: 升级到triple协议 +title: 升级到triple协议 +type: docs +weight: 2 +--- + +{{% alert title="请注意" color="warning" %}} +* 本文档内容并不是升级 Dubbo3 必须的,您完全可以只升级框架并继续使用 dubbo 通信协议。 +* 如果您是 Dubbo 新用户,强烈建议直接 [使用 triple 协议](/zh-cn/overview/mannual/java-sdk/tasks/protocol/) 即可。 +{{% /alert %}} + +本文档适合服务已经运行在 dubbo 协议之上的老用户,请先参考上一篇文档 [如何从 Dubbo2 升级到 Dubbo3](../migration/) 完成框架版本升级,然后遵循以下步骤以最小改动平滑迁移到 triple 协议。 + +以下是协议升级的架构图,展示了平滑升级过程中不同 Dubbo 应用的状态: + + +dubbo协议迁移到tirple协议 + +按先后顺序,升级基本步骤如下: +1. Provider 提供者侧配置单端口双协议(dubbo、triple)发布 +2. Provider 提供者侧配置首选协议为 triple(此时,提供者注册的URL地址为 `dubbo://host:port/DemoService?preferred-protocol=tri`) +3. Consumer 消费者升级,根据情况不同有以下两种方式: + * 升级消费者到 3.3 版本,消费者会根据 `preferred-protocol=tri` 优先调用 triple 协议 + * 无法升级到 3.3 版本的消费者应用,可以配置 `@DubboReference(protocol="tri")` 调用 triple 协议 +4. 推动所有应用升级到最新 Dubbo3 版本,最终所有流量都是 triple 协议 + +{{% alert title="请注意" color="warning" %}} +请注意,以上提到的单端口多协议、识别 `preferred-protocol` 首选协议等功能,需要 Dubbo 3.3.0+ 版本! +{{% /alert %}} + +### 步骤一:提供者双协议发布 +假设我们有以下应用配置,即在 20880 端口发布 dubbo 协议: +```yaml +dubbo: + protocol: + name: dubbo + port: 20880 +``` + +我们需要增加两个配置项,如下所示: + +```yaml +dubbo: + protocol: + name: dubbo + port: 20880 + ext-protocol: tri + preferred-protocol: tri +``` + +其中, +* `ext-protocol: tri` 指定在原 20880 端口上额外发布 triple 协议,即单端口双协议发布。 +* `preferred-protocol: tri` 会随注册中心同步到 Consumer 侧,告诉 consumer 优先使用 triple 协议调用 + +{{% alert title="注意" color="warning" %}} +`preferred-protocol: tri` 配置仅在 3.3.0 及之后版本支持,所以即使 provider 配置了这个选项,对于 3.3.0 版本即之前的 consumer 消费端并不会生效,还是会调用 dubbo 协议。 +{{% /alert %}} + +### 步骤二:消费端切换协议 +提供端完成步骤一配置并重启后,消费端根据版本与配置不同,可能处于以下三种状态之一: + +**1. 消费端是 3.3.0 及之后版本** + +此类消费端会自动识别提供者 url 上的 `preferred-protocol: tri` 标记,如果发现此标记,则消费端自动使用 triple 协议调用服务,否则继续使用 dubbo 协议。 + +**2. 消费端是 2.x 或 3.3.0 之前版本** + +由于低版本 Dubbo 框架不能识别 `preferred-protocol: tri` 参数,因此这部分消费者不受提供者端多协议发布的任何影响,继续调用 dubbo 协议。 + +**3. 消费端是 2.x 或 3.3.0 之前版本,且额外指定要调用的协议** + +与第 2 种情况基本一致,只是这时用户可以明确的为某些服务指定使用哪种 rpc 协议,如: + +```java +@DubboReference(protocol="tri") +private DemoService demoService; +``` + +或者 + +```xml + +``` + +在配置了 `protocol="tri"` 后,服务的调用会使用 triple 协议。需要注意的是,在配置 `protocol="tri"` 之前,一定要确保提供端已经发布了 triple 协议支持,否则调用将会失败。 + +{{% alert title="注意" color="warning" %}} +* 从以上三种情况可知,协议升级过程对消费端完全无感,消费端不会因提供端的多协议配置而出现任何通信障碍。 +* 对于消费端,最简单的协议切换方式就是通过 `preferred-protocol=tri` 进行自动切换,需要两边版本都升级到 3.3.0+ 才支持。 +{{% /alert %}} + +### 步骤三:完全收敛到triple协议 +步骤一、二操作起来非常简单,并且保证了过程平滑,通过单端口双协议、消费端自动切换保证了整个升级过程的平滑。 + +平滑升级意味着我们要经历一个中间态,即在某一段时间内,集群内 dubbo 协议、triple 协议共存(有些服务间通信是dubbo协议、有些服务间通信是triple协议)。如何才能推进达成终态目标那,即所有服务调用都使用 triple 协议?我们推荐使用以下两种方式达成目标: +* 推进集群内所有 Dubbo 应用都升级到 3.3.x 最新版本,这样消费端就能自动切换到 triple 协议 +* 通过 Dubbo 框架的指标埋点,观察某个应用(作为provider)是否仍在处理 dubbo 流量,对这部分应用的上下游进行治理 + +{{% alert title="注意" color="info" %}} +对于 Dubbo 框架而言,集群内 dubbo 协议和 triple 协议共存的状态并不存在任何技术问题,不同的服务调用使用不同协议也很正常,因此双协议共存的中间态是完全可以接受的。但有时候为了整体方案统一,我们可能需要达成单一通信协议的终态目标。 +{{% /alert %}} + diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/upgrades-and-compatibility/migration-triple.md.bak b/content/zh-cn/overview/mannual/java-sdk/reference-manual/upgrades-and-compatibility/migration-triple.md.bak new file mode 100644 index 000000000000..910d130944ea --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/upgrades-and-compatibility/migration-triple.md.bak @@ -0,0 +1,346 @@ +--- +aliases: + - /zh/docs3-v2/java-sdk/upgrades-and-compatibility/migration-triple/ + - /zh-cn/docs3-v2/java-sdk/upgrades-and-compatibility/migration-triple/ +description: Triple 协议迁移指南 +linkTitle: Dubbo 协议迁移至 Triple 协议 +title: Dubbo 协议迁移至 Triple 协议 +type: docs +weight: 7 +--- + + +## Triple 协议介绍 + +根据 Triple 设计的目标,`Triple` 协议有以下优势: + +- 具备跨语言交互的能力,传统的多语言多 SDK 模式和 Mesh 化跨语言模式都需要一种更通用易扩展的数据传输协议。 +- 提供更完善的请求模型,除了支持传统的 Request/Response 模型(Unary 单向通信),还支持 Stream(流式通信) 和 Bidirectional(双向通信)。 +- 易扩展、穿透性高,包括但不限于 Tracing / Monitoring 等支持,也应该能被各层设备识别,网关设施等可以识别数据报文,对 Service Mesh 部署友好,降低用户理解难度。 +- 完全兼容 grpc,客户端/服务端可以与原生grpc客户端打通。 +- 可以复用现有 grpc 生态下的组件, 满足云原生场景下的跨语言、跨环境、跨平台的互通需求。 + +当前使用其他协议的 Dubbo 用户,框架提供了兼容现有序列化方式的迁移能力,在不影响线上已有业务的前提下,迁移协议的成本几乎为零。 + +需要新增对接 Grpc 服务的 Dubbo 用户,可以直接使用 Triple 协议来实现打通,不需要单独引入 grpc client 来完成,不仅能保留已有的 Dubbo 易用性,也能降低程序的复杂度和开发运维成本,不需要额外进行适配和开发即可接入现有生态。 + +对于需要网关接入的 Dubbo 用户,Triple 协议提供了更加原生的方式,让网关开发或者使用开源的 grpc 网关组件更加简单。网关可以选择不解析 payload ,在性能上也有很大提高。在使用 Dubbo 协议时,语言相关的序列化方式是网关的一个很大痛点,而传统的 HTTP 转 Dubbo 的方式对于跨语言序列化几乎是无能为力的。同时,由于 Triple 的协议元数据都存储在请求头中,网关可以轻松的实现定制需求,如路由和限流等功能。 + +> `Triple` 协议的格式和原理请参阅 [RPC 通信协议](/zh-cn/docs/concepts/rpc-protocol/) + +## Dubbo2 协议迁移流程 + +Dubbo2 的用户使用 dubbo 协议 + 自定义序列化,如 hessian2 完成远程调用。 + +而 Grpc 的默认仅支持 Protobuf 序列化,对于 Java 语言中的多参数以及方法重载也无法支持。 + +Dubbo3的之初就有一条目标是完美兼容 Dubbo2,所以为了 Dubbo2 能够平滑升级, Dubbo 框架侧做了很多工作来保证升级的无感,目前默认的序列化和 Dubbo2 保持一致为`hessian2`。 + +所以,如果决定要升级到 Dubbo3 的 `Triple` 协议,只需要修改配置中的协议名称为 `tri` (注意: 不是triple)即可。 + +接下来我们我们以一个使用 Dubbo2 协议的[工程](https://github.com/apache/dubbo-samples/tree/master/3-extensions/protocol/dubbo-samples-triple/src/main/java/org/apache/dubbo/sample/tri/migration) 来举例,如何一步一步安全的升级。 + +1. 仅使用 `dubbo` 协议启动 `provider` 和 `consumer`,并完成调用。 +2. 使用 `dubbo` 和 `tri` 协议 启动`provider`,以 `dubbo` 协议启动 `consumer`,并完成调用。 +3. 仅使用 `tri` 协议 启动 `provider`和 `consumer`,并完成调用。 + +### 定义服务 + +1. 定义接口 +```java +public interface IWrapperGreeter { + + //... + + /** + * 这是一个普通接口,没有使用 pb 序列化 + */ + String sayHello(String request); + +} +``` + +2. 实现类如下 +```java +public class IGreeter2Impl implements IWrapperGreeter { + + @Override + public String sayHello(String request) { + return "hello," + request; + } +} +``` + +### 仅使用 triple 协议 + +当所有的 consuemr 都升级至支持 `Triple` 协议的版本后,provider 可切换至仅使用 `Triple` 协议启动 + +结构如图所示: +![strust](/imgs/v3/migration/tri/migrate-only-tri-strust.png) + +[Provider](https://github.com/apache/dubbo-samples/blob/master/3-extensions/protocol/dubbo-samples-triple/src/main/java/org/apache/dubbo/sample/tri/migration/ApiMigrationTriProvider.java) +和 [Consumer](https://github.com/apache/dubbo-samples/blob/master/3-extensions/protocol/dubbo-samples-triple/src/main/java/org/apache/dubbo/sample/tri/migration/ApiMigrationTriConsumer.java) 完成调用,输出如下: + +![result](/imgs/v3/migration/tri/dubbo3-tri-migration-tri-tri-result.png) + +### 仅使用 dubbo 协议 + +为保证兼容性,我们先将部分 provider 升级到 `dubbo3` 版本并使用 `dubbo` 协议。 + +使用 `dubbo` 协议启动一个 [`Provider`](https://github.com/apache/dubbo-samples/blob/master/3-extensions/protocol/dubbo-samples-triple/src/main/java/org/apache/dubbo/sample/tri/migration/ApiMigrationDubboProvider.java) 和 [`Consumer`](https://github.com/apache/dubbo-samples/blob/master/3-extensions/protocol/dubbo-samples-triple/src/main/java/org/apache/dubbo/sample/tri/migration/ApiMigrationDubboConsumer.java) ,完成调用,输出如下: +![result](/imgs/v3/migration/tri/dubbo3-tri-migration-dubbo-dubbo-result.png) + +### 同时使用两协议 + +对于线上服务的升级,不可能一蹴而就同时完成 provider 和 consumer 升级, 需要按步操作,保证业务稳定。 +第二步, provider 提供双协议的方式同时支持 dubbo + tri 两种协议的客户端。 + +结构如图所示: +![strust](/imgs/v3/migration/tri/migrate-dubbo-tri-strust.png) + +> 按照推荐升级步骤,provider 已经支持了tri协议,所以 dubbo3的 consumer 可以直接使用 tri 协议 + +使用`dubbo`协议和`triple`协议启动[`Provider`](https://github.com/apache/dubbo-samples/blob/master/3-extensions/protocol/dubbo-samples-triple/src/main/java/org/apache/dubbo/sample/tri/migration/ApiMigrationBothProvider.java)和[`Consumer`](https://github.com/apache/dubbo-samples/blob/master/3-extensions/protocol/dubbo-samples-triple/src/main/java/org/apache/dubbo/sample/tri/migration/ApiMigrationBothConsumer.java),完成调用,输出如下: + +![result](/imgs/v3/migration/tri/dubbo3-tri-migration-both-dubbo-tri-result.png) + + +### 实现原理 + +通过上面介绍的升级过程,我们可以很简单的通过修改协议类型来完成升级。框架是怎么帮我们做到这些的呢? + +通过对 `Triple` 协议的介绍,我们知道Dubbo3的 `Triple` 的数据类型是 `protobuf` 对象,那为什么非 `protobuf` 的 java 对象也可以被正常传输呢。 + +这里 Dubbo3 使用了一个巧妙的设计,首先判断参数类型是否为 `protobuf` 对象,如果不是。用一个 `protobuf` 对象将 `request` 和 `response` 进行 wrapper,这样就屏蔽了其他各种序列化带来的复杂度。在 `wrapper` 对象内部声明序列化类型,来支持序列化的扩展。 + +wrapper 的`protobuf`的 IDL如下: +```proto +syntax = "proto3"; + +package org.apache.dubbo.triple; + +message TripleRequestWrapper { + // hessian4 + // json + string serializeType = 1; + repeated bytes args = 2; + repeated string argTypes = 3; +} + +message TripleResponseWrapper { + string serializeType = 1; + bytes data = 2; + string type = 3; +} +``` + +对于请求,使用`TripleRequestWrapper`进行包装,对于响应使用`TripleResponseWrapper`进行包装。 + +> 对于请求参数,可以看到 args 被`repeated`修饰,这是因为需要支持 java 方法的多个参数。当然,序列化只能是一种。序列化的实现沿用 Dubbo2 实现的 spi + + +## 多语言用户 + +使用 `protobuf` 建议新服务均使用该方式,对于 Dubbo3 和 Triple 来说,主推的是使用 `protobuf` 序列化,并且使用 `proto` 定义的 `IDL` 来生成相关接口定义。以 `IDL` 做为多语言中的通用接口约定,加上 `Triple` 与 `Grpc` 的天然互通性,可以轻松地实现跨语言交互,例如 Go 语言等。 + +将编写好的 `.proto` 文件使用 `dubbo-compiler` 插件进行编译并编写实现类,完成方法调用: + +![result](/imgs/v3/migration/tri/dubbo3-tri-migration-tri-tri-result.png) + +从上面升级的例子我们可以知道,`Triple` 协议使用 `protbuf` 对象序列化后进行传输,所以对于本身就是 `protobuf` 对象的方法来说,没有任何其他逻辑。 + +使用 `protobuf` 插件编译后接口如下: +```java +public interface PbGreeter { + + static final String JAVA_SERVICE_NAME = "org.apache.dubbo.sample.tri.PbGreeter"; + static final String SERVICE_NAME = "org.apache.dubbo.sample.tri.PbGreeter"; + + static final boolean inited = PbGreeterDubbo.init(); + + org.apache.dubbo.sample.tri.GreeterReply greet(org.apache.dubbo.sample.tri.GreeterRequest request); + + default CompletableFuture greetAsync(org.apache.dubbo.sample.tri.GreeterRequest request){ + return CompletableFuture.supplyAsync(() -> greet(request)); + } + + void greetServerStream(org.apache.dubbo.sample.tri.GreeterRequest request, org.apache.dubbo.common.stream.StreamObserver responseObserver); + + org.apache.dubbo.common.stream.StreamObserver greetStream(org.apache.dubbo.common.stream.StreamObserver responseObserver); +} +``` + +## Triple 新特性 Stream 流 +Stream 是 Dubbo3 新提供的一种调用类型,在以下场景时建议使用流的方式: + +- 接口需要发送大量数据,这些数据无法被放在一个 RPC 的请求或响应中,需要分批发送,但应用层如果按照传统的多次 RPC 方式无法解决顺序和性能的问题,如果需要保证有序,则只能串行发送 +- 流式场景,数据需要按照发送顺序处理, 数据本身是没有确定边界的 +- 推送类场景,多个消息在同一个调用的上下文中被发送和处理 + +Stream 分为以下三种: +- SERVER_STREAM(服务端流) +![SERVER_STREAM](/imgs/v3/migration/tri/migrate-server-stream.png) +- CLIENT_STREAM(客户端流) +![CLIENT_STREAM](/imgs/v3/migration/tri/migrate-client-stream.png) +- BIDIRECTIONAL_STREAM(双向流) +![BIDIRECTIONAL_STREAM](/imgs/v3/migration/tri/migrate-bi-stream.png) + +> 由于 `java` 语言的限制,BIDIRECTIONAL_STREAM 和 CLIENT_STREAM 的实现是一样的。 + +在 Dubbo3 中,流式接口以 `SteamObserver` 声明和使用,用户可以通过使用和实现这个接口来发送和处理流的数据、异常和结束。 + +> 对于 Dubbo2 用户来说,可能会对StreamObserver感到陌生,这是Dubbo3定义的一种流类型,Dubbo2 中并不存在 Stream 的类型,所以对于迁移场景没有任何影响。 + +流的语义保证 +- 提供消息边界,可以方便地对消息单独处理 +- 严格有序,发送端的顺序和接收端顺序一致 +- 全双工,发送不需要等待 +- 支持取消和超时 + +## 非 PB 序列化的流 +1. api +```java +public interface IWrapperGreeter { + + StreamObserver sayHelloStream(StreamObserver response); + + void sayHelloServerStream(String request, StreamObserver response); +} +``` + +> Stream 方法的方法入参和返回值是严格约定的,为防止写错而导致问题,Dubbo3 框架侧做了对参数的检查, 如果出错则会抛出异常。 +> 对于 `双向流(BIDIRECTIONAL_STREAM)`, 需要注意参数中的 `StreamObserver` 是响应流,返回参数中的 `StreamObserver` 为请求流。 + +2. 实现类 +```java +public class WrapGreeterImpl implements WrapGreeter { + + //... + + @Override + public StreamObserver sayHelloStream(StreamObserver response) { + return new StreamObserver() { + @Override + public void onNext(String data) { + System.out.println(data); + response.onNext("hello,"+data); + } + + @Override + public void onError(Throwable throwable) { + throwable.printStackTrace(); + } + + @Override + public void onCompleted() { + System.out.println("onCompleted"); + response.onCompleted(); + } + }; + } + + @Override + public void sayHelloServerStream(String request, StreamObserver response) { + for (int i = 0; i < 10; i++) { + response.onNext("hello," + request); + } + response.onCompleted(); + } +} +``` + +3. 调用方式 +```java +delegate.sayHelloServerStream("server stream", new StreamObserver() { + @Override + public void onNext(String data) { + System.out.println(data); + } + + @Override + public void onError(Throwable throwable) { + throwable.printStackTrace(); + } + + @Override + public void onCompleted() { + System.out.println("onCompleted"); + } +}); + + +StreamObserver request = delegate.sayHelloStream(new StreamObserver() { + @Override + public void onNext(String data) { + System.out.println(data); + } + + @Override + public void onError(Throwable throwable) { + throwable.printStackTrace(); + } + + @Override + public void onCompleted() { + System.out.println("onCompleted"); + } +}); +for (int i = 0; i < n; i++) { + request.onNext("stream request" + i); +} +request.onCompleted(); +``` + +## Protobuf 序列化的流 + +对于 `Protobuf` 序列化方式,推荐编写 `IDL` 使用 `compiler` 插件进行编译生成。生成的代码大致如下: +```java +public interface PbGreeter { + + static final String JAVA_SERVICE_NAME = "org.apache.dubbo.sample.tri.PbGreeter"; + static final String SERVICE_NAME = "org.apache.dubbo.sample.tri.PbGreeter"; + + static final boolean inited = PbGreeterDubbo.init(); + + //... + + void greetServerStream(org.apache.dubbo.sample.tri.GreeterRequest request, org.apache.dubbo.common.stream.StreamObserver responseObserver); + + org.apache.dubbo.common.stream.StreamObserver greetStream(org.apache.dubbo.common.stream.StreamObserver responseObserver); +} +``` + +## 流的实现原理 + +`Triple`协议的流模式是怎么支持的呢? + +- 从协议层来说,`Triple` 是建立在 `HTTP2` 基础上的,所以直接拥有所有 `HTTP2` 的能力,故拥有了分 `stream` 和全双工的能力。 + +- 框架层来说,`StreamObserver` 作为流的接口提供给用户,用于入参和出参提供流式处理。框架在收发 stream data 时进行相应的接口调用, 从而保证流的生命周期完整。 + +## Triple 与应用级注册发现 + +关于 Triple 协议的应用级服务注册和发现和其他语言是一致的,可以通过下列内容了解更多。 + +- [服务发现](/zh-cn/docs/concepts/service-discovery/) +- [应用级地址发现迁移指南](/zh-cn/docs/migration/migration-service-discovery/) + +## 与 GRPC 互通 + +通过对于协议的介绍,我们知道 `Triple` 协议是基于 `HTTP2` 并兼容 `GRPC`。为了保证和验证与`GRPC`互通能力,Dubbo3 也编写了各种从场景下的测试。详细的可以通过[这里](https://github.com/apache/dubbo-samples/blob/master/3-extensions/protocol/dubbo-samples-triple/README.MD) 了解更多。 + + +{{% alert title="未来: Everything on Stub" color="primary" %}} + +用过 `Grpc` 的同学应该对 `Stub` 都不陌生。 +Grpc 使用 `compiler` 将编写的 `proto` 文件编译为相关的 protobuf 对象和相关 rpc 接口。默认的会同时生成几种不同的 `stub` + +- blockingStub +- futureStub +- reactorStub +- ... + +`stub` 用一种统一的使用方式帮我们屏蔽了不同调用方式的细节。不过目前 `Dubbo3` 暂时只支持传统定义接口并进行调用的使用方式。 + +在不久的未来,`Triple` 也将实现各种常用的 `Stub`,让用户写一份`proto`文件,通过 `comipler` 可以在任意场景方便的使用,请拭目以待。 +{{% /alert %}} diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/upgrades-and-compatibility/migration.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/upgrades-and-compatibility/migration.md new file mode 100644 index 000000000000..3cee46083f52 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/upgrades-and-compatibility/migration.md @@ -0,0 +1,305 @@ +--- +aliases: + - /zh/docs3-v2/java-sdk/reference-manual/protocol/triple/migration/ + - /zh-cn/docs3-v2/java-sdk/reference-manual/protocol/triple/migration/ + - /zh-cn/overview/mannual/java-sdk/reference-manual/upgrades-and-compatibility/migration/ +description: "从 dubbo2 升级到 dubbo3:涵盖 2.6.x、2.5.x、2.7.x 等版本升级。" +linkTitle: 升级到Dubbo3 +title: 从 dubbo2 升级到 dubbo3(涵盖 2.5.x、2.6.x、2.7.x 等版本) +type: docs +weight: 1 +--- + +总体来说,Dubbo2 升级到 Dubbo3 后的核心能力都是兼容的,对于 90% 以上的常规用户而言(指未做深度 SPI 扩展或源码定制的用户),可以非常简单的完成升级。 + +## 2.7.x 升级 Dubbo3 + +### 步骤一:升级核心依赖 + +首先,在应用中增加 bom 依赖管理: + +```xml + + + + org.apache.dubbo + dubbo-dependencies-bom + 3.3.0 + pom + import + + + +``` + +如果您之前用的是 `org.apache.dubbo:dubbo` 依赖,请升级到以下版本(如果项目中还有其它 dubbo 子模块依赖,请一并升级版本号): + +```xml + + org.apache.dubbo + dubbo + +``` + +如果之前的应用是 Spring Boot,建议使用以下 starter 依赖方式并升级到最新版本(如果之前未使用 starter,请删除所有老的 dubbo 模块依赖,直接使用以下配置即可): + +```xml + + org.apache.dubbo + dubbo-spring-boot-starter + +``` + +{{% alert title="Dubbo3 相关的 Spring、Spring Boot 版本升级说明" color="warning" %}} +Dubbo3 支持的 Spring、Spring Boot 版本兼容范围非常广: +* 既支持 Spring 3.x ~ Spring 5.x 相关版本,同时也支持 Spring Boot 1.x ~ Spring Boot 2.x 版本。如果遇到应用无法升级高版本 Spring、Spring Boot 的情况下,可排掉 `dubbo-spring-boot-starter` 或 `dubbo` 中传递的高版本 Spring 依赖,指定项目可接受的 Spring 版本依赖即可。 +* Spring Boot 3.x 和 Spring 6 版本由于需要 JDK 17 及以上版本,请参考 [Dubbo Spring Boot 手册]() 了解详情。 +{{% /alert %}} + +### 步骤二:升级其它组件依赖 +1. Nacos 注册中心 + + 如果您使用的是 Nacos 注册中心,在升级到 Dubbo3 之前,请先确保 Nacos Server 升级到 2.x 版本。除了 Nacos Server 之外,我们还需要升级应用侧的 Nacos Client 依赖。 + + 如果是 Spring Boot 应用,则可删除 nacos-client 依赖,直接使用 starter: + + ```xml + + org.apache.dubbo + dubbo-nacos-spring-boot-starter + + ``` + + 如果您当前不是 Spring Boot 应用,则直接更新 nacos-client 到 2.x 即可: + + ```xml + + com.alibaba + nacos-client + 2.3.0 + + ``` + +2. Zookeeper 注册中心 + + 如果是 Spring Boot 应用,则可删除之前老的 Zookeeper 相关依赖,直接使用 starter: + + ```xml + + org.apache.dubbo + dubbo-zookeeper-curator5-spring-boot-starter + + ``` + + 请注意,以上 `dubbo-zookeeper-curator5-spring-boot-starter` 请搭配 Zookeeper Server 3.8.0+ 版本使用。如果您当前正在使用的 Zookeeper Server 版本是 3.4.x 版本,则使用以下 starter: + + ```xml + + org.apache.dubbo + dubbo-zookeeper-spring-boot-starter + + ``` + + 如果不是 Spring Boot 应用,则可以使用以下依赖(推荐,需确保 Zookeeper Server 3.8.0 版本及以上): + + ```xml + + org.apache.dubbo + dubbo-dependencies-zookeeper-curator5 + + ``` + + 或者(对于 Zookeeper Server 3.4.x 版本用户) + + ```xml + + org.apache.dubbo + dubbo-dependencies-zookeeper + + ``` + {{% alert title="Zookeeper升级注意事项" color="warning" %}} + 请注意在使用以上方式管理 zookeeper 客户端依赖时,请清理项目中的其它 zookeper、curator 等依赖,完全使用 dubbo 提供的版本。 + {{% /alert %}} + +3. 其它组件升级 + + 除了注册中心之外,如果您有用到 Dubbo 的其它特性并且依赖第三方组件支持此特性,则您需要根据具体情况升级相应的组件版本,以确保组件能配合 Dubbo3 工作。 + +{{% alert title="查看依赖的三方组件版本" color="info" %}} +目的是确认项目中的三方依赖可以与 Dubbo3 正常工作(保持API兼容性)。正常来说,Dubbo 应用中并不会有非常多的第三方组件依赖,所以只要按需确认即可,另外,您可以参考 [Dubbo3 版本依赖的组件版本]() 确认合适的组件版本。 +{{% /alert %}} + +### 步骤三:兼容性检查 +{{% alert title="哪些用户需要做兼容性检查" color="info" %}} +对于大部分常规用户来说,可以跳过这个环节,通常是当前对 Dubbo 有深度定制的用户需要关注(SPI 扩展或源码定制)! +{{% /alert %}} + +#### 检查点一:是否有 SPI 扩展 + +1. 以下 SPI 扩展点在 Dubbo3 中已被移除,如有使用请注意: + + * 事件总线。出于事件管理的复杂度原因,EventDispatcher 和 EventListener 在 Dubbo 3.x 的支持已经删除。如果有对应扩展机制的使用请考虑重构为对应 Dubbo 功能的扩展。 + +2. 以下 SPI 扩展点的内部工作机制做了实现优化,可按需调整: + + * Filter 拦截器机制。可以基于 Filter 拦截器对请求进行拦截处理,在 2.7 中支持在路由选址后再对请求进行拦截处理。Dubbo3 中新增了 `ClusterFilter` SPI 定义,相比于之前的 `Filter` 扩展点,`ClusterFilter` 可以在很大程度上降低内存的占用,对与超大规模集群有较大的收益。 + +如果您有一些 Consumer 侧的拦截器是基于 Filter 扩展实现的,如果没有和远端的 IP 地址强绑定的逻辑,我们建议您将对应的 `org.apache.dubbo.rpc.Filter` SPI 扩展点迁移到 `org.apache.dubbo.rpc.cluster.filter.ClusterFilter` 这个新的 SPI 扩展点。 + +{{% alert title="警告" color="info" %}} +`org.apache.dubbo.rpc.Filter` 与 `org.apache.dubbo.rpc.cluster.filter.ClusterFilter` 在 Dubbo3 中同时支持,ClusterFilter 适配可按需调整,之前老的 Filter 实现都会继续生效,无需担心。 +{{% /alert %}} + +#### 检查点二:是否存在源码定制 +如果您正在使用的 Dubbo 框架包含一些私有源码定制(通过 javagent 或者 asm 等通过运行时对 Dubbo 的修改也在此范围内),则直接升级到开源 Dubbo3 版本可能有兼容性风险。对于这种非标准行为,Dubbo 无法保证其先前的兼容性,需要用户在升级前对所有源码修改进行检查,确保这部分内容完成对 Dubbo3 版本的适配后再升级上线。 + +> 此类问题可通过一些字节码层面的工具实现,如将进程 metaspace 内容遍历导出,过滤出 Dubbo 所有相关类及调用,以识别业务中、二方包中等直接依赖或增强 Dubbo 框架内部源码的位置。判断这些源码调用在 Dubbo3 内部是否仍然存在,以决策下一步升级动作。 + +### 步骤四:上线验证 +1. 灰度发布 +Dubbo 3 升级对于发布流程没有做特殊限制,按照正常业务发布即可。 +由于 Dubbo 是进行跨大版本的变更升级,发布中请尽可能多分批次发布,同时拉大第一批和第二批发布的时间间隔,做好充足的观察。 +发布过程中,我们建议您先升级应用的下游(也即是服务提供者),在验证服务处理正常以后再继续后续发布。 + +2. 观测应用指标 +在发布的过程中,有以下几个纬度的指标可以判断升级是否出现问题。 + +- 机器的 CPU、内存使用情况 +- 接口请求成功率 +- 接口请求 RT +- 日志的报错信息 +- 自定义扩展行为是否符合预期 + +## 2.6.x 及以下版本升级 Dubbo3 + +以下内容是针对 2.6.x、2.5.x 及以下版本用户的,帮助了解如何升级到 Dubbo3 版本。对于这些版本的用户而言,80% 的用户都是可以通过替换依赖实现平滑升级的,按以下步骤升级并做好检查即可。 + +### 步骤一:升级核心依赖 + +首先,必须升级之前老的 `com.alibaba:dubbo` 依赖坐标升级为 `org.apache.dubbo:dubbo`。 + +如下所示,将 `com.alibaba:dubbo` 依赖 + +```xml + + com.alibaba + dubbo + 2.6.5 + +``` + +替换为 `org.apache.dubbo:dubbo` 依赖,其它配置文件不用修改,如下所示: + +```xml + + 3.3.0 + + + + + org.apache.dubbo + dubbo-dependencies-bom + ${dubbo.version} + pom + import + + + + + + + org.apache.dubbo + dubbo + + +``` + +如果您是 Spring Boot 应用,则也可以使用 `org.apache.dubbo:dubbo-spring-boot-starter` 替换上面的 `org.apache.dubbo:dubbo` 依赖: + +```xml + + + org.apache.dubbo + dubbo-spring-boot-starter + + +``` + +### 步骤二:升级其它组件依赖 + +您需要升级注册中心(Nacos、Zookeeper或其它)等第三方组件,具体升级方法和目标版本请参考本文前面一节的 [2.7.x 版本升级到 Dubbo3](./#步骤二升级其它组件依赖) 中的详细说明,两者操作方法完全一样。 + +{{% alert title="请务必注意第三方组件的版本" color="info" %}} +* 对于很多 Dubbo 2.6.x 及以下的老用户来说,可能用到的组件(如注册中心)都是比较老的版本,这时升级到 Dubbo3 之前请仔细分析一下都有哪些功能和核心依赖组件,以评估组件升级到的目标版本。 +* 对于部分 Zookeeper 用户而言,如果 Zookeeper 版本较老,建议先升级 Zookeeper Server 到 3.8.x 及以上版本,再使用 Dubbo3 的 `dubbo-zookeeper-curator5-spring-boot-starter` 管理依赖,如上文 [2.7.x 升级](./#步骤二升级其它组件依赖) 一节中所述。 +{{% /alert %}} + +### 步骤三:兼容性检查 +如果升级依赖后出现API或SPI扩展相关的编译错误,请参考下文。如果您的 Dubbo 用法中有很多 SPI 扩展实现、内部 API 调用、或者改了一些内核源码,则需要重点关注这一部分的兼容性检查。 + +#### 检查点一:包名改造 + Dubbo3 与 2.6.x 及以下版本最大的一个区别就是坐标、包名的变化: + +1. Maven 坐标 GAV + +**groupId 由 `com.alibaba` 改为 `org.apache.dubbo`** + +2. package + +**package 前缀由 `com.alibaba.dubbo.*` 改为 `org.apache.dubbo.*`** + + +Maven坐标升级比较直观,只需要修改相应的pom文件就可以了;而package变更则可能会带来编译问题,但好在 Dubbo3 版本继续保留了绝大部分常用基础 API 和 SPI 的 `com.alibaba.dubbo` 适配支持,因此理论上升级 pom 后项目仍可直接编译成功。 + +#### 检查点二:API编程接口 + +- 注解 + +| 注解 | 推荐的新注解 | 说明 | +| --------------------- | ------------------ | ------------------ | +| @Reference | @DubboReference | 消费端服务引用注解 | +| @Service | @DubboService | 提供端服务暴露注解 | +| @EnableDubbo | @EnableDubbo | | +| 其他常用Spring注解API | 其他常用Spring注解API | | + + + +- 编程API + +| API | 说明 | +| ----------------- | ----------------------------- | +| ReferenceConfig | Service配置采集和引用编程接口 | +| ServiceConfig | Service配置采集和暴露编程接口 | +| ApplicationConfig | Application配置采集API | +| RegistryConfig | 注册中心配置采集API | +| ConsumerConfig | 消费端默认配置采集API | +| ProviderConfig | 提供端默认配置采集API | +| ProtocolConfig | RPC协议配置采集API | +| ArgumentConfig | 服务参数级配置采集API | +| MethodConfig | 服务方法级配置采集API | +| ModuleConfig | 服务治理Module配置采集API | +| MonitorConfig | 监控配置采集API | +| RpcContext | 编程上下文API | + + +#### 检查点三:SPI扩展 + +如果公司内部有维护的自定义SPI扩展库,在业务工程升级到 Dubbo3 上线之前,请务必先确保扩展库与 Dubbo3 的兼容性。如果发现有兼容性问题,建议通过修改包名引用的方式(从实现 `com.alibaba.dubbo.*` 包名类到实现 `org.apache.dubbo.*` 包名类 )完成升级,并重新打包。 + + + +| SPI扩展点 | 说明 | +| ------------- | ------------------------------------------------------------ | +| Registry | 包括`RegistryFactory`, `Registry` ,`RegistryService`等扩展点 | +| Protocol | RPC协议扩展 | +| Serialization | 序列化协议扩展 | +| Cluster | 集群容错策略扩展,如Failover, Failfast等 | +| Loadbalance | 负载均衡策略扩展 | +| Transporter | 传输框架扩展,如Netty等 | +| Monitor | 监控中心扩展,包括MonitorFactory, Monitor, MonitorService等 | +| Router | 路由规则扩展 | +| Filter | 拦截器扩展 | + +### 步骤四:上线验证 + +参考本文前面一节的 [2.7.x 版本升级到 Dubbo3](./#步骤四上线验证) 中讲到的验证方法。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/upgrades-and-compatibility/migration.md.bak b/content/zh-cn/overview/mannual/java-sdk/reference-manual/upgrades-and-compatibility/migration.md.bak new file mode 100644 index 000000000000..36d71387bb14 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/upgrades-and-compatibility/migration.md.bak @@ -0,0 +1,97 @@ +--- +aliases: + - /zh/docs3-v2/java-sdk/reference-manual/protocol/triple/migration/ + - /zh-cn/docs3-v2/java-sdk/reference-manual/protocol/triple/migration/ +description: Dubbo2 协议迁移 +linkTitle: Dubbo2 协议迁移 +title: Dubbo2 协议迁移 +type: docs +weight: 10 +--- + +## 迁移流程说明 + +Dubbo2 的用户使用 dubbo 协议 + 自定义序列化,如 hessian2 完成远程调用。 + +而 Grpc 的默认仅支持 Protobuf 序列化,对于 Java 语言中的多参数以及方法重载也无法支持。 + +Dubbo3 的之初就有一条目标是完美兼容 Dubbo2,所以为了 Dubbo2 能够平滑升级, Dubbo 框架侧做了很多工作来保证升级的无感,目前默认的序列化和 Dubbo2 保持一致为 `hessian2`。 + +所以,如果决定要升级到 Dubbo3 的 `Triple` 协议,只需要修改配置中的协议名称为 `tri` (注意: 不是 triple )即可。 + +接下来我们以一个使用 Dubbo2 协议的[工程](https://github.com/apache/dubbo-samples/tree/master/3-extensions/protocol/dubbo-samples-triple/src/main/java/org/apache/dubbo/sample/tri/migration)来举例,如何一步一步安全的升级。 + +1. 仅使用 `dubbo` 协议启动 `provider` 和 `consumer`,并完成调用。 +2. 仅使用 `tri` 协议启动 `provider` 和 `consumer`,并完成调用。 +3. 使用 `dubbo` 协议和 `tri` 协议 启动 `provider`,以 `dubbo` 协议启动 `consumer`,并完成调用。 + +### 定义服务 + +1. 定义接口 +```java +public interface IWrapperGreeter { + + //... + + /** + * 这是一个普通接口,没有使用 pb 序列化 + */ + String sayHello(String request); + +} +``` + +2. 实现类示例 +```java +public class IGreeter2Impl implements IWrapperGreeter { + + @Override + public String sayHello(String request) { + return "hello," + request; + } +} +``` + +### 仅使用 dubbo 协议 + +为保证兼容性,我们先将部分 provider 升级到 `dubbo3` 版本并使用 `dubbo` 协议。 + +使用 `dubbo` 协议启动一个 [`Provider`](https://github.com/apache/dubbo-samples/tree/master/3-extensions/protocol/dubbo-samples-triple/src/main/java/org/apache/dubbo/sample/tri/migration/ApiMigrationDubboProvider.java) 和 [`Consumer`](https://github.com/apache/dubbo-samples/tree/master/3-extensions/protocol/dubbo-samples-triple/src/main/java/org/apache/dubbo/sample/tri/migration/ApiMigrationDubboConsumer.java) 完成调用。 + +{{% alert title="输出结果" color="info" %}} +![result](/imgs/v3/migration/tri/dubbo3-tri-migration-dubbo-dubbo-result.png) +{{% /alert %}} + +### 仅使用 triple 协议 + +当所有的 consumer 都升级至支持 `Triple` 协议的版本后,provider 可切换至仅使用 `Triple` 协议启动 + +结构如图所示: +![strust](/imgs/v3/migration/tri/migrate-only-tri-strust.png) + +[Provider](https://github.com/apache/dubbo-samples/tree/master/3-extensions/protocol/dubbo-samples-triple/src/main/java/org/apache/dubbo/sample/tri/migration/ApiMigrationTriProvider.java) +和 [Consumer](https://github.com/apache/dubbo-samples/tree/master/3-extensions/protocol/dubbo-samples-triple/src/main/java/org/apache/dubbo/sample/tri/migration/ApiMigrationTriConsumer.java) 完成调用。 + + +{{% alert title="输出结果" color="info" %}} +![result](/imgs/v3/migration/tri/dubbo3-tri-migration-tri-tri-result.png) +{{% /alert %}} + +### 同时使用 dubbo 和 triple 协议 + +对于线上服务的升级,不可能一蹴而就同时完成 provider 和 consumer 升级, 需要按步操作, + +**第一步:保证业务稳定。** + +**第二步:provider 提供双协议的方式同时支持 dubbo + tri 两种协议的客户端。** + +结构如图所示: +![strust](/imgs/v3/migration/tri/migrate-dubbo-tri-strust.png) + +> 按照推荐升级步骤,provider 已经支持了 tri 协议,所以 dubbo3 的 consumer 可以直接使用 tri 协议 + +使用 `dubbo` 协议和 `triple` 协议启动[`Provider`](https://github.com/apache/dubbo-samples/tree/master/3-extensions/protocol/dubbo-samples-triple/src/main/java/org/apache/dubbo/sample/tri/migration/ApiMigrationBothProvider.java)和[`Consumer`](https://github.com/apache/dubbo-samples/tree/master/3-extensions/protocol/dubbo-samples-triple/src/main/java/org/apache/dubbo/sample/tri/migration/ApiMigrationBothConsumer.java) 完成调用。 + +{{% alert title="输出结果" color="info" %}} +![result](/imgs/v3/migration/tri/dubbo3-tri-migration-both-dubbo-tri-result.png) +{{% /alert %}} diff --git a/content/zh-cn/overview/mannual/java-sdk/upgrades-and-compatibility/2.x-to-3.x-compatibility-guide.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/upgrades-and-compatibility/version/2.x-to-3.x-compatibility-guide.md similarity index 98% rename from content/zh-cn/overview/mannual/java-sdk/upgrades-and-compatibility/2.x-to-3.x-compatibility-guide.md rename to content/zh-cn/overview/mannual/java-sdk/reference-manual/upgrades-and-compatibility/version/2.x-to-3.x-compatibility-guide.md index 81f3bb57f85d..10e9f39b5422 100644 --- a/content/zh-cn/overview/mannual/java-sdk/upgrades-and-compatibility/2.x-to-3.x-compatibility-guide.md +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/upgrades-and-compatibility/version/2.x-to-3.x-compatibility-guide.md @@ -2,6 +2,7 @@ aliases: - /zh/docs3-v2/java-sdk/upgrades-and-compatibility/2.x-to-3.x-compatibility-guide/ - /zh-cn/docs3-v2/java-sdk/upgrades-and-compatibility/2.x-to-3.x-compatibility-guide/ + - /zh-cn/overview/mannual/java-sdk/upgrades-and-compatibility/2.x-to-3.x-compatibility-guide/ description: Dubbo 3 升级与兼容性指南 linkTitle: 2.x 升级至 3.x title: 2.x 升级至 3.x @@ -9,10 +10,6 @@ type: docs weight: 1 --- - - - - ## 升级到 Dubbo 3.X 的收益 Dubbo3 依旧保持了 2.x 的经典架构,以解决微服务进程间通信为主要职责,通过丰富的服务治理(如地址发现、流量管理等)能力来更好的管控微服务集群;Dubbo3 对原有框架的升级是全面的,体现在核心 Dubbo 特性的几乎每个环节,通过升级实现了稳定性、性能、伸缩性、易用性的全面提升。 @@ -101,4 +98,4 @@ Dubbo 3 升级对于发布流程没有做特殊限制,按照正常业务发布 ## 注意事项 ### 1. 应用级服务发现 -由于 Dubbo 2.7 的应用级服务发现模型存在设计上的问题,在 Dubbo 3.x 中做了大量格式上的修改,所以 2.7.x 和 3.x 的应用级服务发现可能存在无法互相订阅调用的可能性。虽然 Dubbo 会剔除识别不了的实例,但是从稳定性的角度出发,如果您在 2.7.x 中开启了应用级服务发现特性(在 2.7.x 中非默认注册),我们建议先在 2.7.x 中关闭,待升级到 3.x 之后再开启。 \ No newline at end of file +由于 Dubbo 2.7 的应用级服务发现模型存在设计上的问题,在 Dubbo 3.x 中做了大量格式上的修改,所以 2.7.x 和 3.x 的应用级服务发现可能存在无法互相订阅调用的可能性。虽然 Dubbo 会剔除识别不了的实例,但是从稳定性的角度出发,如果您在 2.7.x 中开启了应用级服务发现特性(在 2.7.x 中非默认注册),我们建议先在 2.7.x 中关闭,待升级到 3.x 之后再开启。 diff --git a/content/zh-cn/overview/mannual/java-sdk/upgrades-and-compatibility/3.0-to-3.1-compatibility-guide.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/upgrades-and-compatibility/version/3.0-to-3.1-compatibility-guide.md similarity index 100% rename from content/zh-cn/overview/mannual/java-sdk/upgrades-and-compatibility/3.0-to-3.1-compatibility-guide.md rename to content/zh-cn/overview/mannual/java-sdk/reference-manual/upgrades-and-compatibility/version/3.0-to-3.1-compatibility-guide.md diff --git a/content/zh-cn/overview/mannual/java-sdk/upgrades-and-compatibility/3.1-to-3.2-compatibility-guide.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/upgrades-and-compatibility/version/3.1-to-3.2-compatibility-guide.md similarity index 100% rename from content/zh-cn/overview/mannual/java-sdk/upgrades-and-compatibility/3.1-to-3.2-compatibility-guide.md rename to content/zh-cn/overview/mannual/java-sdk/reference-manual/upgrades-and-compatibility/version/3.1-to-3.2-compatibility-guide.md diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/upgrades-and-compatibility/version/3.2-to-3.3-compatibility-guide.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/upgrades-and-compatibility/version/3.2-to-3.3-compatibility-guide.md new file mode 100644 index 000000000000..889828aa2c87 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/upgrades-and-compatibility/version/3.2-to-3.3-compatibility-guide.md @@ -0,0 +1,350 @@ +--- +aliases: + - /zh/docs3-v2/java-sdk/upgrades-and-compatibility/3.2-to-3.3-compatibility-guide/ + - /zh-cn/docs3-v2/java-sdk/upgrades-and-compatibility/3.2-to-3.3-compatibility-guide/ +description: Dubbo 3.3 升级与兼容性指南 +linkTitle: 3.2 升级至 3.3 +title: 3.2 升级至 3.3 +type: docs +weight: 4 + +--- + + +对于绝大多数的用户,升级到 Dubbo 3.3.0 是完全平滑的,仅需要修改依赖包版本即可。 + +```xml + + org.apache.dubbo + dubbo + 3.3.0 + +``` + +或者 + +```xml + + org.apache.dubbo + dubbo-spring-boot-starter + 3.3.0 + +``` + +# 兼容性 CheckList + +## 1. 默认序列化切换 + +Dubbo 3.3.0 版本开始默认序列化方式从 `fastjson2` 切换为 `hessian2`,对于升级到 3.3.0 的应用,Dubbo 会自动尝试采用 `hessian2` 进行序列化。 + +### Q1:为什么要切换默认序列化方式? + +`hessian2` 为 Dubbo 3.1.x 及以下版本中默认的序列化,长期的生产验证了其稳定性和兼容性,在评估了向前兼容性和长期可维护性后,Dubbo 团队决定将 `hessian-lite` 升级到最新 `hessian4` 主干版本,以支持 JDK17 和 JDK21。 + +升级到 Dubbo 3.3.0 以后,依赖的 `hessian-lite` 版本将同步升级为 `4.0.x`,主要包含以下修改: +- 同步 hessian 到上游 4.0.66 版本 +- 修复 JDK17 及 JDK21 下类可见性带来的兼容性问题 +- 支持 Record、ImmutableCollections 等 JDK9+ 特性 + +### Q2:会不会影响和低版本的 Dubbo 互通? + +部分场景下可能会有影响,具体如下: + +1. Dubbo 3.3.x Consumer 与 Dubbo 3.2.x Provider 互通时默认使用 Dubbo 3.2.x 中 `fastjson2` 优先的策略,无兼容性问题 +2. Dubbo 3.3.x Consumer 与 Dubbo 3.1.x 及以下版本 Provider 互通时默认使用 Dubbo 3.2.x 中 `fastjson2` 优先的策略,无兼容性问题 +3. Dubbo 3.2.x Consumer 与 Dubbo 3.3.x Provider 互通时默认使用 Dubbo 3.3.x 中 `hessian2` 优先的策略,此时由于 Dubbo 3.2.x Consumer 中携带的 `hessian2` 为低版本的,在 JDK >= 17 的场景下可能会出现兼容性问题,建议按照 Q3 中的最佳实践进行升级。 +4. Dubbo 3.1.x 及以下版本 Consumer 与 Dubbo 3.3.x Provider 互通时默认使用 Dubbo 3.3.x 中 `hessian2` 优先的策略,此时由于 Dubbo 3.1.x 及以下版本 Consumer 中携带的 `hessian2` 为低版本的,在 JDK >= 17 的场景下可能会出现兼容性问题,建议按照 Q3 中的最佳实践进行升级。 + +原理可参考[序列化协议升级指南](/zh-cn/overview/mannual/java-sdk/upgrades-and-compatibility/serialization-upgrade/)一文。 + +### Q3:升级序列化最佳实践是什么? + +1. 从 Dubbo 3.2.x 升级到 3.3.x 时,建议配置 `prefer-serialization` 为 `fastjson2,hessian2` 保持与 3.2.x 一致,待全集群升级完毕后在删除该配置,使用 `hessian2` 序列化 +2. 从 Dubbo 3.1.x 及以下版本升级到 3.3.x 时,无需配置 `prefer-serialization`,但需要注意避免与 JDK 升级一起进行,以免出现兼容性问题 + +### Q4:如果我仍想使用 `fastjson2`,怎么办? + +如果你不想使用 `hessian2`,可以配置 `prefer-serialization` 为 `fastjson2` 覆盖默认配置。(如 `dubbo.provider.prefer-serialization=fastjson2,hessian2`) + +--- + +## 2. 使用 `register=false` 不注册时将无法通过 QoS 手动注册 + +如果注册中心配置中配置了 `dubbo.registry.register=false` 或者指定服务配置 `dubbo.provider.register=false`: + +1. 在 Dubbo 3.2.x 及以前版本中,默认 Dubbo 不自动注册,使用 QoS 命令(`curl http://127.0.0.1:22222/online` )可以实现注册 +2. 在 Dubbo 3.3.x 中,默认 Dubbo 不自动注册,**使用 QoS 命令也无法注册** + +### Q1: 为什么要做这个调整? + +为了避免有的用户使用优雅上下线和隔离环境配置预期不一致,造成跨环境错误注册的情况,将 `register=false` 定义为**永远不注册**,`delay=-1` 且 `-Ddubbo.application.manual-register=true` 定义为**延迟到手动注册**。 + +### Q2: 实现优雅上线的最佳实践是什么? + +简单来说需要完成两个配置:`delay=-1` 且 `-Ddubbo.application.manual-register=true` + +`delay=-1` 实现指定服务允许优雅上线: +1. 如果需要对全部的服务都进行优雅上线,可以在 `dubbo.provider.delay=-1` 配置 +2. 如果只需要对部分服务进行优雅上线,可以在指定服务配置 `delay=-1` + +`-Ddubbo.application.manual-register=true` 实现手动注册: +对于需要进行优雅上线的机器,配置 `-Ddubbo.application.manual-register=true` JVM 参数 + +完善启动脚本: +对于需要进行优雅上线的机器,启动脚本中在启动结束后,主动调用 QoS 命令 `curl http://127.0.0.1:22222/online` 进行注册 + +考虑因素: +1. 全局一套代码,无论是线上环境、测试环境均对需要优雅上线的服务进行配置 `delay=-1` +2. 仅对线上环境进行 `-Ddubbo.application.manual-register=true` 配置,测试环境不配置,保证测试环境的服务能够自动注册 + +--- + +## 3. Nacos 兼容订阅默认关闭 + +从 Dubbo 3.3.x 版本开始,将不再订阅 Dubbo 2.7.3 及以前版本的兼容服务名,如果仍需要订阅,请配置 `-Dnacos.subscribe.legacy-name=true`。 + +### Q1: 为什么要做这个调整? + +在 Dubbo 2.7.3 及以前版本中,Dubbo 服务注册到 Nacos 时,订阅格式为 `providers(:{interfaceName})(:{version})(:{group})`,其中每个字段如果本身未空,会连带前面的 `:` 也一起省略,导致订阅名字不唯一,无法精确订阅。 + +如: + +1. 接口名:`com.foo.BarService`,版本:`1.0.0`,分组:`baz`,订阅名字为 `providers:com.foo.BarService:1.0.0:baz` +2. 接口名:`com.foo.BarService`,版本:空,分组:`baz`,订阅名字为 `providers:com.foo.BarService:baz` +3. 接口名:`com.foo.BarService`,版本:`baz`,分组:空,订阅名字为 `providers:com.foo.BarService:baz` + +如上,2 和 3 的订阅名字是一样的,但实际上是不同的服务。 + +为了解决这个问题,Dubbo 2.7.4 及以后版本中,订阅名字将会变为 `providers:({interfaceName}):({group}):({version})`,保证订阅名字的唯一性。 + +如: + +1. 接口名:`com.foo.BarService`,版本:`1.0.0`,分组:`baz`,订阅名字为 `providers:com.foo.BarService:1.0.0:baz` +2. 接口名:`com.foo.BarService`,版本:空,分组:`baz`,订阅名字为 `providers:com.foo.BarService::baz` +3. 接口名:`com.foo.BarService`,版本:`baz`,分组:空,订阅名字为 `providers:com.foo.BarService:baz:` + + +--- + +## 4. Dubbo Spring Boot Starters 更新 + +在 Dubbo 3.3.x 中,Dubbo Spring Boot Starters 为了方便依赖管理,提供了更多的 Starter 依赖。 + +此外:**为了遵循 Spring 规范的命名规范,从 3.3.0 版本开始,可观测相关 Starter 的 artifactId 从 `dubbo-spring-boot-observability-starter` 更名为 `dubbo-observability-spring-boot-starter`。** + +### Q1: Dubbo 3.3.x 版本中的 Starter 有哪些? +以下是 Dubbo 官方社区提供的 starter 列表(3.3.0+ 版本),方便在 Spring Boot 应用中快速使用: +* `dubbo-spring-boot-starter`,管理 dubbo 核心依赖,用于识别 application.properties 或 application.yml 中 `dubbo.` 开头的配置项,扫描 @DubboService 等注解。 +* `dubbo-spring-boot-starter3`,管理 dubbo 核心依赖,与 dubbo-spring-boot-starter 相同,支持 spring boot 3.2 版本。 +* `dubbo-nacos-spring-boot-starter`,管理 nacos-client 等依赖,使用 Nacos 作为注册中心、配置中心时引入。 +* `dubbo-zookeeper-spring-boot-starter`,管理 zookeeper、curator 等依赖,使用 Zookeeper 作为注册中心、配置中心时引入(Zookeeper server 3.4 及以下版本使用)。 +* `dubbo-zookeeper-curator5-spring-boot-starter`,管理 zookeeper、curator5 等依赖,使用 Zookeeper 作为注册中心、配置中心时引入。 +* `dubbo-sentinel-spring-boot-starter`,管理 sentinel 等依赖,使用 Sentinel 进行限流降级时引入。 +* `dubbo-seata-spring-boot-starter`,管理 seata 等依赖,使用 Seata 作为分布式事务解决方案时引入。 +* `dubbo-observability-spring-boot-starter`,加入该依赖将自动开启 Dubbo 内置的 metrics 采集,可用于后续的 Prometheus、Grafana 等监控系统。 +* `dubbo-tracing-brave-spring-boot-starter`,管理 brave/zipkin、micrometer 等相关相关依赖,使用 Brave/Zipkin 作为 Tracer,将 Trace 信息 export 到 Zipkin。 +* `dubbo-tracing-otel-otlp-spring-boot-starter`,管理 brave/zipkin、micrometer 等相关相关依赖,使用 OpenTelemetry 作为 Tracer,将 Trace 信息 export 到 OTlp Collector。 +* `dubbo-tracing-otel-zipkin-spring-boot-starter`,管理 brave/zipkin、micrometer 等相关相关依赖,使用 OpenTelemetry 作为 Tracer,将 Trace 信息 export 到 Zipkin。 + + +--- + +## 5. 迁移 dubbo-compiler 和 dubbo-native-plugin 到 dubbo-maven-plugin + +在 3.3 版本中,Dubbo 移除了 dubbo-native-plugin,同时 dubbo-native-plugin 相关的功能都将迁移至 dubbo-maven-plugin。此外,在 dubbo-maven-plugin 中也新增了对 dubbo-compiler 的支持。 + +更多过于 dubbo-maven-plugin 的说明请参考[配置详情](/zh-cn/overview/mannual/java-sdk/reference-manual/config/maven-plugin/)。 + +### Q1:为什么要做这个迁移和调整? + +1. 为了提升用户的使用体验,后续dubbo有关maven的插件能力都将统一使用dubbo-maven-plugin来提供。方便Dubbo用户使用和接入。而不需要一个特性对应一个插件,导致用户需要依赖多个plugin。 +2. 更加有利于后续Dubbo提供maven plugin能力时的维护和特性增强。 + +### Q2:如何迁移配置? + +1. 使用 Native Image 时,原配置为: +```xml + + + org.apache.dubbo + dubbo-maven-plugin + ${dubbo.version} + + com.example.nativedemo.NativeDemoApplication + + + + process-sources + + dubbo-process-aot + + + + +``` + +需要替换为: +```xml + + org.apache.dubbo + dubbo-maven-plugin + ${dubbo.version} + + org.apache.dubbo.registry.consumer.NativeDemoConsumerRegistryApplication + + + + process-sources + + dubbo-process-aot + + + + +``` + +注:仅需要替换 `artifactId` + +2. 使用 Triple + Protobuf 时,原配置为: +```xml + + + + kr.motd.maven + os-maven-plugin + 1.6.1 + + + + + org.xolstice.maven.plugins + protobuf-maven-plugin + 0.6.1 + + com.google.protobuf:protoc:${protoc.version}:exe:${os.detected.classifier} + + grpc-java + io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier} + + + + dubbo + org.apache.dubbo + dubbo-compiler + ${dubbo.compiler.version} + org.apache.dubbo.gen.tri.Dubbo3TripleGenerator + + + + + + + compile + + + + + + +``` + +可以直接替换为: +```xml + + + + org.apache.dubbo + dubbo-maven-plugin + ${dubbo.version} + + + + compile + + + + + + +``` + +注:无需引入 `os-maven-plugin` 和 `protobuf-maven-plugin`,仅需要引入 `dubbo-maven-plugin` 即可。 + +--- + +## 6. 移除原 REST 协议支持 + +在 Dubbo 3.3.x 中,Triple 协议支持了 Provider 侧原生 REST 协议的所有特性,同时移除了原 REST 协议实现的支持。 + +1. 如果仅使用 REST 协议作为服务提供者,请修改协议名字为 `tri`,使用方式无需改变,详见 [Triple 3.3新特性](/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/triple-3.3/) 和 [Triple REST 用户手册](/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/tripe-rest-manual/) +2. 如果需要使用 REST 协议作为服务消费者,可以添加以下依赖提供能力兼容 + +```xml + + org.apache.dubbo.extensions + dubbo-rpc-rest + 3.3.0 + +``` + +--- + +## 7. JDK 序列化 + +由于 JDK 原生序列化中,如果不手动添加配置,存在大量的反序列化漏洞,为了提升 Dubbo 的安全性,Dubbo 3.3.x 版本中默认不支持 JDK 序列化。 + +如果需要使用 JDK 序列化,可以添加以下依赖提供能力兼容,但请注意,**这可能会引入安全风险**。 + +```xml + + org.apache.dubbo.extensions + dubbo-serialization-jdk + 3.3.0 + +``` + +--- + +## 8. 传递依赖变更 + +在 Dubbo 3.3.x 中,默认不再传递以下依赖,如有需要请按需引入: + +```xml + + org.springframework + spring-core + + + org.springframework + spring-beans + + + org.springframework + spring-context + + + com.alibaba.spring + spring-context-support + +``` + +同时,新增传递以下依赖: + +```xml + + com.google.protobuf + protobuf-java + + + com.google.protobuf + protobuf-java-util + +``` + +注:Dubbo 从 3.3.x 开始不再依赖 `com.alibaba.spring:spring-context-support` 实现自身能力,如果需要请自行引入。 + +--- + +## 9. Zookeeper 3.4 支持移除 + +由于 Zookeeper 3.4.x 已经 EOL 4 年多了,为了降低 Dubbo 的维护成本,Dubbo 3.3.x 版本中移除了对 Zookeeper 3.4.x 的支持,请迁移 Curator (如有)到 5.x 版本。 diff --git a/content/zh-cn/overview/mannual/java-sdk/reference-manual/upgrades-and-compatibility/version/_index.md b/content/zh-cn/overview/mannual/java-sdk/reference-manual/upgrades-and-compatibility/version/_index.md new file mode 100755 index 000000000000..7ce0943a83b5 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/reference-manual/upgrades-and-compatibility/version/_index.md @@ -0,0 +1,11 @@ +--- +aliases: + - /zh/docs3-v2/java-sdk/version/ + - /zh-cn/docs3-v2/java-sdk/version/ + - /zh-cn/overview/mannual/java-sdk/version/ +description: "Dubbo 各个版本变更记录(release note),跨版本升级兼容性说明。" +linkTitle: 版本变更记录 +title: 版本变更记录 +type: docs +weight: 100 +--- diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/_index.md b/content/zh-cn/overview/mannual/java-sdk/tasks/_index.md new file mode 100755 index 000000000000..39d273ea7063 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/_index.md @@ -0,0 +1,10 @@ +--- +aliases: + - /zh/overview/tasks/ + - /zh-cn/overview/tasks/ +description: "" +linkTitle: 使用教程 +title: 跟随示例任务学习 Dubbo +type: docs +weight: 4 +--- diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/deploy/_index.md b/content/zh-cn/overview/mannual/java-sdk/tasks/deploy/_index.md new file mode 100644 index 000000000000..cb40bbb75b1d --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/deploy/_index.md @@ -0,0 +1,14 @@ +--- +aliases: + - /zh/overview/tasks/deploy/ + - /zh-cn/overview/tasks/deploy/ +description: "学习在 Kubernetes、Service Mesh(Kubernetes Service)、虚拟机(Zookeeper、Nacos)等场景部署 Dubbo 应用。" +feature: + description: | + 一键拉起服务治理体系,屏蔽底层跨平台的微服务基础设施复杂度,支持虚拟机、Docker、Kubernetes、服务网格等多种部署模式。 + title: 灵活部署模式 +linkTitle: 打包部署 +title: 打包并部署应用 +type: docs +weight: 5 +--- diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/deploy/deploy-on-kubernetes-service.md b/content/zh-cn/overview/mannual/java-sdk/tasks/deploy/deploy-on-kubernetes-service.md new file mode 100644 index 000000000000..3423f24dcc7b --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/deploy/deploy-on-kubernetes-service.md @@ -0,0 +1,116 @@ +--- +aliases: + - /zh/overview/tasks/deploy/deploy-on-vm/ + - /zh-cn/overview/tasks/deploy/deploy-on-vm/ +description: "部署 Dubbo 应用到服务网格(Service Mesh),基于 Kubernetes Service 与控制面。" +linkTitle: 服务网格 +title: 部署 Dubbo 应用到虚拟机环境 +type: docs +weight: 3 +--- +这种模式将 Dubbo Service 与 Kubernetes Service 概念映射起来,不再需要 Nacos 等传统注册中心,而是由 Kubernetes APISERVER 承担注册中心指责。 + + + +## 安装 Control Plane +在这个模式下,我们需要安装 `dubbo-control-plane` +> 这里是要用 istio 配合一起工作(提供xds推送能力),还是dubbo-control-plane自己实现xds server? + +```yaml +dubboctl manifests install --profile=control-plane +``` + +## 部署应用 +### 打包镜像 +### 定义 YAML +请查看 dubbo-samples 了解示例 + +```yaml +kind: service +``` + +```yaml +kind: deployment +``` + +### 优雅上下线 + +配置 probe +配置 pre-stop + +### 观测服务状态 + +## 与 Service Mesh 的区别 + + + + + + + + +## 特性说明 +[Pod 的生命周期](https://kubernetes.io/zh/docs/concepts/workloads/pods/pod-lifecycle/) 与服务调度息息相关,通过对 Kubernetes 官方探针的实现,能够使 Dubbo3 乃至整个应用的生命周期与 Pod 的生命周期,在 Pod 的整个生命周期中,影响到 Pod 的就只有健康检查这一部分, 我们可以通过配置 liveness probe(存活探针)和 readiness probe(可读性探针)来影响容器的生命周期。 + +通过 Dubbo3 的 SPI 机制,在内部实现多种“探针”,基于 Dubbo3 QOS 运维模块的 HTTP 服务,使容器探针能够获取到应用内对应探针的状态。另外,SPI 的实现机制也利于用户自行拓展内部“探针”,使整个应用的生命周期更有效的进行管控。 + +**三种探针对应的 SPI 接口** + +- livenessProbe: `org.apache.dubbo.qos.probe.LivenessProbe` +- readinessProbe: `org.apache.dubbo.qos.probe.ReadinessProbe` +- startupProbe: `org.apache.dubbo.qos.probe.StartupProbe` + +接口将自动获取当前应用所有 SPI 的实现,对应接口的 SPI 实现均成功就绪则接口返回成功。 + +Dubbo3 SPI 更多扩展的介绍见 [Dubbo SPI扩展](/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/) + +## 使用场景 +`liveness probe` 来确定你的应用程序是否正在运行,查看是否存活。 + +`readiness probe` 来确定容器是否已经就绪可以接收流量过来,是否准备就绪,是否可以开始工作。 + +`startup probe` 来确定容器内的应用程序是否已启动,如果提供了启动探测则禁用所有其他探测,直到它成功为止,如果启动探测失败则杀死容器,容器将服从其重启策略。如果容器没有提供启动探测,则默认状态为成功。 + +## 使用方式 + +### 存活检测 + +对于 livenessProbe 存活检测,由于 Dubbo3 框架本身无法获取到应用的存活状态,因此本接口无默认实现,且默认返回成功。开发者可以根据 SPI 定义对此 SPI 接口进行拓展,从应用层次对是否存活进行判断。 + +关于 [liveness 存活探针](/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/liveness/) 扩展示例 +### 就绪检测 + +对于 readinessProbe 就绪检测,目前 Dubbo3 默认提供了两个检测维度,一是对 Dubbo3 服务自身是否启停做判断,另外是对所有服务是否存在已注册接口,如果所有服务均已从注册中心下线(可以通过 QOS 运维进行操作)将返回未就绪的状态。 + +关于 [readiness 就绪探针](/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/readiness/) 扩展示例 + +### 启动检测 + +对于 startupProbe 启动检测,目前 Dubbo3 默认提供了一个检测维度,即是在所有启动流程(接口暴露、注册中心写入等)均结束后返回已就绪状态。 + +关于 [startup 启动探针](/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/startup/) 扩展示例 + +### 参考示例 +```yaml +livenessProbe: + httpGet: + path: /live + port: 22222 + initialDelaySeconds: 5 + periodSeconds: 5 +readinessProbe: + httpGet: + path: /ready + port: 22222 + initialDelaySeconds: 5 + periodSeconds: 5 +startupProbe: + httpGet: + path: /startup + port: 22222 + failureThreshold: 30 + periodSeconds: 10 +``` +> QOS 当计算节点检测到内存压力时,kuberentes 会 BestEffort -> Burstable -> Guaranteed 依次驱逐 Pod。 + +目前三种探针均有对应的接口,路径为 QOS 中的命令,端口信息请根据 QOS 配置进行对应修改(默认端口为 22222)。其他参数请参考 [Kubernetes官方文档说明](https://kubernetes.io/zh/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/)。 diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/deploy/deploy-on-kubernetes.md b/content/zh-cn/overview/mannual/java-sdk/tasks/deploy/deploy-on-kubernetes.md new file mode 100644 index 000000000000..56fe5149adf5 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/deploy/deploy-on-kubernetes.md @@ -0,0 +1,89 @@ +--- +aliases: + - /zh/overview/tasks/deploy/deploy-on-vm/ + - /zh-cn/overview/tasks/deploy/deploy-on-vm/ +description: "部署 Dubbo 应用到 Kubernetes 环境,使用 Nacos 或者 Zookeeper 等作为注册中心。" +linkTitle: Kubernetes +title: 部署 Dubbo 应用到 Kubernetes 环境 +type: docs +weight: 2 +--- +这种模式与传统的非 Kubernetes 部署并无太大差异,如下图所示,仍然使用 Nacos 或者 Zookeeper 等作为注册中心,只不过将 Kubernetes 作为应用生命周期调度的底层平台。 + + + +## 安装 Nacos +在 Kubernetes 模式下,我们推荐使用 `dubboctl` 快速安装 Nacos、dubbo-control-plane、prometheus 等组件: + +```yaml +$ dubboctl install --profile=demo +``` + +{{% alert title="提示" color="primary" %}} +1. 请查看 dubboctl 了解更多细节 +2. 您也可以在此了解 Nacos 官方提供的 Kubernetes 集群安装方案 +{{% /alert %}} + + +## 部署应用 +我们仍然以 [快速开始]() 中的项目为例,演示应用打包部署的具体步骤。 + +首先,克隆示例项目到本地: +```shell +$ git clone -b main --depth 1 https://github.com/apache/dubbo-samples +```` + +切换到示例目录: +```shell +$ cd dubbo-samples/11-quickstart +``` + +### 打包镜像 +```shell +$ dubboctl build +# 具体写一下推送到 docker 仓库 +``` + +### 部署 + +```shell +$ dubboctl deploy +``` + +以下是生成的完整 Kubernetes manifests: + +```yaml + +``` + +执行以下命令,将应用部署到 Kubernetes 集群: +```shell +$ kubectl apply -f xxx.yml +``` + +### 查看部署状态 +如果之前已经使用 `dubboctl` 安装 dubbo-control-plane,则可以通过以下方式查看服务部署情况: + +```shell +$ kubectl port-forward +``` + +访问 `http://xxx` 查看服务部署详情。 + +### 优雅上下线 +如上面的架构图所示,我们仍然使用 Nacos 作为注册中心,因此,与传统 Linux 部署模式类似,控制实例发布到注册中心、实例从注册中心摘除的时机,是我们实现优雅上下线的关键: +1. 上线阶段,通过 [延迟发布]() 机制控制实例注册到注册中心的时机,通过开启 [消费端预热]() 确保流量缓慢的被转发到新节点上。 +2. 下线阶段,通过配置 `prestop` 确保先从注册中心摘除实例注册信息,之后再进入进程销毁过程。 + +优雅下线摘除实例的示例配置: + +```yaml +preStop: + exec: + command: ["/bin/sh","-c","curl /offline; sleep 10"] +``` + +{{% alert title="提示" color="primary" %}} +在这个模式下,由于 Dubbo 服务的发布与注销与注册中心强关联,因此与 Kubernetes 中的 liveness、readiness 关联并不大。在下一篇文档中,我们会讲到 Kubernetes Service 部署模式下如何配置 liveness、readiness。 +{{% /alert %}} + diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/deploy/deploy-on-vm.md b/content/zh-cn/overview/mannual/java-sdk/tasks/deploy/deploy-on-vm.md new file mode 100644 index 000000000000..695f09958df5 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/deploy/deploy-on-vm.md @@ -0,0 +1,120 @@ +--- +aliases: + - /zh/overview/tasks/deploy/deploy-on-vm/ + - /zh-cn/overview/tasks/deploy/deploy-on-vm/ +description: "传统基于 Zookeeper、Nacos 的注册中心部署架构,部署 Dubbo 应用到虚拟机环境" +linkTitle: 传统注册中心 +title: 传统基于 Zookeeper、Nacos 的注册中心部署架构,部署 Dubbo 应用到虚拟机环境 +type: docs +weight: 1 +--- + +下图是使用 Nacos、Zookeeper 作为注册中心的典型 Dubbo 微服务部署架构。 + + + +## 安装 Nacos +请参考以下文档了解如何在本地 [安装 Nacos]()。 + +## 部署应用 +我们仍然以 [快速开始]() 中的项目为例,演示应用打包部署的具体步骤。 + +克隆示例项目到本地: +```shell +$ git clone -b main --depth 1 https://github.com/apache/dubbo-samples +```` + +切换到示例目录: +```shell +$ cd dubbo-samples/11-quickstart +``` + +以下是两种打包部署模式: + +### 方式一:本地进程 + +本地打包进程: +```shell +$ mvn clean package +``` + +启动 Dubbo 进程: +```shell +$ java -jar ./quickstart-service/target/quickstart-service-0.0.1-SNAPSHOT.jar +``` + +{{% alert title="提示" color="primary" %}} +为了程序正常运行,请确保 `application.yml` 文件中的注册中心地址已经正确指向你想要的注册中心。 +{{% /alert %}} + +### 方式二:docker容器 + +```shell +$ docker build -f ./Dockerfile -t quickstart +``` + +```shell +$ docker run quickstart -p port1:port2 +# 对于一些端口或连接注册中心的细节要写清楚 +``` + +{{% alert title="提示" color="primary" %}} +Docker 容器环境下,不同容器间用于网络通信的地址需要特别关注,因此你可能需要设置 Dubbo 进程监听或者注册到注册中心的地址,请参考以下链接了解更多内容。 + +见 [dubbo 通过环境变量设置 host](https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-docker) + +有些部署场景需要动态指定服务注册的地址,如 docker bridge 网络模式下要指定注册宿主机 ip 以实现外网通信。dubbo 提供了两对启动阶段的系统属性,用于设置对外通信的ip、port地址。 + +* **DUBBO_IP_TO_REGISTRY**:注册到注册中心的 ip 地址 +* **DUBBO_PORT_TO_REGISTRY**:注册到注册中心的 port 端口 +* **DUBBO_IP_TO_BIND**:监听 ip 地址 +* **DUBBO_PORT_TO_BIND**:监听 port 端口 + +以上四个配置项均为可选项,如不配置 dubbo 会自动获取 ip 与端口,请根据具体的部署场景灵活选择配置。 +dubbo 支持多协议,如果一个应用同时暴露多个不同协议服务,且需要为每个服务单独指定 ip 或 port,请分别在以上属性前加协议前缀。 如: + +* **HESSIAN_DUBBO_PORT_TO_BIND**:hessian 协议绑定的 port +* **DUBBO_DUBBO_PORT_TO_BIND**:dubbo 协议绑定的 port +* **HESSIAN_DUBBO_IP_TO_REGISTRY**:hessian 协议注册的 ip +* **DUBBO_DUBBO_IP_TO_REGISTRY**:dubbo 协议注册的 ip + +PORT_TO_REGISTRY 或 IP_TO_REGISTRY 不会用作默认 PORT_TO_BIND 或 IP_TO_BIND,但是反过来是成立的。如: + +* 设置 `PORT_TO_REGISTRY=20881` 和 `IP_TO_REGISTRY=30.5.97.6`,则 `PORT_TO_BIND` 和 `IP_TO_BIND` 不受影响 +* 设置 `PORT_TO_BIND=20881` 和 `IP_TO_BIND=30.5.97.6`,则默认 `PORT_TO_REGISTRY=20881` 且 `IP_TO_REGISTRY=30.5.97.6` + +{{% /alert %}} + +### 查看部署状态 +安装并运行 dubbo-control-plane,查看本地服务部署状态: + +1. 下载安装包 + + ```shell + $ curl -L https://raw.githubusercontent.com/apache/dubbo-kubernetes/master/release/downloadDubbo.sh | sh - + $ cd dubbo-$version/bin + ``` + +2. 运行以下命令,启动 dubbo-control-plane 进程 + ```shell + $ ./dubbo-cp run + ``` + +{{% alert title="提示" color="primary" %}} +为了 dubbo-control-plane 正常运行,请修改 `conf/dubbo-cp.yml` 以确保其指向你想要的注册中心。 +{{% /alert %}} + +访问 `http://xxx` 查看服务部署详情。 + +### 优雅上下线 +在使用传统注册中心的情况下,我们需要控制实例发布到注册中心、实例从注册中心摘除的时机,以实现优雅上下线: +1. 上线阶段,通过 [延迟发布]() 机制控制实例注册到注册中心的时机,通过开启 [消费端预热]() 确保流量缓慢的被转发到新节点上。 +2. 下线阶段,通过配置 `prestop` 确保先从注册中心摘除实例注册信息,之后再进入进程销毁过程。 + +在下线之前,建议调用以下 http 端口,先从注册中心摘除实例,然后再尝试停止进程 + +```shell +$ curl http://offline +$ sleep 10 +$ kill dubbo-pid +``` \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/develop/_index.md b/content/zh-cn/overview/mannual/java-sdk/tasks/develop/_index.md new file mode 100755 index 000000000000..9520e800ed8a --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/develop/_index.md @@ -0,0 +1,10 @@ +--- +aliases: + - /zh/overview/tasks/develop/ + - /zh-cn/overview/tasks/develop/ +description: 演示 Dubbo 框架提供的微服务开发 API 与编程模式 +linkTitle: 快速创建应用 +title: 快速创建应用 +type: docs +weight: 1 +--- diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/develop/api.md b/content/zh-cn/overview/mannual/java-sdk/tasks/develop/api.md new file mode 100644 index 000000000000..a927377b58a3 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/develop/api.md @@ -0,0 +1,299 @@ +--- +description: 作为一款 RPC 框架,Dubbo 定义了一套完善的 API 接口,我们可以基于原生 API 开发 RPC 服务和微服务应用 +linkTitle: 纯 API 开发模式 +title: 使用原生 API 开发 Dubbo 应用 +type: docs +weight: 2 +--- + +你可能已经注意到了,文档中大部分的功能、示例都是基于 Spring Boot 模式编写的,但 Spring Boot 或 Spring 仅仅是 Dubbo 适配的一种应用或者微服务开发模式。**作为一款 RPC 框架,Dubbo 定义了一套完善的 API 接口,我们可以基于原生 API 开发 Dubbo 应用**,纯 API 可以实现的业务场景包括: +* **轻量 RPC Server & Client**,通常用于一些应用内、基础组件、中间件等内的简单远程调用场景 +* **微服务应用**,不依赖 Spring 的情况下,直接用 API 开发微服务 + +## API 概览 +```java +public class Application { + public static void main(String[] args) { + DubboBootstrap.getInstance() + .protocol(new ProtocolConfig(CommonConstants.TRIPLE, 50051)) + .service(ServiceBuilder.newBuilder().ref(new DemoServiceImpl()).build()) + .start() + .await(); + } +} +``` + +以上是启动 Dubbo RPC Server 的一段代码示例,`DubboBootstrap` 实例代表一个 Dubbo 应用,是整个 Dubbo 应用的启动入口。在 DubboBootstrap 基础上,我们可以设置 `protocol`、`service`、`registry`、`metrics` 等来注册服务、连接注册中心等,这和我们在 Spring Boot 中调整 application.yml 或者 application.properties 文件是对等的作用。 + +官方推荐使用 `DubboBootstrap.start()` 作为应用的集中启动入口,但为了方便在进程启动后,在运行态单独发布一些服务,Dubbo 框架也允许直接调用 `ServiceConfig.export()` 或 `ReferenceConfig.refer()` 方法发布单个服务,这时 Service/Reference 会注册到默认的 DubboBootstrap 实例中,效果同调用 `DubboBootstrap.service(...).start()` 类似。 + +以下是开发中会常用到的一些组件,完整组件定义及详细参数说明请参见 [参考手册 - 配置项手册](/zh-cn/overview/mannual/java-sdk/reference-manual/config/properties/#配置项手册): + +| API 组件 | 全局唯一 | 核心方法或属性 | 说明 | +| --- | --- | --- | --- | +| DubboBootstrap | 是(多应用场景除外) | start()、stop() | DubboBootstrap 实例代表一个 Dubbo 应用,是整个 Dubbo 应用的启动入口。 | +| ApplicationConfig | 是 | name | 应用名及应用级别的一些全局配置 | +| MetricsConfig | 是 | protocol、prometheus、tracing | Metrics、tracing 采集相关配置 | +| ProtocolConfig | 否。多协议场景服务通过 id 关联 | id、name、port、serialization、threadpool | RPC 协议端口、序列化协议、运行时行为配置 | +| RegistrtyConfig | 否。多注册中心场景服务通过 id 关联 | id、address、protocol、group | 注册中心实现、地址、订阅等配置 | +| ConfigCenterConfig | 否。多配置中心场景服务通过 id 关联 | id、address、protocol、group、namespace | 配置中心实现、地址、分组隔离等配置 | +| MetadataReportConfig | 否。多元数据中心场景服务通过 id 关联 | id、address、protocol、group、namespace | 元数据中心实现、地址、分组隔离等配置 | +| ProviderConfig | 否 | 参考 ServiceConfig | 作为多个ServiceConfig的默认值 | +| ConsumerConfig | 否 | 参考 ReferenceConfig | 作为多个ReferenceConfig的默认值 | +| ServiceConfig | 否 | - 方法:export()
- 属性: interfaceClass、ref、group、version、timeout、retry | 一个 ServiceConfig 实例代表一个 RPC 服务 | +| ReferenceConfig | 否 | - 方法:refer()
- 属性:interfaceClass、group、version、timeout、retry、cluster、loadbalance | 一个 ReferenceConfig 实例代表一个 RPC 服务 | +| MethodConfig | 否 | name、oninvoke、onreturn、onthrow | ServiceConfig/ReferenceConfig 内嵌的方法级别配置 | +| ArgumentConfig | 否 | index、type、callback | MethodConfig 内嵌的参数级别配置 | + +## 轻量 RPC 示例 +本示例演示如何使用轻量 Dubbo SDK 开发 RPC Server 与 Client,示例使用 Java Interface 方式定义、发布和访问 RPC 服务,底层使用 Triple 协议通信。本示例完整代码请参见 dubbo-samples。 + +基于 Dubbo 定义的 Triple 协议,你可以轻松编写浏览器、gRPC 兼容的 RPC 服务,并让这些服务同时运行在 HTTP/1 和 HTTP/2 上。Dubbo Java SDK 支持使用 IDL 或编程语言特有的方式定义服务,并提供一套轻量的 API 来发布或调用这些服务。 + +### Maven 依赖 + +在基于 Dubbo RPC 编码之前,您只需要在项目添加一个非常轻量的 `dubbo`依赖包即可,以 Maven 为例: +```xml + + org.apache.dubbo + dubbo + 3.3.0 + +``` + +### 定义服务 + +定义一个名为 `DemoService`的标准 Java 接口作为 Dubbo 服务(Dubbo 还支持[基于 IDL 的服务定义模式](/zh-cn/overview/mannual/java-sdk/tasks/protocols/triple/idl/))。 + +```java +public interface DemoService { + String sayHello(String name); +} +``` + +实现 `DemoService` 接口并编写业务逻辑代码。 + +```java +public class DemoServiceImpl implements DemoService { + @Override + public String sayHello(String name) { + return "Hello " + name + ", response from provider."; + } +} +``` + +### 注册服务并启动 Server + +启动 server 并在指定端口监听 RPC 请求,在此之前,我们向 server 注册了以下信息: + +- 使用 `Triple` 作为通信 RPC 协议与并监听端口 `50051` +- 注册 Dubbo 服务到 `DemoService` server + +```java +public class Application { + public static void main(String[] args) { + DubboBootstrap.getInstance() + .protocol(new ProtocolConfig(CommonConstants.TRIPLE, 50051)) + .service(ServiceBuilder.newBuilder().ref(new DemoServiceImpl()).build()) + .start() + .await(); + } +} +``` + +### 访问服务 + +最简单方式是使用 HTTP/1.1 POST 请求访问服务,参数则以标准 JSON 格式作为 HTTP 负载传递。如下是使用 cURL 命令的访问示例: + +```shell +curl \ + --header "Content-Type: application/json" \ + --data '["Dubbo"]' \ + http://localhost:50051/org.apache.dubbo.demo.DemoService/sayHello +``` + +> 参数必须以数组格式进行传递,如果有多个参数,则格式类似 `["param1", {"param2-field": "param2-value"}, ...]`,具体请参见 triple 协议规范。 + +接下来,您也可以使用标准的 Dubbo client 请求服务,指定 server 地址即可发起 RPC 调用,其格式为 `protocol://ip:host` + +```java +public class Application { + public static void main(String[] args) { + DemoService demoService = + ReferenceBuilder.newBuilder() + .interfaceClass(DemoService.class) + .url("tri://localhost:50051") + .build() + .get(); + + String message = demoService.sayHello("dubbo"); + System.out.println(message); + } +} +``` + +恭喜您, 以上即是 Dubbo Java RPC 通信的基本使用方式! 🎉 + + +### 更多示例 +除了以上简单使用场景之外,开发者还可以发布多个服务、直接调用 ServiceConfig/ReferenceConfig 发布/订阅单个服务等。 + +#### 发布多个服务 +以下示例注册并发布任意多个服务 FooService、BarService,这些服务都将使用 providerConfig 中配置的默认超时时间,省去多个服务重复配置的烦恼。 + +```java +public static void main(String[] args) { + ProviderConfig providerConfig = new ProviderConfig(); + providerConfig.setTimeout(5000); + + ProtocolConfig protocolConfig = new ProtocolConfig(CommonConstants.TRIPLE, 50051); + + DubboBootstrap.getInstance() + .protocol(protocolConfig) + .provider(providerConfig) + .service(ServiceBuilder.newBuilder().ref(new FooServiceImpl()).build()) + .service(ServiceBuilder.newBuilder().ref(new BarServiceImpl()).build()) + .start() + .await(); +} +``` + +#### 发布单个服务 +直接调用 ServiceConfig.export() 发布服务,适用于运行态动态发布或订阅一个服务,对于 ReferenceConfig 同理。对于正常的应用启动流程,推荐使用 DubboBootstrap 而非直接调用 ServiceConfig.export() 发布单个服务。 + +1. 通过 ServiceConfig 发布服务 +```java +public static void main(String[] args) { + ServiceConfig demoServiceConfig = new ServiceConfig<>(); + demoServiceConfig.setInterface(DemoService.class); + demoServiceConfig.setRef(new DemoServiceImpl()); + demoServiceConfig.setVersion("1.0.0"); + + demoServiceConfig.export(); // this service will be registered to the default instance of DubboBootstrap.getInstance() +} +``` + +2. 通过 ReferenceConfig 订阅服务 + +```java +private DemoService referService() { + ReferenceConfig reference = new ReferenceConfig<>(); + reference.setInterfaceClass(DemoService.class); + + ReferenceCache cache = SimpleReferenceCache.getCache(); + try { + return cache.get(reference); + } catch (Exception e) { + throw new RuntimeException(e.getMessage()); + } +} +``` + +由于 ReferenceConfig.get() 创建的代理对象持有连接、地址等大量资源,因此建议缓存复用,Dubbo 官方提供了 SimpleReferenceCache 实现参考实现。关于 SimpleReferenceCache 更多内容,请参考 [RPC 框架](/zh-cn/overview/mannual/java-sdk/tasks/framework/more/reference-config-cache/)。 + +#### 获得引用代理 +使用 DubboBootstrap 作为启动入口,订阅服务并获得代理对象。 + +```java +public static void main(String[] args) { + ReferenceConfig reference = + ReferenceBuilder.newBuilder() + .interfaceClass(GreetingsService.class) + .build(); + DubboBootstrap.getInstance().reference(reference).start(); + GreetingsService service = reference.get(); +} +``` + +## 微服务示例 +### 注册中心和应用名 +相比于 RPC server、RPC client,基于 API 的微服务应用开发需要配置应用名、注册中心。 + +```java +public static void main(String[] args) { + DubboBootstrap.getInstance() + .application() + .registry(new RegistryConfig("nacos://127.0.0.1:8848")) + .protocol(new ProtocolConfig(CommonConstants.TRIPLE, 50051)) + .service(ServiceBuilder.newBuilder().ref(new DemoServiceImpl()).build()) + .service(ServiceBuilder.newBuilder().ref(new FooServiceImpl()).build()) + .start() + .await(); +} +``` + +### 多个注册中心 +多个注册中心可指定不同的 id,服务通过 id 关联注册中心实例。如下示例中,GreetingsService 发布到 bjRegistry,DemoService 发布到 hzRegistry。 + +```java +public static void main(String[] args) { + RegistryConfig bjRegistry = new RegistryConfig(); + bjRegistry.setId("bj"); + bjRegistry.setAddress("nacos://127.0.0.1:8848"); + + RegistryConfig hzRegistry = new RegistryConfig(); + hzRegistry.setId("hz"); + hzRegistry.setAddress("nacos://127.0.0.2:8848"); + + DubboBootstrap.getInstance() + .registry(bjRegistry) + .registry(hzRegistry) + .service(ServiceBuilder.newBuilder().registryIds("bj").interfaceClass(GreetingsService.class).ref(new GreetingsServiceImpl()).build()) + .service(ServiceBuilder.newBuilder().registryIds("hz").interfaceClass(DemoService.class).ref(new DemoServiceImpl()).build()) + .start() + .await(); +} +``` + +### 发布单个服务 +直接调用 ServiceConfig.export() 发布服务,适用于运行态动态发布或订阅一个服务,对于 ReferenceConfig 同理。对于正常的应用启动流程,推荐使用 DubboBootstrap 而非直接调用 ServiceConfig.export() 发布单个服务。 + +{{% alert title="注意" color="primary" %}} + +{{% /alert %}} + +1. 通过 ServiceConfig 发布服务 +```java +public static void main(String[] args) { + RegistryConfig hzRegistry = new RegistryConfig(); + hzRegistry.setId("hz"); + hzRegistry.setAddress("nacos://127.0.0.2:8848"); + + ServiceConfig demoServiceConfig = new ServiceConfig<>(); + demoServiceConfig.setInterface(DemoService.class); + demoServiceConfig.setRef(new DemoServiceImpl()); + demoServiceConfig.setVersion("1.0.0"); + + demoServiceConfig.setRegistry(hzRegistry); + + demoServiceConfig.export(); // this service will be registered to the default instance of DubboBootstrap.getInstance() +} +``` + +2. 通过 ReferenceConfig 订阅服务 + +```java +private DemoService referService() { + RegistryConfig hzRegistry = new RegistryConfig(); + hzRegistry.setId("hz"); + hzRegistry.setAddress("nacos://127.0.0.2:8848"); + + ReferenceConfig reference = new ReferenceConfig<>(); + reference.setInterfaceClass(DemoService.class); + + reference.setRegistry(hzRegistry) + + ReferenceCache cache = SimpleReferenceCache.getCache(); + try { + return cache.get(reference); + } catch (Exception e) { + throw new RuntimeException(e.getMessage()); + } +} +``` + +## 更多内容 + +- Triple 协议完全兼容 gRPC,您可以参考这里了解如何 [使用 IDL 编写 gRPC 兼容的服务](/zh-cn/overview/mannual/java-sdk/tasks/protocols/triple/idl/),或者 [使用其他通信协议](/zh-cn/overview/mannual/java-sdk/tasks/protocols/) +- 作为 RPC 框架,Dubbo 支持异步调用、连接管理、context上下文等,请参考 [RPC 框架核心功能](/zh-cn/overview/mannual/java-sdk/tasks/framework/) +- 使用 [Dubbo Spring Boot 开发微服务应用](/zh-cn/overview/mannual/java-sdk/tasks/develop/springboot/) diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/develop/springboot.md b/content/zh-cn/overview/mannual/java-sdk/tasks/develop/springboot.md new file mode 100644 index 000000000000..555ad30b27d3 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/develop/springboot.md @@ -0,0 +1,207 @@ +--- +description: Dubbo 提供了对 Spring 框架的完整支持,我们推荐使用官方提供的丰富的 `dubbo-spring-boot-starter` 高效开发 Dubbo 微服务应用。 +linkTitle: Spring Boot Starter +title: Spring Boot +type: docs +weight: 1 +--- + +Dubbo 提供了对 Spring 框架的完整支持,我们推荐使用官方提供的 `dubbo-spring-boot-starter` 高效开发 Dubbo 微服务应用。 + +## 创建项目 +创建 Dubbo 应用最快捷的方式就是使用官方项目脚手架工具 - start.dubbo.apache.org 在线服务。它可以帮助开发者创建 Spring Boot 结构应用,自动管理 `dubbo-spring-boot-starter` 等依赖和必要配置。 + +另外,Jetbrain 官方也提供了 Apache Dubbo 项目插件,可用于快速创建 Dubbo Spring Boot 项目,能力与 start.dubbo.apache.org 对等,具体安装使用请查看 [博客文章](/zh-cn/blog/2023/10/23/intellij-idea%EF%B8%8Fapache-dubboidea官方插件正式发布/) + +## dubbo-spring-boot-starter +在 [快速开始](/zh-cn/overview/mannual/java-sdk/quick-start/) 中,我们已经详细介绍了典型的 Dubbo Spring Boot 工程源码及其项目结构,不熟悉的开发者可以前往查看。 + +`dubbo-spring-boot-starter` 可为项目引入 dubbo 核心依赖,自动扫描 dubbo 相关配置与注解。 + +### Maven 依赖 + +使用 Dubbo Spring Boot Starter,首先引入以下 Maven 依赖 + +```xml + + + + org.apache.dubbo + dubbo-bom + 3.3.0 + pom + import + + + +``` + +然后,在相应模块的 pom 中增加必要的 starter 依赖: +```xml + + + org.apache.dubbo + dubbo-spring-boot-starter + + + org.apache.dubbo + dubbo-zookeeper-spring-boot-starter + + +``` + +`dubbo-spring-boot-starter` 和 `dubbo-zookeeper-spring-boot-starter` 是官方提供的 starter,提供了 Spring Boot 的集成适配,它们的版本号与 Dubbbo 主框架版本号完全一致。 + +### application.yml 配置文件 +以下是一个示例文件配置 + +```yaml +dubbo: + application: + name: dubbo-springboot-demo-provider + logger: slf4j + protocol: + name: triple + port: -1 + registry: + address: zookeeper://127.0.0.1:2181 +``` + +除 service、reference 之外的组件都可以在 application.yml 文件中设置,具体可参考 [配置列表](/zh-cn/overview/mannual/java-sdk/reference-manual/config/spring/spring-boot/#applicationyaml)。 + +service、reference 组件也可以通过 `id` 与 application 中的全局组件做关联,以下面配置为例。如果要扩展 service 或 reference 的注解配置,则需要增加 `dubbo.properties` 配置文件或使用其他非注解如 Java Config 方式,具体请看下文 [扩展注解的配置](#扩展注解配置)。 + +```yaml +dubbo: + application: + name: dubbo-springboot-demo-provider + protocol: + name: triple + port: -1 + registry: + id: zk-registry + address: zookeeper://127.0.0.1:2181 +``` + +通过注解将 service 关联到上文定义的特定注册中心(通过id关联) +```java +@DubboService(registry="zk-registry") +public class DemoServiceImpl implements DemoService {} +``` + +通过 Java Config 配置进行关联也是同样道理 +```java +@Configuration +public class ProviderConfiguration { + @Bean + public ServiceConfig demoService() { + ServiceConfig service = new ServiceConfig(); + service.setRegistry("zk-registry"); + return service; + } +} +``` + +### Dubbo 注解 +* `application.properties` 或 `application.yml` 配置文件。 +* `@DubboService`、`@DubboReference` 与 `EnableDubbo` 注解。其中 `@DubboService` 与 `@DubboReference` 用于标记 Dubbo 服务,`EnableDubbo` 启动 Dubbo 相关配置并指定 Spring Boot 扫描包路径。 + +#### @DubboService 注解 + +> `@Service` 注解从 3.0 版本开始就已经废弃,改用 `@DubboService`,以区别于 Spring 的 `@Service` 注解 + +定义好 Dubbo 服务接口后,提供服务接口的实现逻辑,并用 `@DubboService` 注解标记,就可以实现 Dubbo 的服务暴露 + +```java +@DubboService +public class DemoServiceImpl implements DemoService {} +``` + +如果要设置服务参数,`@DubboService` 也提供了常用参数的设置方式。如果有更复杂的参数设置需求,则可以考虑使用其他设置方式 +```java +@DubboService(version = "1.0.0", group = "dev", timeout = 5000) +public class DemoServiceImpl implements DemoService {} +``` + +#### @DubboReference 注解 + +> `@Reference` 注解从 3.0 版本开始就已经废弃,改用 `@DubboReference`,以区别于 Spring 的 `@Reference` 注解 + +```java +@Component +public class DemoClient { + @DubboReference + private DemoService demoService; +} +``` + +`@DubboReference` 注解将自动注入为 Dubbo 服务代理实例,使用 demoService 即可发起远程服务调用 + +#### @EnableDubbo 注解 +`@EnableDubbo` 注解必须配置,否则将无法加载 Dubbo 注解定义的服务,`@EnableDubbo` 可以定义在主类上 + +```java +@SpringBootApplication +@EnableDubbo +public class ProviderApplication { + public static void main(String[] args) throws Exception { + SpringApplication.run(ProviderApplication.class, args); + } +} +``` + +Spring Boot 注解默认只会扫描 main 类所在的 package,如果服务定义在其它 package 中,需要增加配置 `EnableDubbo(scanBasePackages = {"org.apache.dubbo.springboot.demo.provider"})` + +#### 扩展注解配置 +虽然可以通过 `@DubboService` 和 `DubboReference` 调整配置参数(如下代码片段所示),但总体来说注解是为易用性设计的,其提供的仅仅是 80% 场景下常用的配置项。在这种情况下,如果有更复杂的参数设置需求,可以使用 `Java Config` 或 `dubbo.properties` 两种方式。 + +```java +@DubboService(version = "1.0.0", group = "dev", timeout = 5000) +@DubboReference(version = "1.0.0", group = "dev", timeout = 5000) +``` + +#### 使用 Java Config 代替注解 + +注意,Java Config 是 `DubboService` 或 `DubboReference` 的替代方式,对于有复杂配置需求的服务建议使用这种方式。 + +```java +@Configuration +public class ProviderConfiguration { + @Bean + public ServiceBean demoService() { + ServiceBean service = new ServiceBean(); + service.setInterface(DemoService.class); + service.setRef(new DemoServiceImpl()); + service.setGroup("dev"); + service.setVersion("1.0.0"); + Map parameters = new HashMap<>(); + service.setParameters(parameters); + return service; + } +} +``` + + +#### 通过 dubbo.properties 补充配置 +对于使用 `DubboService` 或 `DubboReference` 的场景,可以通过在项目 resources 目录下增加 dubbo.properties 文件作为配置补充,[具体格式](../principle/#1-配置格式)这里有更详细解释。 + +```properties +dubbo.service.org.apache.dubbo.springboot.demo.DemoService.timeout=5000 +dubbo.service.org.apache.dubbo.springboot.demo.DemoService.parameters=[{myKey:myValue},{anotherKey:anotherValue}] +dubbo.reference.org.apache.dubbo.springboot.demo.DemoService.timeout=6000 +``` + +> properties 格式配置目前结构性不太强,比如体现在 key 字段冗余较多,后续会考虑提供对于 yaml 格式的支持。 + +## 更多微服务开发模式 +* [纯 API 开发模式](../api/) +* 其他 Spring 开发模式 + * [Spring XML](/zh-cn/overview/mannual/java-sdk/reference-manual/config/spring/xml/) + +## Dubbo 与 Spring Cloud 的关系 +Dubbo 与 Spring Cloud 是两套平行的微服务开发与解决方案,两者都提供了微服务定义、发布、治理的相关能力,对于微服务开发者来说,我们建议在开发之初就确定好 Apache Dubbo 与 Spring Cloud 之间的选型,尽量避免两个不同体系在同一集群中出现,以降低集群维护复杂度。而对于一些确需两套体系共存的场景,为了解决相互之间的通信问题,我们提供了 [Dubbo 与 Spring Cloud 异构微服务体系互通最佳实践](/zh-cn/blog/2023/10/07/微服务最佳实践零改造实现-spring-cloud-apache-dubbo-互通/) 解决方案。 + + Dubbo 与 Spring Boot 是互补的关系,Dubbo 在 Spring Boot 体系之上提供了完整的微服务开发、治理能力,关于这一点我们在另一篇文章中有更详尽的说明:[Dubbo、Spring Cloud 与 Istio](/zh-cn/overview/what/xyz-difference/)。 + + + diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/extensibility/_index.md b/content/zh-cn/overview/mannual/java-sdk/tasks/extensibility/_index.md new file mode 100755 index 000000000000..2778fcca2b18 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/extensibility/_index.md @@ -0,0 +1,65 @@ +--- +aliases: + - /zh/overview/tasks/extensibility/ + - /zh-cn/overview/tasks/extensibility/ +description: 演示 Dubbo 扩展能力特性的使用方式。 +linkTitle: 自定义扩展 +no_list: true +title: 自定义扩展 +type: docs +weight: 6 +--- + +通过如下任务项分别来介绍 Dubbo 的扩展特性。 + +{{< blocks/section color="white" height="auto">}} +
+
+
+
+
+

+ 自定义过滤器 +

+

通过SPI机制动态加载自定义过滤器,可以对返回的结果进行统一的处理、验证等,减少对开发人员的打扰。

+
+
+
+
+
+
+

+ 自定义路由 +

+

在服务调用的过程中根据实际使用场景自定义路由策略,可以有效的改善服务吞吐量和耗时。

+
+
+
+
+
+
+

+ 自定义协议 +

+

针对不同的异构系统可以使用自定义传输协议,为系统之间的整合屏蔽了协议之间的差异。 +

+
+
+
+
+
+
+

+ 自定义注册中心 +

+

将不同注册中心中的服务都纳入到 Dubbo 体系中,自定义注册中心是打通异构服务体系之间的利刃。 +

+
+
+
+
+
+
+ +{{< /blocks/section >}} diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/extensibility/filter.md b/content/zh-cn/overview/mannual/java-sdk/tasks/extensibility/filter.md new file mode 100644 index 000000000000..14f20f0d1397 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/extensibility/filter.md @@ -0,0 +1,94 @@ +--- +aliases: + - /zh/overview/tasks/extensibility/filter/ + - /zh-cn/overview/tasks/extensibility/filter/ +description: 在本文中,我们来了解如何扩展自定义的过滤器实现:一个可以对返回的结果进行统一的处理、验证等统一 Filter 处理器,减少对开发人员的打扰。 +linkTitle: Filter +no_list: true +title: Filter +type: docs +weight: 2 +--- + +在 [RPC框架 - Filter请求拦截](../../framework/filter/) 一节中,我们了解了 Filter 的工作机制,以及 Dubbo 框架提供的一些内置 Filter 实现。在本文中,我们来了解如何扩展自定义的过滤器实现:一个可以对返回的结果进行统一的处理、验证等统一 Filter 处理器,减少对开发人员的打扰。 + +本示例的完整源码请参见 [dubbo-samples-extensibility](https://github.com/apache/dubbo-samples/blob/master/10-task/dubbo-samples-extensibility/)。除了本示例之外,Dubbo 核心仓库 apache/dubbo 以及扩展库 [apache/dubbo-spi-extensions](https://github.com/apache/dubbo-spi-extensions/tree/master/dubbo-filter-extensions/) 中的众多 Filter 实现,都可以作为扩展参考实现。 + +## 任务详情 + +对所有调用Provider服务的请求在返回的结果的后面统一添加`'s customized AppendedFilter`。 + +## 实现方式 + +在Provider中自定义一个Filter,在Filter中修改返回结果。 + +#### 代码结构 +```properties +src + |-main + |-java + |-org + |-apache + |-dubbo + |-samples + |-extensibility + |-filter + |-provider + |-AppendedFilter.java (实现Filter接口) + |-resources + |-META-INF + |-application.properties (Dubbo Provider配置文件) + |-dubbo + |-org.apache.dubbo.rpc.Filter (纯文本文件) +``` +#### 代码详情 +```java +package org.apache.dubbo.samples.extensibility.filter.provider; + +import org.apache.dubbo.rpc.Filter; +import org.apache.dubbo.rpc.Result; +import org.apache.dubbo.rpc.Invoker; +import org.apache.dubbo.rpc.Invocation; +import org.apache.dubbo.rpc.RpcException; +import org.apache.dubbo.rpc.AsyncRpcResult; + +public class AppendedFilter implements Filter { + + @Override + public Result invoke(Invoker invoker, Invocation invocation) throws RpcException { + Result result= invoker.invoke(invocation); + // Obtain the returned value + Result appResponse = ((AsyncRpcResult) result).getAppResponse(); + // Appended value + appResponse.setValue(appResponse.getValue()+"'s customized AppendedFilter"); + return result; + } +} +``` + +#### SPI配置 +在`resources/META-INF/dubbo/org.apache.dubbo.rpc.Filter`文件中添加如下配置: +```properties +appended=org.apache.dubbo.samples.extensibility.filter.provider.AppendedFilter +``` + +#### 配置文件 +在`resources/application.properties`文件中添加如下配置,激活刚才的自定义 Filter 实现: +```properties +# Apply AppendedFilter +dubbo.provider.filter=appended +``` + +{{% alert title="注意" color="warning" %}} +除了通过配置激活 Filter 实现之外,还可以通过为实现类增加 @Activate 注解,以在满足某些条件时自动激活 Filter 实现,如: +```java +@Activate(group="provider") +public class AppendedFilter implements Filter {} +``` +这个 Filter 实现将在 Provider 提供者端自动被激活。 +{{% /alert %}} + +## 运行结果 +以**使用本地IDE**的方式来运行任务,结果如下: + +![dubbo-samples-extensibility-filter-output.jpg](/imgs/v3/tasks/extensibility/dubbo-samples-extensibility-filter-output.jpg) diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/extensibility/protocol.md b/content/zh-cn/overview/mannual/java-sdk/tasks/extensibility/protocol.md new file mode 100644 index 000000000000..0679b645872e --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/extensibility/protocol.md @@ -0,0 +1,188 @@ +--- +aliases: + - /zh/overview/tasks/extensibility/protocol/ + - /zh-cn/overview/tasks/extensibility/protocol/ +description: 本文讲解如何通过扩展 `org.apache.dubbo.rpc.Protocol` SPI,提供自定义的 RPC 协议实现。 +linkTitle: Protocol +no_list: true +title: Protocol +type: docs +weight: 2 +--- + +在 [通信协议](/zh-cn/overview/mannual/java-sdk/tasks/protocols/) 一章中,我们了解了 Dubbo 内置的几个核心 RPC 协议 `dubbo`、`rest`、和`tri` 以及它们的使用方式。本文讲解如何通过扩展 `org.apache.dubbo.rpc.Protocol` SPI,提供自定义的 RPC 协议实现。 + +自定义一套私有协议有两种方式,第一种是对原有的协议进行包装,添加一些特定的业务逻辑。另外一种是完全自定义一套协议。前者实现简单,在`dubbo`中也是有广泛的使用,比如:`ProtocolFilterWrapper`, `QosProtocolWrapper`, `ProtocolListenerWrapper`等。后者实现相对复杂,但却具有最大的灵活性,比如 Dubbo 框架内置的协议 `dubbo`、`triple` 协议都可以算作这种实现方式。 + +本示例的完整源码请参见 [dubbo-samples-extensibility](https://github.com/apache/dubbo-samples/blob/master/10-task/dubbo-samples-extensibility/)。除了本示例之外,Dubbo 核心仓库 apache/dubbo 以及扩展库 [apache/dubbo-spi-extensions](https://github.com/apache/dubbo-spi-extensions/tree/master/dubbo-protocol-extensions/) 中的众多 Protocol 实现,都可以作为扩展参考实现: + +```properties +# Dubbo对外支持的常用协议 +dubbo=org.apache.dubbo.rpc.protocol.dubbo.DubboProtocol +tri=org.apache.dubbo.rpc.protocol.tri.TripleProtocol +``` + +## 任务详情 + +基于现有的`dubbo`协议来实现自定义协议`edubbo`。 + +## 实现方式 + +通过对`dubbo`协议进行包装来实现`edubbo`协议。 + +#### 代码结构 + +##### Common + +```properties +src + |-main + |-java + |-org + |-apache + |-dubbo + |-samples + |-extensibility + |-protocol + |-common + |-EnhancedProtocol.java (实现Protocol接口) +``` + +##### Provider +```properties +src + |-main + |-java + |-org + |-apache + |-dubbo + |-samples + |-extensibility + |-protocol + |-provider + |-ExtensibilityProtocolProviderApplication.java + |-ExtensibilityProtocolServiceImpl.java + |-resources + |-META-INF + |-application.properties (Dubbo Provider配置文件) + |-dubbo + |-org.apache.dubbo.rpc.Protocol (纯文本文件) +``` + +##### Consumer +```properties +src + |-main + |-java + |-org + |-apache + |-dubbo + |-samples + |-extensibility + |-protocol + |-consumer + |-ExtensibilityProtocolConsumerApplication.java + |-ExtensibilityProtocolConsumerTask.java + |-resources + |-META-INF + |-application.properties (Dubbo Consumer配置文件) + |-dubbo + |-org.apache.dubbo.rpc.Protocol (纯文本文件) +``` + +#### 代码详情 +```java +package org.apache.dubbo.samples.extensibility.protocol.common; + +import org.apache.dubbo.common.URL; +import org.apache.dubbo.rpc.Protocol; +import org.apache.dubbo.rpc.Invoker; +import org.apache.dubbo.rpc.Exporter; +import org.apache.dubbo.rpc.ProtocolServer; +import org.apache.dubbo.rpc.RpcException; +import org.apache.dubbo.rpc.model.FrameworkModel; +import org.apache.dubbo.rpc.protocol.dubbo.DubboProtocol; + +import java.util.List; + +public class EnhancedProtocol implements Protocol { + + public EnhancedProtocol(FrameworkModel frameworkModel) { + this.protocol = new DubboProtocol(frameworkModel); + } + + private final Protocol protocol; + + @Override + public int getDefaultPort() { + return this.protocol.getDefaultPort(); + } + + @Override + public Exporter export(Invoker invoker) throws RpcException { + // do something + return this.protocol.export(invoker); + } + + @Override + public Invoker refer(Class type, URL url) throws RpcException { + // do something + return this.protocol.refer(type, url); + } + + @Override + public void destroy() { + this.protocol.destroy(); + } + + @Override + public List getServers() { + return protocol.getServers(); + } +} +``` + +#### SPI配置 + +##### Provider + +在`resources/META-INF/dubbo/org.apache.dubbo.rpc.Protocol`文件中添加如下配置: +```properties +edubbo=org.apache.dubbo.samples.extensibility.protocol.common.EnhancedProtocol +``` + +##### Consumer + +在`resources/META-INF/dubbo/org.apache.dubbo.rpc.Protocol`文件中添加如下配置: +```properties +edubbo=org.apache.dubbo.samples.extensibility.protocol.common.EnhancedProtocol +``` + +#### 配置文件 + +##### Provider + +在`resources/application.properties`文件中添加如下配置: +```properties +# 自定义协议 +dubbo.provider.protocol=edubbo +``` + +##### Consumer + +在`resources/application.properties`文件中添加如下配置: +```properties +# 自定义协议 +dubbo.consumer.protocol=edubbo +``` + +## 运行结果 +以**使用本地IDE**的方式来运行任务,结果如下: + +#### 注册协议 + +![dubbo-samples-extensibility-protocol-output2.jpg](/imgs/v3/tasks/extensibility/dubbo-samples-extensibility-protocol-output2.jpg) + +#### 输出结果 + +![dubbo-samples-extensibility-protocol-output1.png](/imgs/v3/tasks/extensibility/dubbo-samples-extensibility-protocol-output1.png) diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/extensibility/registry.md b/content/zh-cn/overview/mannual/java-sdk/tasks/extensibility/registry.md new file mode 100644 index 000000000000..8bef424e5038 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/extensibility/registry.md @@ -0,0 +1,134 @@ +--- +aliases: + - /zh/overview/tasks/extensibility/registry/ + - /zh-cn/overview/tasks/extensibility/registry/ +description: 本文讲解如何通过扩展 `org.apache.dubbo.registry.client.ServiceDiscovery` SPI,提供自定义的注册中心实现。 +linkTitle: Registry +no_list: true +title: Registry +type: docs +weight: 3 +--- + +在 [服务发现](/zh-cn/overview/mannual/java-sdk/tasks/protocols/) 一章中,我们了解了 Dubbo 内置的几个核心注册中心实现 `Nacos`、`Zookeeper` 的使用方式与工作原理。本文讲解如何通过扩展 `org.apache.dubbo.registry.client.ServiceDiscovery` 和 `org.apache.dubbo.registry.nacos.NacosServiceDiscoveryFactory` SPI,提供自定义的注册中心实现。 + +本示例的完整源码请参见 [dubbo-registry-etcd](https://github.com/apache/dubbo-spi-extensions/tree/3.2.0/dubbo-registry-extensions/dubbo-registry-etcd3)。除了本示例之外,Dubbo 核心仓库 apache/dubbo 以及扩展库 apache/dubbo-spi-extensions 中的众多注册中心扩展实现,都可以作为扩展参考实现: + +```properties +# Dubbo对外支持的常用注册中心实现 +nacos=org.apache.dubbo.registry.nacos.NacosServiceDiscoveryFactory +zookeeper=org.apache.dubbo.registry.zookeeper.ZookeeperServiceDiscoveryFactory +``` + +## 任务详情 +通过扩展 SPI 实现基于的 etcd 注册中心。 + +## 实现方式 + +#### 代码详情 +首先,通过继承 `AbstractServiceDiscoveryFactory` 实现 `ServiceDiscoveryFactory` 接口 + +```java +public class EtcdServiceDiscoveryFactory extends AbstractServiceDiscoveryFactory { + + @Override + protected ServiceDiscovery createDiscovery(URL registryURL) { + return new EtcdServiceDiscovery(applicationModel, registryURL); + } + +} +``` + +`EtcdServiceDiscovery` 的一些关键方法与实现如下: + +```java +public class EtcdServiceDiscovery extends AbstractServiceDiscovery { + + private final Set services = new ConcurrentHashSet<>(); + private final Map childListenerMap = new ConcurrentHashMap<>(); + + EtcdClient etcdClient; + + public EtcdServiceDiscovery(ApplicationModel applicationModel, URL registryURL) { + super(applicationModel, registryURL); + EtcdTransporter etcdTransporter = applicationModel.getExtensionLoader(EtcdTransporter.class).getAdaptiveExtension(); + + etcdClient = etcdTransporter.connect(registryURL); + + etcdClient.addStateListener(state -> { + if (state == StateListener.CONNECTED) { + try { + recover(); + } catch (Exception e) { + logger.error(e.getMessage(), e); + } + } + }); + + this.registryURL = registryURL; + } + + @Override + public void doRegister(ServiceInstance serviceInstance) { + try { + String path = toPath(serviceInstance); + etcdClient.putEphemeral(path, new Gson().toJson(serviceInstance)); + services.add(serviceInstance.getServiceName()); + } catch (Throwable e) { + throw new RpcException("Failed to register " + serviceInstance + " to etcd " + etcdClient.getUrl() + + ", cause: " + (OptionUtil.isProtocolError(e) + ? "etcd3 registry may not be supported yet or etcd3 registry is not available." + : e.getMessage()), e); + } + } + + @Override + protected void doUnregister(ServiceInstance serviceInstance) { + try { + String path = toPath(serviceInstance); + etcdClient.delete(path); + services.remove(serviceInstance.getServiceName()); + } catch (Throwable e) { + throw new RpcException("Failed to unregister " + serviceInstance + " to etcd " + etcdClient.getUrl() + ", cause: " + e.getMessage(), e); + } + } + + @Override + public void addServiceInstancesChangedListener(ServiceInstancesChangedListener listener) throws NullPointerException, IllegalArgumentException { + for (String serviceName : listener.getServiceNames()) { + registerServiceWatcher(serviceName, listener); + } + } + + @Override + public List getInstances(String serviceName) { + List children = etcdClient.getChildren(toParentPath(serviceName)); + if (CollectionUtils.isEmpty(children)) { + return Collections.emptyList(); + } + List list = new ArrayList<>(children.size()); + for (String child : children) { + ServiceInstance serviceInstance = new Gson().fromJson(etcdClient.getKVValue(child), DefaultServiceInstance.class); + list.add(serviceInstance); + } + return list; + } +} +``` + +#### SPI配置 + +在 `resources/META-INF/dubbo/org.apache.dubbo.registry.client.ServiceDiscoveryFactory` 文件中添加如下配置: + +```properties +etcd=org.apache.dubbo.registry.etcd.EtcdServiceDiscoveryFactory +``` + +## 使用方式 + +要开启 etcd 作为注册中心,修改应用中的 `resources/application.properties` 文件中的 registry 配置如下: + +```properties +dubbo.registry.address=etcd://host:port +``` + diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/extensibility/router.md b/content/zh-cn/overview/mannual/java-sdk/tasks/extensibility/router.md new file mode 100644 index 000000000000..816303ec22ba --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/extensibility/router.md @@ -0,0 +1,149 @@ +--- +aliases: + - /zh/overview/tasks/extensibility/router/ + - /zh-cn/overview/tasks/extensibility/router/ +description: 本文讲解如何通过扩展 Router 实现自定义路由策略,可以根据业务场景的特点来实现特定的路由方式。 +linkTitle: Router +no_list: true +title: Router +type: docs +weight: 4 +--- + +通过自定义路由,可以根据业务场景的特点来实现特定的路由方式。本示例 router 扩展实现源码请参见 [dubbo-samples-extensibility](https://github.com/apache/dubbo-samples/blob/master/10-task/dubbo-samples-extensibility/)。 + +## 开始之前 + +## 任务详情 + +对所有的请求都使用第一提供服务的Provider,如果该Provider下线,则从新选择一个新的Provider。 + +## 实现方式 + +在Consumer中自定义一个Router,在Router中将第一次调用的Provider保存下来,如果后续有请求调用且Provider列表中包含第一次调用时使用的Provider,则继续使用第一次调用时使用的Provider,否则重新选去一个Provider。 + +#### 代码结构 +```properties +src + |-main + |-java + |-org + |-apache + |-dubbo + |-samples + |-extensibility + |-router + |-consumer + |-router + |-StickFirstStateRouter.java (实现StateRouter接口) + |-StickFirstStateRouterFactory.java (实现StateRouterFactory接口) + |-resources + |-META-INF + |-application.properties (Dubbo Consumer配置文件) + |-dubbo + |-org.apache.dubbo.rpc.cluster.router.state.StateRouterFactory (纯文本文件) +``` +#### 代码详情 + ++ StickFirstStateRouter +```java +package org.apache.dubbo.samples.extensibility.router.consumer.router; + +import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.config.configcenter.ConfigChangeType; +import org.apache.dubbo.common.config.configcenter.ConfigChangedEvent; +import org.apache.dubbo.common.config.configcenter.ConfigurationListener; +import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; +import org.apache.dubbo.common.logger.LoggerFactory; +import org.apache.dubbo.common.utils.CollectionUtils; +import org.apache.dubbo.common.utils.Holder; +import org.apache.dubbo.rpc.Invocation; +import org.apache.dubbo.rpc.Invoker; +import org.apache.dubbo.rpc.RpcException; +import org.apache.dubbo.rpc.cluster.router.RouterSnapshotNode; +import org.apache.dubbo.rpc.cluster.router.state.AbstractStateRouter; +import org.apache.dubbo.rpc.cluster.router.state.BitList; + +public class StickFirstStateRouter extends AbstractStateRouter implements ConfigurationListener { + public StickFirstStateRouter(URL url) { + super(url); + } + + public static final String NAME = "STICK_FIRST_ROUTER"; + private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(StickFirstStateRouter.class); + private volatile BitList> firstInvokers; + + @Override + protected BitList> doRoute(BitList> invokers, URL url, Invocation invocation, boolean needToPrintMessage, Holder> routerSnapshotNodeHolder, Holder messageHolder) throws RpcException { + if (CollectionUtils.isEmpty(invokers)) { + if (needToPrintMessage) { + messageHolder.set("Directly Return. Reason: Invokers from previous router is empty."); + } + return invokers; + } + BitList> copy = invokers.clone(); + if (CollectionUtils.isEmpty(copy)) { + this.firstInvokers = new BitList<>(BitList.emptyList()); + this.firstInvokers.add(copy.get(0)); + } else { + this.firstInvokers = copy.and(invokers); + if(CollectionUtils.isEmpty(this.firstInvokers)){ + this.firstInvokers.add(copy.get(0)); + } + } + return this.firstInvokers; + } + + @Override + public void process(ConfigChangedEvent event) { + if (logger.isDebugEnabled()) { + logger.debug("Notification of tag rule, change type is: " + event.getChangeType() + ", raw rule is:\n " + + event.getContent()); + } + // Reset + if (event.getChangeType().equals(ConfigChangeType.DELETED)) { + this.firstInvokers = null; + } + } + + @Override + public void stop() { + super.stop(); + this.firstInvokers = null; + } +} +``` + ++ StickFirstStateRouterFactory +```java +package org.apache.dubbo.samples.extensibility.router.consumer.router; + +import org.apache.dubbo.common.URL; +import org.apache.dubbo.rpc.cluster.router.state.StateRouter; +import org.apache.dubbo.rpc.cluster.router.state.StateRouterFactory; + +public class StickFirstStateRouterFactory implements StateRouterFactory { + @Override + public StateRouter getRouter(Class interfaceClass, URL url) { + return new StickFirstStateRouter<>(url); + } +} +``` + +#### SPI配置 +在`resources/META-INF/dubbo/org.apache.dubbo.rpc.cluster.router.state.StateRouterFactory`文件中添加如下配置: +```properties +stickfirst=org.apache.dubbo.samples.extensibility.router.consumer.router.StickFirstStateRouterFactory +``` + +#### 配置文件 +在`resources/application.properties`文件中添加如下配置: +```properties +# 配置自定义路由 +dubbo.consumer.router=stickfirst +``` + +## 运行结果 +以**使用本地IDE**的方式来运行任务,结果如下: + +![dubbo-samples-extensibility-router-output.png](/imgs/v3/tasks/extensibility/dubbo-samples-extensibility-router-output.png) diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/extensibility/spi.md b/content/zh-cn/overview/mannual/java-sdk/tasks/extensibility/spi.md new file mode 100644 index 000000000000..724fe31266c5 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/extensibility/spi.md @@ -0,0 +1,66 @@ +--- +description: "Dubbo 的 SPI 插件扩展机制说明,讲解自定义 SPI 扩展的基本步骤。" +linkTitle: 如何自定义扩展 +title: "自定义 SPI 扩展的基本步骤" +type: docs +weight: 1 +--- + +下面以 `RPC 协议插件` 为例,说明如何利用 Dubbo 提供的 SPI 插件提供一个自定义的 RPC 协议实现。如果想了解 SPI 机制的工作原理以及框架内置的 SPI 扩展点列表,请查看 [参考手册 - SPI扩展](/zh-cn/overview/mannual/java-sdk/reference-manual/spi/overview)。 + +## 1. 提供 SPI 插件实现类 +提供一个 Java 类实现 `org.apache.dubbo.rpc.Protocol` 接口。 + +```java +package com.spi.demo; +import org.apache.dubbo.rpc.Protocol; + +@Activate +public class CustomizedProtocol implements Protocol { + // ... +} +``` + +## 2. 在指定文件配置实现类 + +在应用 `resources/META-INF/services/` 目录下添加 `org.apache.dubbo.rpc.Protocol` 文件,文件中增加如下配置: + +```properties +customized=com.spi.demo.CustomizedProtocol +``` + +{{% alert title="配置注意事项" color="info" %}} +* 文件名必须为 SPI 插件定义的 package 全路径名,具体取决于你要扩展的 SPI 定义,如示例中的 `resources/META-INF/services/org.apache.dubbo.rpc.Protocol`。 +* 文件中的内容必须是 `key=value` 形式,其中 `key` 可随便定义,但建议增加特定前缀以避免与 Dubbo 内置实现重名,`value` 必须设置为扩展类实现的全路径名。 +{{% /alert %}} + +## 3. 通过配置启用自定义协议实现 + +在应用中修改协议配置,告诉 Dubbo 框架使用自定义协议: + +```yaml +# 使用 Spring Boot,可修改 application.yml 或 application.properties +dubbo + protocol + name: customized +``` + +或者 + +```java +ProtocolConfig protocol = new ProtocolConfig(); +protocol.setName("cutomized"); +``` + +## 4. 更多示例 + +如果你想了解更完整示例,请查看本目录下的其他示例: +* [自定义协议扩展](../protocol) +* [自定义拦截器扩展](../filter) +* [自定义注册中心扩展](../registry) +* [自定义路由器扩展](../router) + + + + + diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/framework/_index.md b/content/zh-cn/overview/mannual/java-sdk/tasks/framework/_index.md new file mode 100755 index 000000000000..041f348d7aa8 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/framework/_index.md @@ -0,0 +1,9 @@ +--- +description: "Dubbo 是一款轻量的 RPC 框架,提供 Java、Go、Node.js、Javascript 等语言支持,帮助开发者构建浏览器、gRPC 兼容的 HTTP API。" +linkTitle: RPC框架 +title: Dubbo 作为轻量 RPC 框架解决组件通信问题 +type: docs +weight: 6 +--- + +{{% docs/section_list %}} \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/framework/async.md b/content/zh-cn/overview/mannual/java-sdk/tasks/framework/async.md new file mode 100644 index 000000000000..4bc64491a2f5 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/framework/async.md @@ -0,0 +1,230 @@ +--- +aliases: + - /zh/overview/tasks/develop/async/ + - /zh/docs3-v2/java-sdk/advanced-features-and-usage/service/async-call/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/async-call/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/async-execute-on-provider/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/async/ +description: 某些情况下希望dubbo接口异步调用,避免不必要的等待。 +linkTitle: 异步调用 +title: 异步调用 +type: docs +weight: 3 +--- + +Dubbo 异步调用分为 Provider 端异步调用和 Consumer 端异步两种模式。 +* Consumer 端异步是指发起 RPC 调用后立即返回,调用线程继续处理其他业务逻辑,当响应结果返回后通过回调函数通知消费端结果。 +* Provider 端异步执行将阻塞的业务从 Dubbo 内部线程池切换到业务自定义线程,避免Dubbo线程池的过度占用,有助于避免不同服务间的互相影响。 + +以下是消费端 consumer 异步调用的工作示例图: + +![/user-guide/images/future.jpg](/imgs/user/future.jpg) + +Provider 端异步执行和 Consumer 端异步调用是相互独立的,你可以任意正交组合两端配置。 ++ Consumer同步 - Provider同步 ++ Consumer异步 - Provider同步 ++ Consumer同步 - Provider异步 ++ Consumer异步 - Provider异步 + +本文档演示的完整示例源码请参见: +* [Consumer 服务调用异步](https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-async/dubbo-samples-async-simple-boot) +* [Provider 服务执行异步](https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-async/dubbo-samples-async-provider) +* [定义 CompletableFuture 方法签名的服务](https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-async/dubbo-samples-async-original-future) + +## Provider异步 + +### 1 使用CompletableFuture + +接口定义: +```java +public interface AsyncService { + /** + * 同步调用方法 + */ + String invoke(String param); + /** + * 异步调用方法 + */ + CompletableFuture asyncInvoke(String param); +} + +``` +服务实现: +```java +@DubboService +public class AsyncServiceImpl implements AsyncService { + + @Override + public String invoke(String param) { + try { + long time = ThreadLocalRandom.current().nextLong(1000); + Thread.sleep(time); + StringBuilder s = new StringBuilder(); + s.append("AsyncService invoke param:").append(param).append(",sleep:").append(time); + return s.toString(); + } + catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + return null; + } + + @Override + public CompletableFuture asyncInvoke(String param) { + // 建议为supplyAsync提供自定义线程池 + return CompletableFuture.supplyAsync(() -> { + try { + // Do something + long time = ThreadLocalRandom.current().nextLong(1000); + Thread.sleep(time); + StringBuilder s = new StringBuilder(); + s.append("AsyncService asyncInvoke param:").append(param).append(",sleep:").append(time); + return s.toString(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + return null; + }); + } +} + +``` +通过 return CompletableFuture.supplyAsync() ,业务执行已从 Dubbo 线程切换到业务线程,避免了对 Dubbo 线程池的阻塞。 + +### 2 使用AsyncContext + +Dubbo 提供了一个类似 Servlet 3.0 的异步接口AsyncContext,在没有 CompletableFuture 签名接口的情况下,也可以实现 Provider 端的异步执行。 + +接口定义: +```java +public interface AsyncService { + String sayHello(String name); +} + +``` + +服务实现: + +```java +public class AsyncServiceImpl implements AsyncService { + public String sayHello(String name) { + final AsyncContext asyncContext = RpcContext.startAsync(); + new Thread(() -> { + // 如果要使用上下文,则必须要放在第一句执行 + asyncContext.signalContextSwitch(); + try { + Thread.sleep(500); + } catch (InterruptedException e) { + e.printStackTrace(); + } + // 写回响应 + asyncContext.write("Hello " + name + ", response from provider."); + }).start(); + return null; + } +} + +``` + +## Consumer异步 + +### 1 使用CompletableFuture +```java +@DubboReference +private AsyncService asyncService; + +@Override +public void run(String... args) throws Exception { + //调用异步接口 + CompletableFuture future1 = asyncService.asyncInvoke("async call request1"); + future1.whenComplete((v, t) -> { + if (t != null) { + t.printStackTrace(); + } else { + System.out.println("AsyncTask Response-1: " + v); + } + }); + //两次调用并非顺序返回 + CompletableFuture future2 = asyncService.asyncInvoke("async call request2"); + future2.whenComplete((v, t) -> { + if (t != null) { + t.printStackTrace(); + } else { + System.out.println("AsyncTask Response-2: " + v); + } + }); + //consumer异步调用 + CompletableFuture future3 = CompletableFuture.supplyAsync(() -> { + return asyncService.invoke("invoke call request3"); + }); + future3.whenComplete((v, t) -> { + if (t != null) { + t.printStackTrace(); + } else { + System.out.println("AsyncTask Response-3: " + v); + } + }); + + System.out.println("AsyncTask Executed before response return."); +} +``` + +### 2 使用 RpcContext +在注解中配置: + +```java +@DubboReference(async="true") +private AsyncService asyncService; +``` + +也可以指定方法级别的异步配置: + +```java +@DubboReference(methods = {@Method(name = "sayHello", timeout = 5000)}) +private AsyncService asyncService; +``` + +接下来的调用即会是异步的: + +```java +// 此调用会立即返回null +asyncService.sayHello("world"); +// 拿到调用的Future引用,当结果返回后,会被通知和设置到此Future +CompletableFuture helloFuture = RpcContext.getServiceContext().getCompletableFuture(); +// 为Future添加回调 +helloFuture.whenComplete((retValue, exception) -> { + if (exception == null) { + System.out.println(retValue); + } else { + exception.printStackTrace(); + } +}); +``` + +或者,也可以这样做异步调用 +```java +CompletableFuture future = RpcContext.getServiceContext().asyncCall( + () -> { + asyncService.sayHello("oneway call request1"); + } +); + +future.get(); +``` + +**异步总是不等待返回**,你也可以设置是否等待消息发出 +- `sent="true"` 等待消息发出,消息发送失败将抛出异常。 +- `sent="false"` 不等待消息发出,将消息放入 IO 队列,即刻返回。 + +```java +@DubboReference(methods = {@Method(name = "sayHello", timeout = 5000, sent = true)}) +private AsyncService asyncService; +``` + +如果你只是想异步,完全忽略返回值,可以配置 `return="false"`,以减少 Future 对象的创建和管理成本 +```java +@DubboReference(methods = {@Method(name = "sayHello", timeout = 5000, return = false)}) +private AsyncService asyncService; +``` + + diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/framework/attachment.md b/content/zh-cn/overview/mannual/java-sdk/tasks/framework/attachment.md new file mode 100644 index 000000000000..56e11f64a8c0 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/framework/attachment.md @@ -0,0 +1,133 @@ +--- +aliases: + - /zh/docs3-v2/java-sdk/advanced-features-and-usage/service/attachment/ + - /zh/overview/tasks/develop/context/ + - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/service/attachment/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/context/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/attachment/ +description: 通过 Dubbo 中的 Attachment 在服务消费方和提供方之间隐式传递参数 +linkTitle: 传递附加参数 +title: 调用链路传递隐式参数 +type: docs +weight: 5 +--- + +在不修改方法签名与参数定义的情况下,可以通过 `RpcContext` 上的 `setAttachment` 和 `getAttachment` 在服务消费方和提供方之间进行参数的隐式传递。隐式参数传递支持以下两个方向: +* 从消费方到提供方,也就是在请求发起时,在方法参数之外通过 attachment 传递附加参数。 +* 从提供方到消费方,也就是在响应结果返回时,在响应结果之外通过 attachment 传递附加参数。 + +**理解隐式参数传递的最直接方式 http header,它的工作方式与 http header 完全一致,在 GET 或 POST 请求体之外可以传递任意多个 header 参数**。在实现原理上,对于不同的协议,attachment 的实现方式略有不同: +* 对于 triple 协议,attachment 会转换为标准的 http header 进行传输。 +* 对于 dubbo 协议,attachment 是编码在协议体的固定位置进行传输,具体请参见 dubbo 协议规范。 + +![/user-guide/images/context.png](/imgs/user/context.png) + +{{% alert title="注意" color="primary" %}} +* 在使用 triple 协议时,由于 http header 的限制,仅支持小写的 ascii 字符 +* path, group, version, dubbo, token, timeout 一些 key 是保留字段,传递 attachment 时应避免使用,尽量通过业务前缀等确保 key 的唯一性。 +{{% /alert %}} + +## 消费端隐式参数 +本文示例完整源码可在以下链接查看 [dubbo-samples-attachment](https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-attachment) + +### 设置隐式参数 + +```java +RpcContext.getClientAttachment().setAttachment("index", "1"); // 隐式传参,后面的远程调用都会隐式将这些参数发送到服务器端,类似cookie,比如用于框架集成 +xxxService.xxx(); // 远程调用 +// ... +``` + +### 读取隐式参数 + +```java +public class XxxServiceImpl implements XxxService { + + public void xxx() { + // 获取客户端隐式传入的参数,比如用于框架集成 + String index = RpcContext.getServerAttachment().getAttachment("index"); + } +} +``` + +## 提供端隐式参数 + +### 设置隐式参数 + +```java +public class XxxServiceImpl implements XxxService { + + public void xxx() { + String index = xxx; + RpcContext.getServerContext().setAttachment("result", index); + } +} +``` + +### 读取隐式参数 + +```java +xxxService.xxx(); // 远程调用 +String result = RpcContext.getServerContext().getAttachment("result"); +// ... +``` + +{{% alert title="参数透传问题" color="warning" %}} +请注意!`setAttachment` 设置的 KV 对,在完成下面一次远程调用会被清空,即多次远程调用要多次设置!这一点与 Dubbo2 中的行为是不一致的! + +比如,对于 Dubbo2 而言,在 A 端设置的参数,调用 B 以后,如果 B 继续调用了 C,原来在 A 中设置的参数也会被带到 C 端过去(造成参数污染的问题)。对于 Dubbo3,B 调用 C 时的上下文是干净的,不会包含最开始在 A 中设置的参数。 + +Dubbo3 提供的了支持参数透传的能力。通过实现以下 SPI 用户可以自行指定需要透传的参数,`select` 的结果(可以从 RpcClientAttachment 获取当前所有参数)将作为需要透传的键值对传递到下一跳,如果返回 null 则表示不透传参数。 + +```java +@SPI +public interface PenetrateAttachmentSelector { + + /** + * Select some attachments to pass to next hop. + * These attachments can fetch from {@link RpcContext#getServerAttachment()} or user defined. + * + * @return attachment pass to next hop + */ + Map select(); + +} +``` +{{% /alert %}} + +{{% alert title="关于老版本 API" color="warning" %}} +老版本 Dubbo2 用户已经熟悉了使用 RpcContext 设置 attachment 隐式参数: + +```java +RpcContext.getContext().setAttachment("index", "1"); +String index = RpcContext.getContext().getAttachment("index"); +``` + +以上 RpcContext API 在 Dubbo3 中仍能正常工作。Dubbo3 之所以引入以上新版本 API 是为了支持提供端隐式参数、解决参数透传等问题,如果用户只是简单的使用消费端隐式参数,没有其他他书需求则可以继续使用老版本 RpcContext API。 + +{{% /alert %}} + +## 内部实现原理 + +上下文信息是 RPC 框架很重要的一个功能,使用 RpcContext 可以为单次调用指定不同配置。如分布式链路追踪场景,其实现原理就是在全链路的上下文中维护一个 traceId,Consumer 和 Provider 通过传递 traceId 来连接一次RPC调用,分别上报日志后可以在追踪系统中串联并展示完整的调用流程。这样可以更方便地发现异常、定位问题。 + +Dubbo 中的 RpcContext 是一个 ThreadLocal 的临时状态记录器,当接收到 RPC 请求,或发起 RPC 请求时,RpcContext 的状态都会变化。比如:**A 调 B,B 调 C,则 B 机器上,在 B 调 C 之前,RpcContext 记录的是 A 和 B 的信息,在 B 调 C 之后,RpcContext 记录的是 B 和 C 的信息。** + +因此,RpcContext 被拆分为四大模块(ServerContext、ClientAttachment、ServerAttachment 和 ServiceContext)。 + +它们分别承担了不同的职责: +- ServiceContext:在 Dubbo 内部使用,用于传递调用链路上的参数信息,如 invoker 对象等 +- ClientAttachment:在 Client 端使用,往 ClientAttachment 中写入的参数将被传递到 Server 端 +- ServerAttachment:在 Server 端使用,从 ServerAttachment 中读取的参数是从 Client 中传递过来的 +- ServerContext:在 Client 端和 Server 端使用,用于从 Server 端回传 Client 端使用,Server 端写入到 ServerContext 的参数在调用结束后可以在 Client 端的 ServerContext 获取到 + +![/imgs/v3/concepts/rpccontext.png](/imgs/v3/concepts/rpccontext.png) + +如上图所示,消费端发起调用的时候可以直接通过 Method Invoke 向远程的服务发起调用,同时消费端往 RpcClientAttachment 写入的数据会连同 Invoke 的参数信息写入到 Invocation 中。 +消费端的 Invocation 经过序列化后通过网络传输发送给服务端,服务端解析 Invocation 生成 Method Invoke 的参数和 RpcServerAttachment,然后发起真实调用。 +在服务端处理结束之后,Method Response 结果会连同 RpcServiceContext 一起生成 Result 对象。 +服务端的 Result 结果对象经过序列化后通过网络传输发送回消费端,消费端解析 Result 生成 Method Response 结果和 RpcServiceContext,返回真实调用结果和上下文给消费端。 + +1、Dubbo系统间调用时,想传递一些通用参数,可通过Dubbo提供的扩展如Filter等实现统一的参数传递 + +2、Dubbo系统间调用时,想传递接口定义之外的参数,可在调用接口前使用setAttachment传递参数。 diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/framework/fault-tolerent-strategy.md b/content/zh-cn/overview/mannual/java-sdk/tasks/framework/fault-tolerent-strategy.md new file mode 100644 index 000000000000..52b96762d6c4 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/framework/fault-tolerent-strategy.md @@ -0,0 +1,107 @@ +--- +aliases: + - /zh/docsv2.7/user/examples/fault-tolerent-strategy/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/fault-tolerent-strategy/ +description: 集群调用失败时,Dubbo 提供的容错方案 +linkTitle: 集群容错(重试) +title: 集群容错 +type: docs +weight: 8 +--- + +## 背景 +在集群调用失败时,Dubbo 提供了多种容错方案,缺省为 failover 重试。 + +![cluster](/imgs/user/cluster.jpg) + +各节点关系: + +* 这里的 `Invoker` 是 `Provider` 的一个可调用 `Service` 的抽象,`Invoker` 封装了 `Provider` 地址及 `Service` 接口信息 +* `Directory` 代表多个 `Invoker`,可以把它看成 `List` ,但与 `List` 不同的是,它的值可能是动态变化的,比如注册中心推送变更 +* `Cluster` 将 `Directory` 中的多个 `Invoker` 伪装成一个 `Invoker`,对上层透明,伪装过程包含了容错逻辑,调用失败后,重试另一个 +* `Router` 负责从多个 `Invoker` 中按路由规则选出子集,比如读写分离,应用隔离等 +* `LoadBalance` 负责从多个 `Invoker` 中选出具体的一个用于本次调用,选的过程包含了负载均衡算法,调用失败后,需要重选 + +## 集群容错模式 + +可以自行扩展集群容错策略,参见:[集群扩展](../../../dev/impls/cluster) + +### Failover Cluster + +失败自动切换,当出现失败,重试其它服务器。通常用于读操作,但重试会带来更长延迟。可通过 `retries="2"` 来设置重试次数(不含第一次)。 + +重试次数配置如下: + +```xml + +``` + +或 + +```xml + +``` + +或 + +```xml + + + +``` + +{{% alert title="提示" color="primary" %}} +该配置为缺省配置 +{{% /alert %}} + +### Failfast Cluster + +快速失败,只发起一次调用,失败立即报错。通常用于非幂等性的写操作,比如新增记录。 + +### Failsafe Cluster + +失败安全,出现异常时,直接忽略。通常用于写入审计日志等操作。 + +### Failback Cluster + +失败自动恢复,后台记录失败请求,定时重发。通常用于消息通知操作。 + +### Forking Cluster + +并行调用多个服务器,只要一个成功即返回。通常用于实时性要求较高的读操作,但需要浪费更多服务资源。可通过 `forks="2"` 来设置最大并行数。 + +### Broadcast Cluster + +广播调用所有提供者,逐个调用,任意一台报错则报错。通常用于通知所有提供者更新缓存或日志等本地资源信息。 + +现在广播调用中,可以通过 broadcast.fail.percent 配置节点调用失败的比例,当达到这个比例后,BroadcastClusterInvoker +将不再调用其他节点,直接抛出异常。 broadcast.fail.percent 取值在 0~100 范围内。默认情况下当全部调用失败后,才会抛出异常。 +broadcast.fail.percent 只是控制的当失败后是否继续调用其他节点,并不改变结果(任意一台报错则报错)。broadcast.fail.percent 参数 +在 dubbo2.7.10 及以上版本生效。 + +Broadcast Cluster 配置 broadcast.fail.percent。 + +broadcast.fail.percent=20 代表了当 20% 的节点调用失败就抛出异常,不再调用其他节点。 + +```text +@reference(cluster = "broadcast", parameters = {"broadcast.fail.percent", "20"}) +``` + + +{{% alert title="提示" color="primary" %}} +`2.1.0` 开始支持 +{{% /alert %}} + +### 集群模式配置 + +按照以下示例在服务提供方和消费方配置集群模式 + +```xml + +``` + +或 + +```xml + +``` diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/framework/filter.md b/content/zh-cn/overview/mannual/java-sdk/tasks/framework/filter.md new file mode 100644 index 000000000000..9578e81a9e75 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/framework/filter.md @@ -0,0 +1,136 @@ +--- +aliases: + - /zh/overview/tasks/develop/async/ + - /zh/docs3-v2/java-sdk/advanced-features-and-usage/service/async-call/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/async-call/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/async-execute-on-provider/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/async/ +description: 使用 Filter 过滤器动态拦截请求(request)或响应(response)以转换或使用请求或响应中包含的信息。 +linkTitle: Filter拦截器 +title: 使用 Filter 过滤器动态拦截请求(request)或响应(response) +type: docs +weight: 3 +--- + +Filter 过滤器动态拦截请求(request)或响应(response)以转换或使用请求或响应中包含的信息。过滤器本身通常不会创建响应,而是提供可以“附加”到任何一次 RPC 请求的通用函数。Dubbo Filter 是可插拔的,我们可以在一次 RPC 请求中插入任意类型的、任意多个 Filter。 + +Filter 工作原理如下图所示: + + + +可以通过 Filter 实现的一些典型能力如下: +* 记录请求参数、响应结果等到日志文件 +* 为 RPC 请求添加认证或校验逻辑 +* 在发送或执行请求之前,格式化请求体或 header 参数 +* 压缩响应结果 +* 对请求数据进行埋点,统计调用耗时、成功、失败次数等 +* 监测并发执行的请求数量,实现限流降级能力 + +## 使用方式 +如上图所示,Dubbo 代理会自动加载 Filter 实现并将它们组装到调用链路。Filter 是一个标准的 SPI 定义,框架按照一定的激活规则自动加载 Filter 实现。 + +```java +@SPI(scope = ExtensionScope.MODULE) +public interface Filter extends BaseFilter {} +``` + +Filter 的默认激活状态可在定义中通过 `@Activate` 注解设置,如以下定义表示该 Filter 在提供者端执行 RPC 请求时自动开启(在消费端不开启)。`@Activate` 支持多种条件控制,包括 classpath 下有某个类的定义时开启,URL 中有哪个参数值时开启等,具体可参见 [SPI 扩展 Activate 介绍]()。 + +```java +@Activate(group = PROVIDER) +public class AccessLogFilter implements Filter {} +``` + +### 关闭自动加载 +如想关闭某个 filter 加载,在不修改 Filter 定义的情况下,可通过以下几种配置关闭。 + +全局关闭 filter,所有 rpc 调用均不启用 filter +```yaml +dubbo: + consumer: + filter: "-accesslog,-tps" +``` + +某个服务调用过程不执行 filter +```java +@DubboReference(filter="-accesslog,-tps") +private DemoService demoService; +``` + +### 开启自动加载 +如想开启某个 filter 加载,在不修改 Filter 定义的情况下,可通过以下几种配置开启。 + +全局开启 filter,所有 rpc 调用均启用 filter +```yaml +dubbo: + consumer: + filter: "accesslog,tps" +``` + +某个服务调用过程执行该 filter +```java +@DubboReference(filter="accesslog,tps") +private DemoService demoService; +``` + +## 内置实现 +以下是 Dubbo 框架中内置的一些 Filter 实现,作为某些功能的底层实现原理,大部分情况下用户不需要关心这些 Filter 实现。这里列出来作为参考,方便用户了解如何开启某个特定功能,以及他们背后的工作原理: + + + +## 具体定义 +以下是关于 Filter 过滤器具体定义与实现的一些细节,对于扩展 Filter 的用户可作为参考。 + +### Filter定义 +Dubbo Filter 的定义如下: +```java +public interface BaseFilter { + /** + * Always call invoker.invoke() in the implementation to hand over the request to the next filter node. + */ + Result invoke(Invoker invoker, Invocation invocation) throws RpcException; + + /** + * This callback listener applies to both synchronous and asynchronous calls, please put logics that need to be executed + * on return of rpc result in onResponse or onError respectively based on it is normal return or exception return. + *

+ * There's something that needs to pay attention on legacy synchronous style filer refactor, the thing is, try to move logics + * previously defined in the 'finally block' to both onResponse and onError. + */ + interface Listener { + + /** + * This method will only be called on successful remote rpc execution, that means, the service in on remote received + * the request and the result (normal or exceptional) returned successfully. + */ + void onResponse(Result appResponse, Invoker invoker, Invocation invocation); + + /** + * This method will be called on detection of framework exceptions, for example, TimeoutException, NetworkException + * Exception raised in Filters, etc. + */ + void onError(Throwable t, Invoker invoker, Invocation invocation); + } +} +``` + +基于以上 BaseFilter 定义,Dubbo 定义了两个 SPI 接口:ClusterFilter 与 Filter。这两个 SPI 实现能实现的效果基本是一致的,之所以定义两个主要是出于性能优化考虑,建议用户关注 Filter SPI 即可,仅在有严苛性能需求的情况下(如集群 provider 提供者实例数量庞大)才关注 ClusterFilter。 + + + +```java +@SPI(scope = ExtensionScope.MODULE) +public interface Filter extends BaseFilter {} +``` + +```java +@SPI(scope = ExtensionScope.MODULE) +public interface ClusterFilter extends BaseFilter {} +``` + +### 扩展Filter + +可参考 [使用教程 - 自定义扩展]() 学习具体示例。 + + + diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/framework/generic.md b/content/zh-cn/overview/mannual/java-sdk/tasks/framework/generic.md new file mode 100644 index 000000000000..125f609039fe --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/framework/generic.md @@ -0,0 +1,149 @@ +--- +aliases: + - /zh/overview/tasks/develop/generic/ + - /zh/docs3-v2/java-sdk/advanced-features-and-usage/service/generic-reference/ + - /zh/docs3-v2/java-sdk/advanced-features-and-usage/service/generic-service/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/generic/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/generic-service/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/generic-reference/ + - /zh-cn/overview/mannual/java-sdk/tasks/framework/more/generic/ +description: 泛化调用,用于在调用方没有服务方提供的 API(SDK)的情况下,对服务方进行调用 +linkTitle: 泛化调用 +title: 泛化调用 +type: docs +weight: 9 +--- + + {{% alert title="注意" color="warning" %}} + 泛化调用适用于老版本 dubbo 通信协议,如果您使用的是 3.3 及之后版本的 triple 协议,请直接使用 triple 自带的 http application/json 能力直接发起服务调用,相关示例可参考 [网关接入说明](/zh-cn/overview/mannual/java-sdk/tasks/gateway/triple/)。 + {{% /alert %}} + +泛化调用(客户端泛化调用)是指在调用方没有服务提供方 API(SDK)的情况下,对服务方进行调用,并且可以正常拿到调用结果。调用方没有接口及模型类元,知道服务的接口的全限定类名和方法名的情况下,可以通过泛化调用调用对应接口。 + +## 使用场景 + +泛化调用可通过一个通用的 GenericService 接口对所有服务发起请求。典型使用场景如下: + +1. 网关服务:如果要搭建一个网关服务,那么服务网关要作为所有 RPC 服务的调用端。但是网关本身不应该依赖于服务提供方的接口 API(这样会导致每有一个新的服务发布,就需要修改网关的代码以及重新部署),所以需要泛化调用的支持。 + +2. 测试平台:如果要搭建一个可以测试 RPC 调用的平台,用户输入分组名、接口、方法名等信息,就可以测试对应的 RPC 服务。那么由于同样的原因(即会导致每有一个新的服务发布,就需要修改网关的代码以及重新部署),所以平台本身不应该依赖于服务提供方的接口 API。所以需要泛化调用的支持。 + +## 使用方式 + +本示例的完整源码请参考 [dubbo-samples-generic-call](https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-generic/dubbo-samples-generic-call/)。 + +示例中有以下 Dubbo 服务定义和实现 + +服务接口定义: + +```java +public interface HelloService { + String sayHello(String name); + CompletableFuture sayHelloAsync(String name); + CompletableFuture sayHelloAsyncComplex(String name); + CompletableFuture> sayHelloAsyncGenericComplex(String name); +} +``` + +服务具体实现并发布: + +```java +@DubboService +public class HelloServiceImpl implements HelloService { + + @Override + public String sayHello(String name) { + return "sayHello: " + name; + } + + @Override + public CompletableFuture sayHelloAsync(String name) { + // ... + } + + @Override + public CompletableFuture sayHelloAsyncComplex(String name) { + // ... + } + + @Override + public CompletableFuture> sayHelloAsyncGenericComplex(String name) { + // ... + } +} +``` + +### API 调用方式 + +针对以上 Dubbo 服务,我们可以通过泛化调用 API 直接发起调用。 + +```java +private GenericService genericService; + +public static void main(String[] args) throws Exception { + ApplicationConfig applicationConfig = new ApplicationConfig(); + applicationConfig.setName("generic-call-consumer"); + RegistryConfig registryConfig = new RegistryConfig(); + registryConfig.setAddress("zookeeper://127.0.0.1:2181"); + + ReferenceConfig referenceConfig = new ReferenceConfig<>(); + referenceConfig.setInterface("org.apache.dubbo.samples.generic.call.api.HelloService"); + applicationConfig.setRegistry(registryConfig); + referenceConfig.setApplication(applicationConfig); + referenceConfig.setGeneric("true"); + // do not wait for result, 'false' by default + referenceConfig.setAsync(true); + referenceConfig.setTimeout(7000); + + genericService = referenceConfig.get(); +} + +public static void invokeSayHello() throws InterruptedException { + Object result = genericService.$invoke("sayHello", new String[]{"java.lang.String"}, new Object[]{"world"}); + CountDownLatch latch = new CountDownLatch(1); + + CompletableFuture future = RpcContext.getContext().getCompletableFuture(); + future.whenComplete((value, t) -> { + System.err.println("invokeSayHello(whenComplete): " + value); + latch.countDown(); + }); + + System.err.println("invokeSayHello(return): " + result); + latch.await(); +} +``` + +1. 在设置 `ReferenceConfig` 时,使用 `setGeneric("true")` 来开启泛化调用 +2. 配置完 `ReferenceConfig` 后,使用 `referenceConfig.get()` 获取到 `GenericService` 类的实例 +3. 使用其 `$invoke` 方法获取结果 +4. 其他设置与正常服务调用配置一致即可 + +### Spring 调用方式 +Spring 中服务暴露与服务发现有多种使用方式,如 xml,注解。这里以 xml 为例。 + +1. 生产者端无需改动 + +2. 消费者端原有的 `dubbo:reference` 标签加上 `generic=true` 的属性。 + +``` xml + +``` + +3. 获取到 Bean 容器,通过 Bean 容器拿到 `GenericService` 实例。 + +4. 调用 `$invoke` 方法获取结果 + +``` java + + private static GenericService genericService; + + public static void main(String[] args) throws Exception { + ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring/generic-impl-consumer.xml"); + context.start(); + //服务对应bean的名字由xml标签的id决定 + genericService = context.getBean("helloService"); + //获得结果 + Object result = genericService.$invoke("sayHello", new String[]{"java.lang.String"}, new Object[]{"world"}); + } +``` + diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/framework/lightweight-rpc.md b/content/zh-cn/overview/mannual/java-sdk/tasks/framework/lightweight-rpc.md new file mode 100644 index 000000000000..56956e7b0809 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/framework/lightweight-rpc.md @@ -0,0 +1,109 @@ +--- +description: 使用轻量的 Java SDK 开发 RPC Server 和 Client +linkTitle: Server与Client +title: 使用轻量的 Java SDK 开发 RPC Server 和 Client +type: docs +weight: 1 +--- +本示例演示如何使用轻量 Dubbo SDK 开发 RPC Server 与 Client,示例使用 Java Interface 方式定义、发布和访问 RPC 服务,底层使用 Triple 协议通信。本示例完整代码请参见 dubbo-samples。 + +基于 Dubbo 定义的 Triple 协议,你可以轻松编写浏览器、gRPC 兼容的 RPC 服务,并让这些服务同时运行在 HTTP/1 和 HTTP/2 上。Dubbo Java SDK 支持使用 IDL 或编程语言特有的方式定义服务,并提供一套轻量的 API 来发布或调用这些服务。 + +## Maven 依赖 + +在基于 Dubbo RPC 编码之前,您只需要在项目添加一个非常轻量的 `dubbo`依赖包即可,以 Maven 为例: +```xml + + org.apache.dubbo + dubbo + 3.3.0 + + + + +``` + +## 定义服务 + +定义一个名为 `DemoService`的标准 Java 接口作为 Dubbo 服务(Dubbo 还支持[基于 IDL 的服务定义模式](/zh-cn/overview/mannual/java-sdk/quick-start/))。 + +```java +public interface DemoService { + String sayHello(String name); +} +``` + +实现 `DemoService` 接口并编写业务逻辑代码。 + +```java +public class DemoServiceImpl implements DemoService { + @Override + public String sayHello(String name) { + return "Hello " + name + ", response from provider."; + } +} +``` + +## 注册服务并启动 Server + +启动 server 并在指定端口监听 RPC 请求,在此之前,我们向 server 注册了以下信息: + +- 使用 `Triple` 作为通信 RPC 协议与并监听端口 `50051` +- 注册 Dubbo 服务到 `DemoService` server + +```java +public class Application { + public static void main(String[] args) { + DubboBootstrap.getInstance() + .protocol(new ProtocolConfig(CommonConstants.TRIPLE, 50051)) + .service(ServiceBuilder.newBuilder().ref(new DemoServiceImpl()).build()) + .start() + .await(); + } +} +``` + +## 访问服务 + +最简单方式是使用 HTTP/1.1 POST 请求访问服务,参数则以标准 JSON 格式作为 HTTP 负载传递。如下是使用 cURL 命令的访问示例: + +```shell +curl \ + --header "Content-Type: application/json" \ + --data '["Dubbo"]' \ + http://localhost:50051/org.apache.dubbo.demo.DemoService/sayHello +``` + +> 参数必须以数组格式进行传递,如果有多个参数,则格式类似 `["param1", {"param2-field": "param2-value"}, ...]`,具体请参见 triple 协议规范。 + +接下来,您也可以使用标准的 Dubbo client 请求服务,指定 server 地址即可发起 RPC 调用,其格式为 `protocol://ip:host` + +```java +public class Application { + public static void main(String[] args) { + DemoService demoService = + ReferenceBuilder.newBuilder() + .interfaceClass(DemoService.class) + .url("tri://localhost:50051") + .build() + .get(); + + String message = demoService.sayHello("dubbo"); + System.out.println(message); + } +} +``` + +恭喜您, 以上即是 Dubbo Java RPC 通信的基本使用方式! 🎉 + +## 更多内容 + +- Triple 协议完全兼容 gRPC,您可以参考这里了解如何 [使用 IDL 编写 gRPC 兼容的服务](/zh-cn/overview/mannual/java-sdk/quick-start/),或者 [使用其他通信协议]() +- 作为 RPC 框架,Dubbo 支持异步调用、连接管理、context上下文等,请参考 [RPC 框架核心功能]() +- 您可以继续 [使用 API 为应用添加更多微服务治理能力](),但我们更推进您使用 [Dubbo Spring Boot 开发微服务应用](../../microservice/develop/) diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/framework/more/_index.md b/content/zh-cn/overview/mannual/java-sdk/tasks/framework/more/_index.md new file mode 100755 index 000000000000..79d44c4720f4 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/framework/more/_index.md @@ -0,0 +1,9 @@ +--- +description: "Dubbo 是一款轻量的 RPC 框架,提供 Java、Go、Node.js、Javascript 等语言支持,帮助开发者构建浏览器、gRPC 兼容的 HTTP API。" +linkTitle: 更多特性 +title: Dubbo 作为轻量 RPC 框架解决组件通信问题 +type: docs +weight: 100 +--- + +{{% docs/section_list %}} \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/callback-parameter.md b/content/zh-cn/overview/mannual/java-sdk/tasks/framework/more/callback-parameter.md similarity index 97% rename from content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/callback-parameter.md rename to content/zh-cn/overview/mannual/java-sdk/tasks/framework/more/callback-parameter.md index 628b72566639..2c6ff26c124e 100644 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/callback-parameter.md +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/framework/more/callback-parameter.md @@ -2,6 +2,7 @@ aliases: - /zh/docs3-v2/java-sdk/advanced-features-and-usage/service/callback-parameter/ - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/service/callback-parameter/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/callback-parameter/ description: 通过参数回调从服务器端调用客户端逻辑 linkTitle: 服务端对客户端进行回调 title: 服务端对客户端进行回调 @@ -123,4 +124,4 @@ callbackService.addListener("foo.bar", new CallbackListener(){ System.out.println("callback1:" + msg); } }); -``` \ No newline at end of file +``` diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/framework/more/concurrency-control.md b/content/zh-cn/overview/mannual/java-sdk/tasks/framework/more/concurrency-control.md new file mode 100644 index 000000000000..8c4d1764acff --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/framework/more/concurrency-control.md @@ -0,0 +1,92 @@ +--- +aliases: + - /zh/docs3-v2/java-sdk/advanced-features-and-usage/performance/concurrency-control/ + - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/performance/concurrency-control/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/concurrency-control/ +description: Dubbo 中的并发控制 +linkTitle: 并发控制 +title: 并发控制 +type: docs +weight: 28 +--- + + +## 功能说明 +多种并发控制功能,帮助用户管理其应用程序和服务。 + +## 使用场景 +限制从同一客户端到同一服务的并发请求数,防止恶意请求使服务器过载,确保服务的稳定性,并防止使用过多资源。 + +控制某些服务的最大并发请求数,确保其他服务的资源可用性。系统过载和确保系统稳定性。 + +允许在需求增加时更平滑地扩展服务。 + +确保服务在高峰使用时间保持可靠和稳定。 + +这种方式要求用户准确的预先评估系统能处理的并发数,而准确的评估系统处理能力并不是一件容易的事情,因此 Dubbo 还提供了自适应限流模式,根据系统负载自动识别系统健康程度并进行限流保护,可以在此 [查看使用文档](../adaptive-concurrency-control)。 + +## 使用方式 +### 样例一 + +> 限制 `com.foo.BarService` 的每个方法,服务器端并发执行(或占用线程池线程数)不能超过 10 个 + +```xml + +``` + +### 样例二 + +> 限制 `com.foo.BarService` 的 `sayHello` 方法,服务器端并发执行(或占用线程池线程数)不能超过 10 个 + +```xml + + + +``` +### 样例三 + +> 限制 `com.foo.BarService` 的每个方法,每客户端并发执行(或占用连接的请求数)不能超过 10 个 + +```xml + +``` + +**或** + +```xml + +``` + +### 样例四 + +> 限制 `com.foo.BarService` 的 `sayHello` 方法,每客户端并发执行(或占用连接的请求数)不能超过 10 个 + +```xml + + + +``` + +或 + +```xml + + + +``` + +> 如果 `` 和 `` 都配了actives,`` 优先,参见:[配置的覆盖策略](/zh-cn/overview/mannual/java-sdk/reference-manual/config/principle/)。 + +### Load Balance 均衡 + +配置服务的客户端的 `loadbalance` 属性为 `leastactive`,此 Loadbalance 会调用并发数最小的 Provider(Consumer端并发数)。 + +```xml + +``` + +**或** + +```xml + +``` diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/framework/more/config-connections.md b/content/zh-cn/overview/mannual/java-sdk/tasks/framework/more/config-connections.md new file mode 100644 index 000000000000..d7d0fa5d650e --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/framework/more/config-connections.md @@ -0,0 +1,104 @@ +--- +aliases: + - /zh/docs3-v2/java-sdk/advanced-features-and-usage/performance/config-connections/ + - /zh/docs3-v2/java-sdk/advanced-features-and-usage/performance/stickiness/ + - /zh/docs3-v2/java-sdk/advanced-features-and-usage/performance/lazy-connect/ + - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/performance/config-connections/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/stickiness/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/lazy-connect/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/config-connections/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/config-connections/ +description: Dubbo 中服务端和客户端的连接控制 +linkTitle: 连接控制 +title: 连接控制 +type: docs +weight: 29 +--- + + + + + +## 功能说明 +连接控制功能可以使用户能够控制和管理进出服务器连接数,限制连接数并设置超时,以确保 Dubbo 系统的稳定性和性能,还允许用户根据 IP 地址、端口和协议配置不同级别的访问控制,保护系统免受恶意流量的影响,并降低服务中断的风险,此外提供了一种监视当前流量和连接状态的方法。 + +## 使用场景 +1. 服务器过载时减少连接数:当服务器过载时,使用 Dubbo 通过设置最大连接限制来减少连接数减少服务器上的负载并防止其崩溃。 +2. 减少服务器受到攻击时的连接数:Dubbo 可以限制服务器受到攻击的连接数防止恶意连接充斥服务器并导致服务器崩溃。 +3. 限制特定服务的连接数:Dubbo 可以限制特定服务连接数防止服务过载过多的请求并确保及时响应所有请求。 +4. 限制来自单个IP地址的连接数:Dubbo 可以限制来自单个地址的连接数降低来自单个IP地址的恶意活动的风险。 + +## 使用方式 +### 服务端连接控制 + +限制服务器端接受的连接不能超过 10 个 [^1]: + +```xml + +``` + +或 + +```xml + +``` + +### 客户端连接控制 + +限制客户端服务使用连接不能超过 10 个 [^2]: + +```xml + +``` + +或 + +```xml + +``` + +如果 `` 和 `` 都配了 connections,`` 优先,参见:[配置的覆盖策略](/zh-cn/overview/mannual/java-sdk/reference-manual/config/principle/) + +[^1]: 因为连接在 Server上,所以配置在 Provider 上 +[^2]: 如果是长连接,比如 Dubbo 协议,connections 表示该服务对每个提供者建立的长连接数 + + + + +## 功能说明 +允许消费者在提供者接收请求之前向提供者发送请求,消费者等待提供者准备就绪,然后将发送消费者者的请求,当消费者需要连接到提供者,提供者尚未准备好接受请求时,确保在正确的时间发送请求,防止消费者被速度慢或不可用的提供程序阻止。 + +## 使用场景 +粘滞连接用于有状态服务,尽可能让客户端总是向同一提供者发起调用,除非该提供者挂了,再连另一台。 + +粘滞连接将自动开启 [延迟连接](../lazy-connect),以减少长连接数。 + +## 使用方式 +```xml + +``` + +Dubbo 支持方法级别的粘滞连接,如果你想进行更细粒度的控制,还可以这样配置。 + +```xml + + + +``` + + + + + +## 功能说明 +当消费者请求服务时,实际使用服务时才建立真正的连接,避免不必要的连接来减少延迟并提高系统稳定性。 + +## 使用场景 +延迟连接用于减少长连接数。当有调用发起时,再创建长连接。 + +## 使用方式 +```xml + +``` + +> 该配置只对使用长连接的 dubbo 协议生效。 diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/framework/more/echo-service.md b/content/zh-cn/overview/mannual/java-sdk/tasks/framework/more/echo-service.md new file mode 100644 index 000000000000..9e727ce84040 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/framework/more/echo-service.md @@ -0,0 +1,41 @@ +--- +aliases: + - /zh/docs3-v2/java-sdk/advanced-features-and-usage/service/echo-service/ + - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/service/echo-service/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/echo-service/ +description: 通过回声测试检测 Dubbo 服务是否可用 +linkTitle: 回声测试 +title: 回声测试 +type: docs +weight: 3 +--- + + + +## 特性说明 +回声测试用于检测服务是否可用,回声测试按照正常请求流程执行,能够测试整个调用是否通畅,可用于监控。执行回声测试,客户端发送一个包含特定值(如字符串)的请求。服务器应使用相同的值进行响应,从而验证请求是否已成功接收和处理。如果响应与请求不匹配,则表示服务运行不正常,应进一步调查。要求 Dubbo 服务器正在运行,并且服务器和客户端之间具有网络连接。在客户端,必须配置 Dubbo 客户端以连接到服务器,客户端将向服务器发送请求,然后服务器应返回与请求相同的响应。 + + +## 使用场景 +测试验证是否可以调用服务以及响应是否正确,对于在尝试在生产环境中使用服务之前验证服务特别有用。 +echo 测试是验证 Dubbo 服务基本功能的一种简单有效的方法,在将服务部署到生产环境之前执行此测试非常重要,以确保服务按预期工作。 + +## 使用方式 + +本示例完整源码请参考 [dubbo-samples-echo](https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-echo)。 + +所有服务自动实现 `EchoService` 接口,只需将任意服务引用强制转型为 `EchoService`,即可使用。 + +如有以下 Dubbo proxy 实例: + +```java +@DubboReference +private DemoService demoService; +``` + +### 代码示例 +```java +EchoService echoService = (EchoService) demoService; + +String status = (String) echoService.$echo("OK"); +``` diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/events-notify.md b/content/zh-cn/overview/mannual/java-sdk/tasks/framework/more/events-notify.md similarity index 94% rename from content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/events-notify.md rename to content/zh-cn/overview/mannual/java-sdk/tasks/framework/more/events-notify.md index 8e0941609086..7cd69d3dc947 100644 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/events-notify.md +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/framework/more/events-notify.md @@ -2,6 +2,7 @@ aliases: - /zh/docs3-v2/java-sdk/advanced-features-and-usage/service/events-notify/ - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/service/events-notify/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/events-notify/ description: 在调用前后出现异常时的事件通知 linkTitle: 调用触发事件通知 title: 调用触发事件通知 @@ -9,10 +10,6 @@ type: docs weight: 8 --- - - - - ## 特性说明 在调用之前、调用之后、出现异常时,会触发 `oninvoke`、`onreturn`、`onthrow` 三个事件,可以配置当事件发生时,通知哪个类的哪个方法。 @@ -22,7 +19,7 @@ weight: 8 调用服务方法前我们可以记录开始时间,调用结束后统计整个调用耗费,发生异常时我们可以告警或打印错误日志或者调用服务前后记录请求日志、响应日志等。 >参考用例 -[https://github.com/apache/dubbo-samples/tree/master/dubbo-samples-notify](https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-notify) +[dubbo-samples-notify](https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-notify) ## 使用方式 @@ -113,4 +110,4 @@ for (int i = 0; i < 10; i++) { } } Assert.assertEquals(requestId, notify.ret.get(requestId).getId()); -``` \ No newline at end of file +``` diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/framework/more/explicit-target.md b/content/zh-cn/overview/mannual/java-sdk/tasks/framework/more/explicit-target.md new file mode 100644 index 000000000000..68441fa858f5 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/framework/more/explicit-target.md @@ -0,0 +1,70 @@ +--- +aliases: + - /zh/docs3-v2/java-sdk/advanced-features-and-usage/service/explicit-target/ + - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/service/explicit-target/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/explicit-target/ +description: Dubbo 中点对点的直连方式 +linkTitle: 直连提供者 +title: 直连提供者 +type: docs +weight: 5 +--- + + +在开发及测试环境下,经常需要绕过注册中心,只测试指定服务提供者,这时候可能需要点对点直连,点对点直连方式,将以服务接口为单位,忽略注册中心的提供者列表,A 接口配置点对点,不影响 B 接口从注册中心获取列表。 + +![/user-guide/images/dubbo-directly.jpg](/imgs/user/dubbo-directly.jpg) + +如果是线上需求需要点对点,可在 `reference` 节点中配置 url 指向提供者,将绕过注册中心,多个地址用分号隔开,配置如下: + +## 注解配置方式 + +```java +@DubboReference(url="tri://localhost:50051") +private XxxService xxxService +``` + +## xml配置方式 + +```xml + +``` + +## 更多配置方式 +{{% alert title="注意" color="warning" %}} +请注意以下配置方式是为了兼容老版本 Dubbo2 而保留,在部分 Dubbo3 版本中可能存在问题,请尽量使用文档前面推荐的配置方式。 +{{% /alert %}} + +### 通过 -D 参数指定 + +在 JVM 启动参数中加入-D参数映射服务地址,如: + +```sh +java -Dcom.alibaba.xxx.XxxService=dubbo://localhost:20890 +``` + +{{% alert title="提示" color="primary" %}} +key 为服务名,value 为服务提供者 url,此配置优先级最高,`1.0.15` 及以上版本支持 +{{% /alert %}} + +### 通过文件映射 + +如果服务比较多,也可以用文件映射,用 `-Ddubbo.resolve.file` 指定映射文件路径,此配置优先级高于 `` 中的配置 [^3],如: + +```sh +java -Ddubbo.resolve.file=xxx.properties +``` + +然后在映射文件 `xxx.properties` 中加入配置,其中 key 为服务名,value 为服务提供者 URL: + +```properties +com.alibaba.xxx.XxxService=dubbo://localhost:20890 +``` + +{{% alert title="提示" color="primary" %}} +`1.0.15` 及以上版本支持,`2.0` 以上版本自动加载 ${user.home}/dubbo-resolve.properties文件,不需要配置 +{{% /alert %}} + +{{% alert title="注意" color="warning" %}} +为了避免复杂化线上环境,不要在线上使用这个功能,只应在测试阶段使用。 +{{% /alert %}} diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/framework/more/generic-impl.md b/content/zh-cn/overview/mannual/java-sdk/tasks/framework/more/generic-impl.md new file mode 100644 index 000000000000..21fa093de477 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/framework/more/generic-impl.md @@ -0,0 +1,78 @@ +--- +aliases: + - /zh/overview/tasks/develop/generic/ + - /zh/docs3-v2/java-sdk/advanced-features-and-usage/service/generic-reference/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/generic/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/generic-reference/ +description: 泛化实现,用于在提供方没有 API(SDK)的情况下,对外提供和发布服务 +linkTitle: 泛化实现 +title: 泛化实现 +type: docs +weight: 1 +--- + +{{% alert title="注意" color="warning" %}} +请注意区分上一篇文档介绍的 [泛化调用](../generic),泛化调用是给消费端用的,而泛化实现是给提供端用的。 +{{% /alert %}} + +泛接口实现方式主要用于服务器端没有 API 接口及模型类元的情况,参数及返回值中的所有 POJO 均用 Map 表示,通常用于框架集成,比如:实现一个通用的远程服务 Mock 框架,可通过实现 GenericService 接口处理所有服务请求。 + +## 使用场景 +* 注册服务: 服务提供者在服务注册表中注册服务,例如 Zookeeper,服务注册表存储有关服务的信息,例如其接口、实现类和地址。 + +* 部署服务: 服务提供商将服务部署在服务器并使其对消费者可用。 + +* 调用服务: 使用者使用服务注册表生成的代理调用服务,代理将请求转发给服务提供商,服务提供商执行服务并将响应发送回消费者。 + +* 监视服务:提供者和使用者可以使用 Dubbo 框架监视服务,允许他们查看服务的执行情况,并在必要时进行调整。 + + +## 使用方式 +本示例的完整源码请参考 [dubbo-samples-generic-impl](https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-generic/dubbo-samples-generic-impl/)。 + +在 Java 代码中实现 `GenericService` 接口 + +```java +package com.foo; +public class MyGenericService implements GenericService { + + public Object $invoke(String methodName, String[] parameterTypes, Object[] args) throws GenericException { + if ("sayHello".equals(methodName)) { + return "Welcome " + args[0]; + } + } +} +``` + +### 通过 Spring 暴露泛化实现 + +在 Spring XML 配置申明服务的实现 + +```xml + + +``` + +### 通过 API 方式暴露泛化实现 + +```java +... +// 用org.apache.dubbo.rpc.service.GenericService可以替代所有接口实现 +GenericService xxxService = new XxxGenericService(); + +// 该实例很重量,里面封装了所有与注册中心及服务提供方连接,请缓存 +ServiceConfig service = new ServiceConfig(); +// 弱类型接口名 +service.setInterface("com.xxx.XxxService"); +// if you need to set different version for service +service.setVersion("1.0.0"); +// 指向一个通用服务实现 +service.setRef(xxxService); + +// 暴露及注册服务 +service.export(); +``` + +1. 在设置 `ServiceConfig` 时,使用`setGeneric("true")`来开启泛化调用 +2. 在设置 `ServiceConfig` 时,使用 setRef 指定实现类时,要设置一个 `GenericService` 的对象。而不是真正的服务实现类对象 +3. 其他设置与正常 Api 服务启动一致即可 diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/local-call.md b/content/zh-cn/overview/mannual/java-sdk/tasks/framework/more/local-call.md similarity index 95% rename from content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/local-call.md rename to content/zh-cn/overview/mannual/java-sdk/tasks/framework/more/local-call.md index 1f496b22d6e3..07e3c9afb6d2 100644 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/local-call.md +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/framework/more/local-call.md @@ -2,6 +2,7 @@ aliases: - /zh/docs3-v2/java-sdk/advanced-features-and-usage/service/local-call/ - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/service/local-call/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/local-call/ description: 在 Dubbo 中进行本地调用 linkTitle: 本地调用 title: 本地调用 @@ -9,11 +10,6 @@ type: docs weight: 22 --- - - - - - ## 特性说明 本地调用使用了 injvm 协议,是一个伪协议,它不开启端口,不发起远程调用,只在 JVM 内直接关联,但执行 Dubbo 的 Filter 链。 diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/framework/more/local-mock.md b/content/zh-cn/overview/mannual/java-sdk/tasks/framework/more/local-mock.md new file mode 100644 index 000000000000..812828e7b0bf --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/framework/more/local-mock.md @@ -0,0 +1,193 @@ +--- +aliases: + - /zh/docs3-v2/java-sdk/advanced-features-and-usage/service/local-mock/ + - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/service/local-mock/ + - /zh/docs3-v2/java-sdk/advanced-features-and-usage/service/service-downgrade/ + - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/service/service-downgrade/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/local-mock/ +description: 了解如何在 Dubbo 中利用本地伪装实现服务降级 +linkTitle: 服务降级 +title: 服务讲解(本地伪装) +type: docs +weight: 10 +--- + +## 特性说明 + +在 Dubbo3 中有一种机制可以实现轻量级的服务降级,也就是本地伪装。 + +Mock 是 Stub 的一个子集,便于服务提供方在客户端执行容错逻辑,因经常需要在出现 RpcException (比如网络失败,超时等)时进行容错,而在出现业务异常(比如登录用户名密码错误)时不需要容错, +如果用 Stub,可能就需要捕获并依赖 RpcException 类,而用 Mock 就可以不依赖 RpcException,因为它的约定就是只有出现 RpcException 时才执行。 + +## 使用场景 + +本地伪装常被用于服务降级。比如某验权服务,当服务提供方全部挂掉后,假如此时服务消费方发起了一次远程调用,那么本次调用将会失败并抛出一个 `RpcException` 异常。为了避免出现这种直接抛出异常的情况出现,那么客户端就可以利用本地伪装来提供 Mock 数据返回授权失败。 + +其他使用场景包括: +- 某服务或接口负荷超出最大承载能力范围,需要进行降级应急处理,避免系统崩溃 +- 调用的某非关键服务或接口暂时不可用时,返回模拟数据或空,业务还能继续可用 +- 降级非核心业务的服务或接口,腾出系统资源,尽量保证核心业务的正常运行 +- 某上游基础服务超时或不可用时,执行能快速响应的降级预案,避免服务整体雪崩 + +## 使用方式 + +完整示例源码请参见 [dubbo-samples-mock](https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-mock) + +### 开启 Mock 配置 + +在 Spring XML 配置文件中按以下方式配置: + +```xml + +``` + +或 + +```xml + +``` + +在工程中提供 Mock 实现 [^2]: +在 interface 旁放一个 Mock 实现,它实现 BarService 接口,并有一个无参构造函数。同时,如果没有在配置文件中显式指定 Mock 类的时候,那么需要保证 Mock 类的全限定类名是 `原全限定类名+Mock` 的形式,例如 `com.foo.BarServiceMock`,否则将会 Mock 失败。 +```java +package com.foo; +public class BarServiceMock implements BarService { + public String sayHello(String name) { + // 你可以伪造容错数据,此方法只在出现RpcException时被执行 + return "容错数据"; + } +} +``` + +### 使用 return 关键字 Mock 返回值 + +使用 `return` 来返回一个字符串表示的对象,作为 Mock 的返回值。合法的字符串可以是: +- *empty*:代表空,返回基本类型的默认值、集合类的空值、自定义实体类的空对象,如果返回值是一个实体类,那么此时返回的将会是一个属性都为默认值的空对象而不是 `null`。 +- *null*:返回 `null` +- *true*:返回 `true` +- *false*:返回 `false` +- *JSON 字符串*:返回反序列化 JSON 串后所得到的对象 + +举个例子,如果服务的消费方经常需要 try-catch 捕获异常,如: + +```java +public class DemoService { + + public Offer findOffer(String offerId) { + Offer offer = null; + try { + offer = offerService.findOffer(offerId); + } catch (RpcException e) { + logger.error(e); + } + + return offer; + } +} +``` + +那么请考虑改为 Mock 实现,并在 Mock 实现中 `return null`。如果只是想简单的忽略异常,在 `2.0.11` 以上版本可用: + +```xml + +``` + +### 使用 throw 关键字 Mock 抛出异常 + +使用 `throw` 来返回一个 Exception 对象,作为 Mock 的返回值。 + +当调用出错时,抛出一个默认的 RPCException: + +```xml + + +``` + +当调用出错时,抛出指定的 Exception: + +自定义异常必须拥有一个入参为 `String` 的构造函数,该构造函数将用于接受异常信息。 +```xml + + +``` + +### 使用 force 和 fail 关键字来配置 Mock 的行为 + +`force:` 代表强制使用 Mock 行为,在这种情况下不会走远程调用。 + +`fail:` 与默认行为一致,只有当远程调用发生错误时才使用 Mock 行为。也就是说,配置的时候其实是可以不使用 `fail` 关键字的,直接使用 `throw` 或者 `return` 就可以了。 + +`force:` 和 `fail:` 都支持与 `throw` 或者 `return` 组合使用。 + +强制返回指定值: + +```xml + + +``` + +强制抛出指定异常: + +```xml + + +``` + +调用失败时返回指定值: +```xml + + + + + +``` + +调用失败时抛出异常 + +```xml + + + + + +``` + +### 在方法级别配置 Mock + +Mock 可以在方法级别上指定,假定 `com.foo.BarService` 上有好几个方法,我们可以单独为 `sayHello()` 方法指定 Mock 行为。 + +具体配置如下所示,在本例中,只要 `sayHello()` 被调用到时,强制返回 "fake": + +```xml + + + + +``` + +### 配合 dubbo-admin 使用 + +* 应用消费端引入 `dubbo-mock-admin`依赖 + +* 应用消费端启动时设置 JVM 参数,`-Denable.dubbo.admin.mock=true` + +* 启动 dubbo-admin,在服务 Mock-> 规则配置菜单下设置 Mock 规则 + +以服务方法的维度设置规则,设置返回模拟数据,动态启用/禁用规则 + + +### 使用专业限流组件 + +如果您有更高级、专业的限流诉求,我们推荐使用专业的限流降级组件如 [Sentinel](https://sentinelguard.io/zh-cn/docs/open-source-framework-integrations.html),以达到最佳体验。参考示例实践:[微服务治理/限流降级](/zh-cn/overview/mannual/java-sdk/tasks/rate-limit/) + +服务降级是指服务在非正常情况下进行降级应急处理。 + + +{{% alert title="注意事项" color="primary" %}} + +Dubbo 启动时会检查配置,当 mock 属性值配置有误时会启动失败,可根据错误提示信息进行排查 + +- 配置格式错误,如 `return+null` 会报错,被当做 mock 类型处理,`return` 后面可省略不写或者跟空格后再跟返回值 +- 类型找不到错误,如自定义 mock 类、throw 自定义异常,请检查类型是否存在或是否有拼写错误 +{{% /alert %}} + diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/local-stub.md b/content/zh-cn/overview/mannual/java-sdk/tasks/framework/more/local-stub.md similarity index 87% rename from content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/local-stub.md rename to content/zh-cn/overview/mannual/java-sdk/tasks/framework/more/local-stub.md index b7122c723a77..ed48ef9e9560 100644 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/local-stub.md +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/framework/more/local-stub.md @@ -2,6 +2,7 @@ aliases: - /zh/docs3-v2/java-sdk/advanced-features-and-usage/service/local-stub/ - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/service/local-stub/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/local-stub/ description: 了解 Dubbo 中本地存根在客户端执行部分逻辑的使用 linkTitle: 本地存根 title: 本地存根 @@ -9,10 +10,6 @@ type: docs weight: 11 --- - - - - ## 特性说明: 远程服务后,客户端通常只剩下接口,而实现全在服务器端,但提供方有些时候想在客户端也执行部分逻辑。 @@ -23,6 +20,9 @@ weight: 11 做 ThreadLocal 缓存,提前验证参数,调用失败后伪造容错数据等等,此时就需要在 API 中带上 Stub,客户端生成 Proxy 实例,会把 Proxy 通过构造函数传给 Stub [^1],然后把 Stub 暴露给用户,Stub 可以决定要不要去调 Proxy。 ## 使用方式 + +完整示例源码请参见 [dubbo-samples-stub](https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-stub) + ### spring 配置文件配置 ```xml @@ -40,7 +40,7 @@ weight: 11 ```java package com.foo; public class BarServiceStub implements BarService { - private final BarService barService; + private final BarSer vice barService; // 构造函数传入真正的远程代理对象 public BarServiceStub(BarService barService){ @@ -60,4 +60,4 @@ public class BarServiceStub implements BarService { ``` [^1]: Stub 必须有可传入 Proxy 的构造函数。 -[^2]: 在 interface 旁边放一个 Stub 实现,它实现 BarService 接口,并有一个传入远程 BarService 实例的构造函数。 \ No newline at end of file +[^2]: 在 interface 旁边放一个 Stub 实现,它实现 BarService 接口,并有一个传入远程 BarService 实例的构造函数。 diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/parameter-validation.md b/content/zh-cn/overview/mannual/java-sdk/tasks/framework/more/parameter-validation.md similarity index 96% rename from content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/parameter-validation.md rename to content/zh-cn/overview/mannual/java-sdk/tasks/framework/more/parameter-validation.md index 120aa988cf7f..13b6fb2f51bf 100644 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/parameter-validation.md +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/framework/more/parameter-validation.md @@ -2,17 +2,14 @@ aliases: - /zh/docs3-v2/java-sdk/advanced-features-and-usage/service/parameter-validation/ - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/service/parameter-validation/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/parameter-validation/ description: 在 Dubbo 中进行参数校验 linkTitle: 参数校验 title: 参数校验 type: docs -weight: 2 +weight: 100 --- - - - - ## 特性说明 参数验证功能是基于 [JSR303](https://jcp.org/en/jsr/detail?id=303) 实现的,用户只需标识 JSR303 标准的验证 annotation,并通过声明 filter 来实现验证。 @@ -168,8 +165,6 @@ public interface ValidationService { > **Dubbo 默认支持 hibernate-validator 版本 <=6.x,若使用 hibernate-validator 7.x 版本,请将 validation 参数声明为 jvalidationNew** -> 如果需要启动客户端验证,并且使用jdk17,则需添加jvm启动参数`--add-opens java.base/java.lang=ALL-UNNAMED`做兼容处理。 - ### 验证异常信息 ```java @@ -202,4 +197,4 @@ public class ValidationConsumer { } ``` -> **验证方式可扩展,扩展方式参见开发者手册中的 [验证扩展](../../../reference-manual/spi/description/validation)** +> **验证方式可扩展,扩展方式参见开发者手册中的 [验证扩展](/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/validation)** diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/reactive.md b/content/zh-cn/overview/mannual/java-sdk/tasks/framework/more/reactive.md similarity index 97% rename from content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/reactive.md rename to content/zh-cn/overview/mannual/java-sdk/tasks/framework/more/reactive.md index 77f9f5b7dc98..edf3d626596c 100644 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/reactive.md +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/framework/more/reactive.md @@ -6,13 +6,12 @@ description: 使用 Reactive API 操作 Triple 流式调用 linkTitle: 响应式编程 title: 响应式编程 type: docs -weight: 1 +weight: 100 --- - - - - +{{% alert title="过时风险提醒" color="warning" %}} +请注意,本文档描述的 Reactive 响应式使用方法可能存在过时的情况,请随时参考 apache/dubbo-samples 中的最新 reactive 示例了解用法。 +{{% /alert %}} ## 特性说明 diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/reference-config-cache.md b/content/zh-cn/overview/mannual/java-sdk/tasks/framework/more/reference-config-cache.md similarity index 95% rename from content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/reference-config-cache.md rename to content/zh-cn/overview/mannual/java-sdk/tasks/framework/more/reference-config-cache.md index df654033c6cc..7ff4e2c057a4 100644 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/reference-config-cache.md +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/framework/more/reference-config-cache.md @@ -2,11 +2,12 @@ aliases: - /zh/docs3-v2/java-sdk/advanced-features-and-usage/performance/reference-config-cache/ - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/performance/reference-config-cache/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/reference-config-cache/ description: 在 Dubbo 中缓存 ReferenceConfig linkTitle: 服务引用配置对象缓存 title: 服务引用配置对象缓存 type: docs -weight: 2 +weight: 50 --- @@ -50,4 +51,4 @@ cache.destroy(reference); ```java KeyGenerator keyGenerator = new ... ReferenceConfigCache cache = ReferenceConfigCache.getCache(keyGenerator); -``` \ No newline at end of file +``` diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/result-cache.md b/content/zh-cn/overview/mannual/java-sdk/tasks/framework/more/result-cache.md similarity index 93% rename from content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/result-cache.md rename to content/zh-cn/overview/mannual/java-sdk/tasks/framework/more/result-cache.md index faac2d8beccd..acda287196cb 100644 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/result-cache.md +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/framework/more/result-cache.md @@ -2,18 +2,14 @@ aliases: - /zh/docs3-v2/java-sdk/advanced-features-and-usage/performance/result-cache/ - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/performance/result-cache/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/result-cache/ description: 通过缓存结果加速访问速度 linkTitle: 调用结果缓存 title: 调用结果缓存 type: docs -weight: 7 +weight: 50 --- - - - - - ## 功能说明 Dubbo支持了服务端结果缓存和客户端结果缓存。 @@ -28,7 +24,7 @@ Dubbo支持了服务端结果缓存和客户端结果缓存。 * `threadlocal` 当前线程缓存,比如一个页面渲染,用到很多 portal,每个 portal 都要去查用户信息,通过线程缓存,可以减少这种多余访问。 * `jcache` 与 [JSR107](http://jcp.org/en/jsr/detail?id=107%27) 集成,可以桥接各种缓存实现。 -缓存类型可扩展 [缓存扩展](../../../reference-manual/spi/description/cache) +缓存类型可扩展 [缓存扩展](/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/cache) 关于 [示例代码](https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-cache) diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/framework/more/router-snapshot.md b/content/zh-cn/overview/mannual/java-sdk/tasks/framework/more/router-snapshot.md new file mode 100644 index 000000000000..c1c823274e9d --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/framework/more/router-snapshot.md @@ -0,0 +1,89 @@ +--- +aliases: + - /zh/docs3-v2/java-sdk/advanced-features-and-usage/performance/router-snapshot/ + - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/performance/router-snapshot/ +description: 路由状态采集 +linkTitle: 路由状态采集 +title: 路由状态采集 +type: docs +weight: 50 +--- + + + + + +## 功能说明 +路由状态收集功能可用于识别可能影响服务性能的任何潜在问题,识别可能阻碍服务尽可能高效使用的任何潜在瓶颈或问题,确保服务平稳运行,用户在尝试访问服务时不会遇到任何问题,允许用户检查路由的状态是启用还是禁用,确保仅使用授权的服务,并且访问仅限于具有适当授权的人员。 + +## 使用场景 + +Dubbo 的很多流量治理能力是基于 Router 进行实现的,在生产环境中,如果出现流量结果不符合预期的情况,可以通过路由状态命令来查看路由的状态,以此来定位可能存在的问题。 + +## 使用方式 + +### 查看路由缓存状态 + +Dubbo 在收到地址变更的时候,会将地址信息推送给所有的 `Router`,这些 `Router` 可以在此阶段提前计算路由的分组,缓存起来,以避免在调用时需要遍历所有的提供者计算分组参数。 +在 Dubbo 3 中引入的 `StateRouter` 提供了通过 qos 命令工具实时获取每个路由的状态的能力。 + +运维人员可以通过 `getRouterSnapshot` 命令获取路由的状态。具体命令使用方式可以参考 [getRouterSnapshot 命令](/zh-cn/overview/mannual/java-sdk/reference-manual/qos/qos-list/) 文档。 + +**注:此功能仅支持 `StateRoute`,且 `StateRouter` 需要基于 `AbstractStateRouter` 实现 `doBuildSnapshot` 接口。** + +### 查看实际请求的路由计算结果 + +Dubbo 3 中默认在路由筛选后为空的时候打印路由计算的节点状态。运维人员可以通过日志判断每个路由的计算结果是否符合预期。 + +#### 日志格式 + +``` +No provider available after route for the service 服务 from registry 注册中心地址 on the consumer 消费端IP using the dubbo version 3.0.7. Router snapshot is below: +[ Parent (Input: 当前节点输入地址数) (Current Node Output: 当前节点计算结果数) (Chain Node Output: 当前节点和后级节点交集结果数) ] Input: 输入的地址示例(显示最多 5 个) -> Chain Node Output: 当前节点输出的地址示例(显示最多 5 个) + [ 路由名称 (Input: 当前节点输入地址数) (Current Node Output: 当前节点计算结果数) (Chain Node Output: 当前节点和后级节点交集结果数) Router message: 路由日志 ] Current Node Output: 当前节点输出的地址示例(显示最多 5 个) + [ 路由名称 (Input: 当前节点输入地址数) (Current Node Output: 当前节点计算结果数) (Chain Node Output: 当前节点和后级节点交集结果数) Router message: 路由日志 ] Current Node Output: 当前输入的地址示例(显示最多 5 个) +``` + +#### 注意: +- 路由日志需要依赖路由实现判断 `needToPrintMessage` 参数,并在需要时写入 `messageHolder` 路由日志 +- 由于多级路由结果是结果取交集的,所以当前节点计算结果数可能和后级取交后为空 + +#### 日志示例 + +``` +[19/07/22 07:42:46:046 CST] main WARN cluster.RouterChain: [DUBBO] No provider available after route for the service org.apache.dubbo.samples.governance.api.DemoService from registry 30.227.64.173 on the consumer 30.227.64.173 using the dubbo version 3.0.7. Router snapshot is below: +[ Parent (Input: 2) (Current Node Output: 2) (Chain Node Output: 0) ] Input: 30.227.64.173:20881,30.227.64.173:20880 -> Chain Node Output: Empty + [ MockInvokersSelector (Input: 2) (Current Node Output: 2) (Chain Node Output: 0) Router message: invocation.need.mock not set. Return normal Invokers. ] Current Node Output: 30.227.64.173:20881,30.227.64.173:20880 + [ StandardMeshRuleRouter (Input: 2) (Current Node Output: 2) (Chain Node Output: 0) Router message: MeshRuleCache has not been built. Skip route. ] Current Node Output: 30.227.64.173:20881,30.227.64.173:20880 + [ TagStateRouter (Input: 2) (Current Node Output: 0) (Chain Node Output: 0) Router message: FAILOVER: return all Providers without any tags ] Current Node Output: Empty, dubbo version: 3.0.7, current host: 30.227.64.173 +``` + +#### 开启路由全采样 + +在一些特殊情况下,请求可能调用到错误的服务端,但是因为选址非空,所以无法看到路由的过程信息,此时可以 [通过 qos 开启路由全采样](/zh-cn/overview/mannual/java-sdk/reference-manual/qos/router-snapshot/)。通过 qos 的 `getRecentRouterSnapshot` 命令可以远程获取最近的路由快照。 + +``` +dubbo>getRecentRouterSnapshot +1658224330156 - Router snapshot service com.dubbo.dubbointegration.BackendService from registry 172.18.111.184 on the consumer 172.18.111.184 using the dubbo version 3.0.9 is below: +[ Parent (Input: 2) (Current Node Output: 2) (Chain Node Output: 2) ] Input: 172.18.111.187:20880,172.18.111.183:20880 -> Chain Node Output: 172.18.111.187:20880,172.18.111.183:20880 + [ MockInvokersSelector (Input: 2) (Current Node Output: 2) (Chain Node Output: 2) Router message: invocation.need.mock not set. Return normal Invokers. ] Current Node Output: 172.18.111.187:20880,172.18.111.183:20880 + [ StandardMeshRuleRouter (Input: 2) (Current Node Output: 2) (Chain Node Output: 2) Router message: MeshRuleCache has not been built. Skip route. ] Current Node Output: 172.18.111.187:20880,172.18.111.183:20880 + [ TagStateRouter (Input: 2) (Current Node Output: 2) (Chain Node Output: 2) Router message: Disable Tag Router. Reason: tagRouterRule is invalid or disabled ] Current Node Output: 172.18.111.187:20880,172.18.111.183:20880 + [ ServiceStateRouter (Input: 2) (Current Node Output: 2) (Chain Node Output: 2) Router message: Directly return. Reason: Invokers from previous router is empty or conditionRouters is empty. ] Current Node Output: 172.18.111.187:20880,172.18.111.183:20880 + [ AppStateRouter (Input: 2) (Current Node Output: 2) (Chain Node Output: 2) Router message: Directly return. Reason: Invokers from previous router is empty or conditionRouters is empty. ] Current Node Output: 172.18.111.187:20880,172.18.111.183:20880 + +1658224330156 - Router snapshot service com.dubbo.dubbointegration.BackendService from registry 172.18.111.184 on the consumer 172.18.111.184 using the dubbo version 3.0.9 is below: +[ Parent (Input: 2) (Current Node Output: 2) (Chain Node Output: 2) ] Input: 172.18.111.187:20880,172.18.111.183:20880 -> Chain Node Output: 172.18.111.187:20880,172.18.111.183:20880 + [ MockInvokersSelector (Input: 2) (Current Node Output: 2) (Chain Node Output: 2) Router message: invocation.need.mock not set. Return normal Invokers. ] Current Node Output: 172.18.111.187:20880,172.18.111.183:20880 + [ StandardMeshRuleRouter (Input: 2) (Current Node Output: 2) (Chain Node Output: 2) Router message: MeshRuleCache has not been built. Skip route. ] Current Node Output: 172.18.111.187:20880,172.18.111.183:20880 + [ TagStateRouter (Input: 2) (Current Node Output: 2) (Chain Node Output: 2) Router message: Disable Tag Router. Reason: tagRouterRule is invalid or disabled ] Current Node Output: 172.18.111.187:20880,172.18.111.183:20880 + [ ServiceStateRouter (Input: 2) (Current Node Output: 2) (Chain Node Output: 2) Router message: Directly return. Reason: Invokers from previous router is empty or conditionRouters is empty. ] Current Node Output: 172.18.111.187:20880,172.18.111.183:20880 + [ AppStateRouter (Input: 2) (Current Node Output: 2) (Chain Node Output: 2) Router message: Directly return. Reason: Invokers from previous router is empty or conditionRouters is empty. ] Current Node Output: 172.18.111.187:20880,172.18.111.183:20880 + +··· + +dubbo> +``` + +#### 注意: +由于日志框架不匹配导致的日志为空可以参考[日志框架适配及运行时管理](../../others/logger-management/)动态修改日志输出框架。 diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/framework/more/set-host.md b/content/zh-cn/overview/mannual/java-sdk/tasks/framework/more/set-host.md new file mode 100644 index 000000000000..8ab9cad87a89 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/framework/more/set-host.md @@ -0,0 +1,81 @@ +--- +aliases: + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/others/set-host/ +description: 自定义 Dubbo 服务对外暴露的主机地址 +linkTitle: 主机配置 +title: 主机配置 +type: docs +weight: 37 +--- + + + +## 背景 + +在 Dubbo 中, Provider 启动时主要做两个事情,一是启动 server,二是向注册中心注册服务。启动 server 时需要绑定 socket,向注册中心注册服务时也需要发送 socket 唯一标识服务地址。 + +1. `dubbo`中不设置`host`时默认`host`是什么? +2. 那在`dubbo`中如何指定服务的`host`,我们是否可以用hostname或domain代替IP地址作为`host`? +3. 在使用docker时,有时需要设置端口映射,此时,启动server时绑定的socket和向注册中心注册的socket使用不同的端口号,此时又该如何设置? + +## 示例 +#### dubbo 中不设置 host 时默认 host 是什么 + +一般的 dubbo 协议配置如下: +``` xml + ... + + ... +``` + +可以看到,只配置了端口号,没有配置 host,此时设置的 host 又是什么呢? + +查看代码发现,在 `org.apache.dubbo.config.ServiceConfig#findConfigedHosts()` 中,通过 `InetAddress.getLocalHost().getHostAddress()` 获取默认 host。其返回值如下: + +1. 未联网时,返回 127.0.0.1 +2. 在阿里云服务器中,返回私有地址,如: 172.18.46.234 +3. 在本机测试时,返回公有地址,如: 30.5.10.11 + +#### 那在 dubbo 中如何指定服务的 socket? + +除此之外,可以通过 `dubbo.protocol` 或 `dubbo.provider `的 `host` 属性对 `host` 进行配置,支持IP地址和域名,如下: + +``` xml + ... + + ... +``` + +#### 在使用 docker 时,有时需要设置端口映射,此时,启动 server 时绑定的 socket 和向注册中心注册的 socket 使用不同的端口号,此时又该如何设置? + +见 [dubbo 通过环境变量设置 host](https://github.com/dubbo/dubbo-samples/tree/master/2-advanced/dubbo-samples-docker) + +有些部署场景需要动态指定服务注册的地址,如 docker bridge 网络模式下要指定注册宿主机 ip 以实现外网通信。dubbo 提供了两对启动阶段的系统属性,用于设置对外通信的ip、port地址。 + +* **DUBBO_IP_TO_REGISTRY**:注册到注册中心的 ip 地址 +* **DUBBO_PORT_TO_REGISTRY**:注册到注册中心的 port 端口 +* **DUBBO_IP_TO_BIND**:监听 ip 地址 +* **DUBBO_PORT_TO_BIND**:监听 port 端口 + +以上四个配置项均为可选项,如不配置 dubbo 会自动获取 ip 与端口,请根据具体的部署场景灵活选择配置。 +dubbo 支持多协议,如果一个应用同时暴露多个不同协议服务,且需要为每个服务单独指定 ip 或 port,请分别在以上属性前加协议前缀。 如: + +* **HESSIAN_DUBBO_PORT_TO_BIND**:hessian 协议绑定的 port +* **DUBBO_DUBBO_PORT_TO_BIND**:dubbo 协议绑定的 port +* **HESSIAN_DUBBO_IP_TO_REGISTRY**:hessian 协议注册的 ip +* **DUBBO_DUBBO_IP_TO_REGISTRY**:dubbo 协议注册的 ip + +PORT_TO_REGISTRY 或 IP_TO_REGISTRY 不会用作默认 PORT_TO_BIND 或 IP_TO_BIND,但是反过来是成立的。如: + +* 设置 `PORT_TO_REGISTRY=20881` 和 `IP_TO_REGISTRY=30.5.97.6`,则 `PORT_TO_BIND` 和 `IP_TO_BIND` 不受影响 +* 设置 `PORT_TO_BIND=20881` 和 `IP_TO_BIND=30.5.97.6`,则默认 `PORT_TO_REGISTRY=20881` 且 `IP_TO_REGISTRY=30.5.97.6` + +## 总结 + + 1. 可以通过`dubbo.protocol`或`dubbo.provider`的`host`属性对`host`进行配置,支持IP地址和域名.但此时注册到注册中心的IP地址和监听IP地址是同一个值 + 2. 为了解决在虚拟环境或局域网内consumer无法与provider通信的问题,可以通过环境变量分别设置注册到注册中心的IP地址和监听IP地址,其优先级高于`dubbo.protocol`或`dubbo.provider`的`host`配置 + +## 参考 + + 1. [Proposal: support hostname or domain in service discovery.](https://github.com/apache/dubbo/issues/2043) + 2. [dubbo通过环境变量设置host](https://github.com/dubbo/dubbo-samples/tree/master/2-advanced/dubbo-samples-docker) diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/specify-ip.md b/content/zh-cn/overview/mannual/java-sdk/tasks/framework/more/specify-ip.md similarity index 93% rename from content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/specify-ip.md rename to content/zh-cn/overview/mannual/java-sdk/tasks/framework/more/specify-ip.md index b1cfc62aba60..3a2ede78ad72 100644 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/specify-ip.md +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/framework/more/specify-ip.md @@ -6,31 +6,25 @@ description: 在发起 Dubbo 调用之前指定本次调用的目标 IP linkTitle: 运行时动态指定 IP 调用 title: 动态指定 IP 调用 type: docs -weight: 5 +weight: 4 --- - - - ## 特性说明 -使用 Dubbo 的扩展,实现指定 IP 调用。 -## 使用场景 - -发起请求的时候需要指定本次调用的服务端,如消息回调、流量隔离等。 +在发起 RPC 请求的时候,需要指定本次调用的服务端,常用的场景包括消息回调、流量隔离等。 ## 使用方式 ### 插件依赖 -适配 Dubbo 3 版本 +首先,需要添加以下插件依赖到项目中 ```xml org.apache.dubbo.extensions dubbo-cluster-specify-address-dubbo3 - 1.0.0 + 3.3.0 ``` diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/framework/threading-model.md b/content/zh-cn/overview/mannual/java-sdk/tasks/framework/threading-model.md new file mode 100644 index 000000000000..868e8d4a962e --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/framework/threading-model.md @@ -0,0 +1,425 @@ +--- +aliases: + - /zh/docs3-v2/java-sdk/advanced-features-and-usage/performance/threading-model/consumer/ + - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/performance/threading-model/consumer/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/threading-model/consumer/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/threading-model/ +description: Dubbo 消费端线程池模型用法 +linkTitle: 线程模型 +title: 消费端线程模型,提供者端线程模型 +type: docs +weight: 2 +--- + +## 消费端线程模型 + +对 2.7.5 版本之前的 Dubbo 应用,尤其是一些消费端应用,当面临需要消费大量服务且并发数比较大的大流量场景时(典型如网关类场景),经常会出现消费端线程数分配过多的问题,具体问题讨论可参见 [Need a limited Threadpool in consumer side #2013](https://github.com/apache/dubbo/issues/2013) + +改进后的消费端线程池模型,通过复用业务端被阻塞的线程,很好的解决了这个问题。 + +**老的线程池模型** + +![消费端线程池.png](/imgs/user/consumer-threadpool0.png) + +我们重点关注 Consumer 部分: + +1. 业务线程发出请求,拿到一个 Future 实例。 +2. 业务线程紧接着调用 future.get 阻塞等待业务结果返回。 +3. 当业务数据返回后,交由独立的 Consumer 端线程池进行反序列化等处理,并调用 future.set 将反序列化后的业务结果置回。 +4. 业务线程拿到结果直接返回 + +**当前线程池模型** + +![消费端线程池新.png](/imgs/user/consumer-threadpool1.png) + +1. 业务线程发出请求,拿到一个 Future 实例。 +2. 在调用 future.get() 之前,先调用 ThreadlessExecutor.wait(),wait 会使业务线程在一个阻塞队列上等待,直到队列中被加入元素。 +3. 当业务数据返回后,生成一个 Runnable Task 并放入 ThreadlessExecutor 队列 +4. 业务线程将 Task 取出并在本线程中执行:反序列化业务数据并 set 到 Future。 +5. 业务线程拿到结果直接返回 + +这样,相比于老的线程池模型,由业务线程自己负责监测并解析返回结果,免去了额外的消费端线程池开销。 + +## 提供端线程模型 +Dubbo协议的和Triple协议目前的线程模型还并没有对齐,下面分开介绍Triple协议和Dubbo协议的线程模型。 + +### Dubbo协议 + +介绍Dubbo协议的Provider端线程模型之前,先介绍Dubbo对channel上的操作抽象成了五种行为: + +- 建立连接:connected,主要是的职责是在channel记录read、write的时间,以及处理建立连接后的回调逻辑,比如dubbo支持在断开后自定义回调的hook(onconnect),即在该操作中执行。 +- 断开连接:disconnected,主要是的职责是在channel移除read、write的时间,以及处理端开连接后的回调逻辑,比如dubbo支持在断开后自定义回调的hook(ondisconnect),即在该操作中执行。 +- 发送消息:sent,包括发送请求和发送响应。记录write的时间。 +- 接收消息:received,包括接收请求和接收响应。记录read的时间。 +- 异常捕获:caught,用于处理在channel上发生的各类异常。 + +Dubbo框架的线程模型与以上这五种行为息息相关,Dubbo协议Provider线程模型可以分为五类,也就是AllDispatcher、DirectDispatcher、MessageOnlyDispatcher、ExecutionDispatcher、ConnectionOrderedDispatcher。 + +#### 配置方式 +| 线程模型 | 配置值 | +| ---- | -- | +All Dispatcher | all +Direct Dispatcher | direct +Execution Dispatcher | execution +Message Only Dispatcher | message +Connection Ordered Dispatcher | connection + +拿 application.yaml 的配置方式举例:在protocol下配置dispatcher: all,即可把dubbo协议的线程模型调整为All Dispatcher + +```yaml +dubbo: + application: + name: dubbo-springboot-demo-provider + protocol: + name: dubbo + port: -1 + dispatcher: all + registry: + id: zk-registry + address: zookeeper://127.0.0.1:2181 +``` + +#### All Dispatcher + +下图是All Dispatcher的线程模型说明图: + +![dubbo-provider-alldispatcher](/imgs/v3/feature/performance/threading-model/dubbo-provider-alldispatcher.png) + +- 在IO线程中执行的操作有: + 1. sent操作在IO线程上执行。 + 2. 序列化响应在IO线程上执行。 +- 在Dubbo线程中执行的操作有: + 1. received、connected、disconnected、caught都是在Dubbo线程上执行的。 + 2. 反序列化请求的行为在Dubbo中做的。 + +#### Direct Dispatcher + +下图是Direct Dispatcher的线程模型说明图: + +![dubbo-provider-directDispatcher](/imgs/v3/feature/performance/threading-model/dubbo-provider-directDispatcher.png) + +- 在IO线程中执行的操作有: + 1. received、connected、disconnected、caught、sent操作在IO线程上执行。 + 2. 反序列化请求和序列化响应在IO线程上执行。 +- 1. 并没有在Dubbo线程操作的行为。 + +#### Execution Dispatcher + +下图是Execution Dispatcher的线程模型说明图: + +![dubbo-provider-ExecutionDispatcher](/imgs/v3/feature/performance/threading-model/dubbo-provider-executionDispatcher.png) + +- 在IO线程中执行的操作有: + 1. sent、connected、disconnected、caught操作在IO线程上执行。 + 2. 序列化响应在IO线程上执行。 +- 在Dubbo线程中执行的操作有: + 1. received都是在Dubbo线程上执行的。 + 2. 反序列化请求的行为在Dubbo中做的。 + +#### Message Only Dispatcher + +在Provider端,Message Only Dispatcher和Execution Dispatcher的线程模型是一致的,所以下图和Execution Dispatcher的图一致,区别在Consumer端。见下方Consumer端的线程模型。 + +下图是Message Only Dispatcher的线程模型说明图: + +![dubbo-provider-ExecutionDispatcher](/imgs/v3/feature/performance/threading-model/dubbo-provider-executionDispatcher.png) + +- 在IO线程中执行的操作有: + 1. sent、connected、disconnected、caught操作在IO线程上执行。 + 2. 序列化响应在IO线程上执行。 +- 在Dubbo线程中执行的操作有: + 1. received都是在Dubbo线程上执行的。 + 2. 反序列化请求的行为在Dubbo中做的。 + +#### Connection Ordered Dispatcher + +下图是Connection Ordered Dispatcher的线程模型说明图: + +![dubbbo-provider-connectionOrderedDispatcher](/imgs/v3/feature/performance/threading-model/dubbbo-provider-connectionOrderedDispatcher.png) + +- 在IO线程中执行的操作有: + 1. sent操作在IO线程上执行。 + 2. 序列化响应在IO线程上执行。 +- 在Dubbo线程中执行的操作有: + 1. received、connected、disconnected、caught都是在Dubbo线程上执行的。但是connected和disconnected两个行为是与其他两个行为通过线程池隔离开的。并且在Dubbo connected thread pool中提供了链接限制、告警灯能力。 + 2. 反序列化请求的行为在Dubbo中做的。 + + +### Triple协议 + +下图为Triple协议 Provider端的线程模型 + +![triple-provider](/imgs/v3/feature/performance/threading-model/triple-provider.png) + +Triple协议Provider线程模型目前还比较简单,目前序列化和反序列化操作都在Dubbo线程上工作,而IO线程并没有承载这些工作。 + + +## 线程池隔离 +一种新的线程池管理方式,使得提供者应用内各个服务的线程池隔离开来,互相独立,某个服务的线程池资源耗尽不会影响其他正常服务。支持线程池可配置化,由用户手动指定。 + +使用线程池隔离来确保 Dubbo 用于调用远程方法的线程与微服务用于执行其任务的线程是分开的。可以通过防止线程阻塞或相互竞争来帮助提高系统的性能和稳定性。 + +目前可以以 API、XML、Annotation 的方式进行配置 + +**配置参数** +- `ApplicationConfig` 新增 `String executor-management-mode` 参数,配置值为 `default` 和 `isolation` ,默认为 `default`。 + - `executor-management-mode = default` 使用原有 **以协议端口为粒度、服务间共享** 的线程池管理方式 + - `executor-management-mode = isolation` 使用新增的 **以服务三元组为粒度、服务间隔离** 的线程池管理方式 +- `ServiceConfig` 新增 `Executor executor` 参数,**用以服务间隔离的线程池**,可以由用户配置化、提供自己想要的线程池,若没有指定,则会根据协议配置(`ProtocolConfig`)信息构建默认的线程池用以服务隔离。 + +> `ServiceConfig` 新增 `Executor executor` 配置参数只有指定`executor-management-mode = isolation` 才生效。 +#### API +```java + public void test() { + // provider app + DubboBootstrap providerBootstrap = DubboBootstrap.newInstance(); + + ServiceConfig serviceConfig1 = new ServiceConfig(); + serviceConfig1.setInterface(DemoService.class); + serviceConfig1.setRef(new DemoServiceImpl()); + serviceConfig1.setVersion(version1); + // set executor1 for serviceConfig1, max threads is 10 + NamedThreadFactory threadFactory1 = new NamedThreadFactory("DemoService-executor"); + ExecutorService executor1 = Executors.newFixedThreadPool(10, threadFactory1); + serviceConfig1.setExecutor(executor1); + + ServiceConfig serviceConfig2 = new ServiceConfig(); + serviceConfig2.setInterface(HelloService.class); + serviceConfig2.setRef(new HelloServiceImpl()); + serviceConfig2.setVersion(version2); + // set executor2 for serviceConfig2, max threads is 100 + NamedThreadFactory threadFactory2 = new NamedThreadFactory("HelloService-executor"); + ExecutorService executor2 = Executors.newFixedThreadPool(100, threadFactory2); + serviceConfig2.setExecutor(executor2); + + ServiceConfig serviceConfig3 = new ServiceConfig(); + serviceConfig3.setInterface(HelloService.class); + serviceConfig3.setRef(new HelloServiceImpl()); + serviceConfig3.setVersion(version3); + // Because executor is not set for serviceConfig3, the default executor of serviceConfig3 is built using + // the threadpool parameter of the protocolConfig ( FixedThreadpool , max threads is 200) + serviceConfig3.setExecutor(null); + + // It takes effect only if [executor-management-mode=isolation] is configured + ApplicationConfig applicationConfig = new ApplicationConfig("provider-app"); + applicationConfig.setExecutorManagementMode("isolation"); + + providerBootstrap + .application(applicationConfig) + .registry(registryConfig) + // export with tri and dubbo protocol + .protocol(new ProtocolConfig("tri", 20001)) + .protocol(new ProtocolConfig("dubbo", 20002)) + .service(serviceConfig1) + .service(serviceConfig2) + .service(serviceConfig3); + + providerBootstrap.start(); + } +``` + +#### XML +```xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +``` +#### Annotation +```java +@Configuration +@EnableDubbo(scanBasePackages = "org.apache.dubbo.config.spring.isolation.spring.annotation.provider") +public class ProviderConfiguration { + @Bean + public RegistryConfig registryConfig() { + RegistryConfig registryConfig = new RegistryConfig(); + registryConfig.setAddress("zookeeper://127.0.0.1:2181"); + return registryConfig; + } + + // NOTE: we need config executor-management-mode="isolation" + @Bean + public ApplicationConfig applicationConfig() { + ApplicationConfig applicationConfig = new ApplicationConfig("provider-app"); + + applicationConfig.setExecutorManagementMode("isolation"); + return applicationConfig; + } + + // expose services with dubbo protocol + @Bean + public ProtocolConfig dubbo() { + ProtocolConfig protocolConfig = new ProtocolConfig("dubbo"); + return protocolConfig; + } + + // expose services with tri protocol + @Bean + public ProtocolConfig tri() { + ProtocolConfig protocolConfig = new ProtocolConfig("tri"); + return protocolConfig; + } + + // customized thread pool + @Bean("executor-demo-service") + public Executor demoServiceExecutor() { + return new DemoServiceExecutor(); + } + + // customized thread pool + @Bean("executor-hello-service") + public Executor helloServiceExecutor() { + return new HelloServiceExecutor(); + } +} +``` +```java +// customized thread pool +public class DemoServiceExecutor extends ThreadPoolExecutor { + public DemoServiceExecutor() { + super(10, 10, 60, TimeUnit.SECONDS, new LinkedBlockingDeque<>(), + new NamedThreadFactory("DemoServiceExecutor")); + } +} +``` + +```java +// customized thread pool +public class HelloServiceExecutor extends ThreadPoolExecutor { + public HelloServiceExecutor() { + super(100, 100, 60, TimeUnit.SECONDS, new LinkedBlockingDeque<>(), + new NamedThreadFactory("HelloServiceExecutor")); + } +} +``` +```java +// "executor-hello-service" is beanName +@DubboService(executor = "executor-demo-service", version = "1.0.0", group = "Group1") +public class DemoServiceImplV1 implements DemoService { + + @Override + public String sayName(String name) { + return "server name"; + } + + @Override + public Box getBox() { + return null; + } +} + +``` + +```java +// not set executor for this service, the default executor built using threadpool parameter of the protocolConfig +@DubboService(version = "3.0.0", group = "Group3") +public class HelloServiceImplV2 implements HelloService { + private static final Logger logger = LoggerFactory.getLogger(HelloServiceImplV2.class); + + @Override + public String sayHello(String name) { + return "server hello"; + } +} + +``` + +```java +@DubboService(executor = "executor-hello-service", version = "2.0.0", group = "Group2") +public class HelloServiceImplV3 implements HelloService { + private static final Logger logger = LoggerFactory.getLogger(HelloServiceImplV3.class); + + @Override + public String sayHello(String name) { + return "server hello"; + } +} +``` + + + +## 线程池状态导出 +dubbo 通过 Jstack 自动导出线程堆栈来保留现场,方便排查问题。 + +默认策略 + +* 导出路径: user.home标识的用户主目录 +* 导出间隔: 最短间隔允许每隔10分钟导出一次 +* 导出开关: 默认打开 + +当业务线程池满时,我们需要知道线程都在等待哪些资源、条件,以找到系统的瓶颈点或异常点。 + +#### 导出开关控制 +```properties +# dubbo.properties +dubbo.application.dump.enable=true +``` +```xml + +``` + +```yaml +dubbo: + application: + name: dubbo-springboot-demo-provider + dump-enable: false +``` + + + +#### 导出路径 + +```properties +# dubbo.properties +dubbo.application.dump.directory=/tmp +``` + +```xml + +``` + +```yaml +dubbo: + application: + name: dubbo-springboot-demo-provider + dump-directory: /tmp +``` diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/framework/timeout.md b/content/zh-cn/overview/mannual/java-sdk/tasks/framework/timeout.md new file mode 100644 index 000000000000..cbad6a8863a6 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/framework/timeout.md @@ -0,0 +1,79 @@ +--- +aliases: + - /zh/overview/tasks/develop/async/ + - /zh/docs3-v2/java-sdk/advanced-features-and-usage/service/async-call/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/async-call/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/async-execute-on-provider/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/async/ +description: 某些情况下希望dubbo接口异步调用,避免不必要的等待。 +linkTitle: 超时时间 +title: 为服务调用指定 timeout 超时时间 +type: docs +weight: 3 +--- + +为 RPC 调用设置超时时间可以提升集群整体稳定性,避免无限等待响应结果导致的资源占用(比如大量长期无响应的请求占用线程池等)。在调用没有响应的情况下,比如 5s 之后,Dubbo 框架就会自动终止调用等待过程(抛出 TimeoutException),释放此次调用占用的资源。 + +## 使用方式 +有多种方式可以配置 rpc 调用超时时间,从粗粒度的全局默认值,到特定服务、特定方法级别的独立配置: + +配置全局默认超时时间为 5s(不配置的情况下,所有服务的默认超时时间是 1s)。 +```yaml +dubbo: + provider: + timeout: 5000 +``` + +在消费端,指定 DemoService 服务调用的超时时间为 5s +```java +@DubboReference(timeout=5000) +private DemoService demoService; +``` + +在提供端,指定 DemoService 服务调用的超时时间为 5s(可作为所有消费端的默认值,如果消费端有指定则优先级更高) +```java +@DubboService(timeout=5000) +public class DemoServiceImpl implements DemoService{} +``` + +在消费端,指定 DemoService sayHello 方法调用的超时时间为 5s +```java +@DubboReference(methods = {@Method(name = "sayHello", timeout = 5000)}) +private DemoService demoService; +``` + +在提供端,指定 DemoService sayHello 方法调用的超时时间为 5s(可作为所有消费端的默认值,如果消费端有指定则优先级更高) +```java +@DubboService(methods = {@Method(name = "sayHello", timeout = 5000)}) +public class DemoServiceImpl implements DemoService{} +``` + +以上配置形式的优先级从高到低依次为:`方法级别配置 > 服务级别配置 > 全局配置 > 默认值`。 + +## Deadline 机制 + + +我们来分析一下以上调用链路以及可能出现的超时情况: +* A 调用 B 设置了超时时间 5s,因此 `B -> C -> D` 总计耗时不应该超过 5s,否则 A 就会收到超时异常 +* 在任何情形下,只要 A 等待 5s 没有收到响应,整个调用链路就可以被终止了(如果此时 C 正在运行,则 `C -> D` 就没有发起的意义了) +* 理论上 `B -> C`、`C -> D` 都有自己独立的超时时间设置,超时计时也是独立计算的,它们不知道 A 作为调用发起方是否超时 + +在 Dubbo 框架中,`A -> B` 的调用就像一个开关,一旦启动,在任何情形下整个 `A -> B -> C -> D` 调用链路都会被完整执行下去,即便调用方 A 已经超时,后续的调用动作仍会继续。这在一些场景下是没有意义的,尤其是链路较长的情况下会带来不必要的资源消耗,deadline 就是设计用来解决这个问题,通过在调用链路中传递 deadline(deadline初始值等于超时时间,随着时间流逝而减少)可以确保调用链路只在有效期内执行,deadline 消耗殆尽之后,调用链路中其他尚未执行的任务将被取消。 + +因此 deadline 机制就是将 ` B -> C -> D` 当作一个整体看待,这一系列动作必须在 5s 之内完成。随着时间流逝 deadline 会从 5s 逐步扣减,后续每一次调用实际可用的超时时间即是当前 deadline 值,比如 `C` 收到请求时已经过去了 3s,则 `C -> D` 的超时时间只剩下 2s。 + + + +deadline 机制默认是关闭的,如果要启用 deadline 机制,需要配置以下参数: +```yaml +dubbo: + provider: + timeout: 5000 + parameters.enable-timeout-countdown: true +``` + +也可以指定某个服务调用开启 deadline 机制: +```java +@DubboReference(timeout=5000, parameters={"enable-timeout-countdown", "true"}) +private DemoService demoService; +``` diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/framework/version_group.md b/content/zh-cn/overview/mannual/java-sdk/tasks/framework/version_group.md new file mode 100644 index 000000000000..f0c7d7976367 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/framework/version_group.md @@ -0,0 +1,312 @@ +--- +aliases: + - /zh/overview/tasks/develop/version_group/ + - /zh/docs3-v2/java-sdk/advanced-features-and-usage/service/service-group/ + - /zh/docs3-v2/java-sdk/advanced-features-and-usage/service/multi-versions/ + - /zh/docs3-v2/java-sdk/advanced-features-and-usage/service/version_group/ + - /zh/docs3-v2/java-sdk/advanced-features-and-usage/service/group-merger/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/service-group/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/service-version/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/multi-versions/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/group-merger/ +description: "" +linkTitle: 版本与分组 +title: 版本与分组 +type: docs +weight: 4 +--- + +Dubbo服务中,接口并不能唯一确定一个服务,只有 `接口+分组+版本号` 的三元组才能唯一确定一个服务。 + +* 当同一个接口针对不同的业务场景、不同的使用需求或者不同的功能模块等场景,可使用服务分组来区分不同的实现方式。同时,这些不同实现所提供的服务是可并存的,也支持互相调用。 +* 当接口实现需要升级又要保留原有实现的情况下,即出现不兼容升级时,我们可以使用不同版本号进行区分。 + +本文示例完整源码可在以下链接查看: +* [dubbo-samples-group](https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-group) +* [dubbo-samples-version](https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-version) +* [dubbo-samples-merge](https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-merge) + +## 使用方式 +使用 @DubboService 注解,配置 `group` 参数和 `version` 参数: + +接口定义: +```java +public interface DevelopService { + String invoke(String param); +} +``` + +接口实现1: +```java +@DubboService(group = "group1", version = "1.0") +public class DevelopProviderServiceV1 implements DevelopService{ + @Override + public String invoke(String param) { + StringBuilder s = new StringBuilder(); + s.append("ServiceV1 param:").append(param); + return s.toString(); + } +} +``` +接口实现2: +```java +@DubboService(group = "group2", version = "2.0") +public class DevelopProviderServiceV2 implements DevelopService{ + @Override + public String invoke(String param) { + StringBuilder s = new StringBuilder(); + s.append("ServiceV2 param:").append(param); + return s.toString(); + } +} +``` + +客户端接口调用: + +> 使用 @DubboReference 注解,添加 group 参数和 version 参数 + +```java +@DubboReference(group = "group1", version = "1.0") +private DevelopService developService; + +@DubboReference(group = "group2", version = "2.0") +private DevelopService developServiceV2; + +@Override +public void run(String... args) throws Exception { + //调用DevelopService的group1分组实现 + System.out.println("Dubbo Remote Return ======> " + developService.invoke("1")); + //调用DevelopService的另一个实现 + System.out.println("Dubbo Remote Return ======> " + developServiceV2.invoke("2")); +} +``` + +#### 服务消费端(注解配置) + +使用 @DubboReference 注解,添加 group 参数 + +```java +@DubboReference(group = "demo") +private DemoService demoService; + +@DubboReference(group = "demo2") +private DemoService demoService2; + +//group值为*,标识匹配任意服务分组 +@DubboReference(group = "*") +private DemoService demoService2; +``` + +同样启动 Dubbo 服务后,可在注册中心看到相同服务名不同分组的引用者,以 Nacos 作为注册中心为例,显示如下内容: +![image-service-group-2.png](/imgs/blog/service-group-2.png) + +#### 服务提供端( xml 配置) + +使用 标签,添加 group 参数 + +```xml + + + ... + + + +... + +``` + +启动 Dubbo 服务,可在注册中心看到相同服务名不同分组的服务,以 Nacos 作为注册中心为例,显示如下内容: + +![image-service-group-1.png](/imgs/blog/service-group-1.png) + +#### 服务消费端( xml 配置) + +使用 注解,添加 group 参数 + +```xml + + + ... + + + + + + + + ... + +``` + +同样启动 Dubbo 服务后,可在注册中心看到相同服务名不同分组的引用者,以 Nacos 作为注册中心为例,显示如下内容: + +![image-service-group-2.png](/imgs/blog/service-group-2.png) + +#### 服务提供端( API 配置) + +使用 org.apache.dubbo.config.ServiceConfig 类,添加 group 参数 + +```java +// ServiceConfig为重对象,内部封装了与注册中心的连接,以及开启服务端口 +// 请自行缓存,否则可能造成内存和连接泄漏 +ServiceConfig service = new ServiceConfig<>(); +service.setInterface(DemoService.class); +service.setGroup("demo"); +... + +ServiceConfig service2 = new ServiceConfig<>(); +service.setInterface(DemoService.class); +service.setGroup("demo2"); +... +``` + +启动 Dubbo 服务,可在注册中心看到相同服务名不同分组的服务,以 Nacos 作为注册中心为例,显示如下内容: + +![image-service-group-1.png](/imgs/blog/service-group-1.png) + +#### 服务消费端( API 配置) + +使用 org.apache.dubbo.config.ReferenceConfig,添加 group 参数 + +```java +// ReferenceConfig为重对象,内部封装了与注册中心的连接,以及开启服务端口 +// 请自行缓存,否则可能造成内存和连接泄漏 +ReferenceConfig reference = new ReferenceConfig<>(); +reference.setInterface(DemoService.class); +reference.setGroup("demo"); +... + +ReferenceConfig reference2 = new ReferenceConfig<>(); +reference2.setInterface(DemoService.class); +reference2.setGroup("demo2"); +... + +ReferenceConfig reference3 = new ReferenceConfig<>(); +reference3.setInterface(DemoService.class); +reference3.setGroup("*"); +... + +``` +同样启动 Dubbo 服务后,可在注册中心看到相同服务名不同分组的引用者,以 Nacos 作为注册中心为例,显示如下内容: +![image-service-group-2.png](/imgs/blog/service-group-2.png) + + +> 总是 **只调** 一个可用组的实现 + + +## 分组聚合 +通过分组对结果进行聚合并返回聚合后的结果,比如菜单服务,用 group 区分同一接口的多种实现,现在消费方需从每种 group 中调用一次并返回结果,对结果进行合并之后返回,这样就可以实现聚合菜单项。 + +相关代码可以参考 [dubbo 项目中的示例](https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-merge) + +将多个服务提供者分组作为一个提供者进行访问。应用程序能够像访问一个服务一样访问多个服务,并允许更有效地使用资源。 + +### 搜索所有分组 + +```xml + +``` + +### 合并指定分组 + +```xml + +``` +### 指定方法合并 + +指定方法合并结果,其它未指定的方法,将只调用一个 Group + +```xml + + + +``` +### 某个方法不合并 + +某个方法不合并结果,其它都合并结果 + +```xml + + + +``` +### 指定合并策略 + +指定合并策略,缺省根据返回值类型自动匹配,如果同一类型有两个合并器时,需指定合并器的名称 [合并结果扩展](/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/merger) + +```xml + + + +``` +### 指定合并方法 + +指定合并方法,将调用返回结果的指定方法进行合并,合并方法的参数类型必须是返回结果类型本身 + +```xml + + + +``` + +{{% alert title="提示" color="primary" %}} +`2.1.0` 开始支持 +{{% /alert %}} + + + + + +## 跨版本升级 +**按照以下的步骤进行版本迁移** + +1. 在低压力时间段,先升级一半提供者为新版本 +2. 再将所有消费者升级为新版本 +3. 然后将剩下的一半提供者升级为新版本 + +#### 配置 +- 新老版本服务提供者 +- 新老版本服务消费者 + +当一个接口实现,出现不兼容升级时,可以用版本号过渡,版本号不同的服务相互间不引用。 + +>参考用例 +[https://github.com/apache/dubbo-samples/tree/master/dubbo-samples-version](https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-version) + +### 服务提供者 +老版本服务提供者配置 +```xml + +``` +新版本服务提供者配置 +```xml + +``` +### 服务消费者 +老版本服务消费者配置 +```xml + +``` +新版本服务消费者配置 +```xml + +``` +### 不区分版本 +如果不需要区分版本,可以按照以下的方式配置 +```xml + +``` + + diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/gateway/_index.md b/content/zh-cn/overview/mannual/java-sdk/tasks/gateway/_index.md new file mode 100755 index 000000000000..ba7223d607c8 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/gateway/_index.md @@ -0,0 +1,8 @@ +--- +description: "如果通过 Higress、APISIX 等网关产品解决前端 http 流量接入后端 RPC 微服务问题。" +linkTitle: HTTP网关接入 +title: HTTP流量接入 +type: docs +weight: 8 +--- + diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/gateway/architecture.md b/content/zh-cn/overview/mannual/java-sdk/tasks/gateway/architecture.md new file mode 100644 index 000000000000..0191c1602934 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/gateway/architecture.md @@ -0,0 +1,41 @@ +--- +description: | + 本文讲述前端 http 流量接入后端 Dubbo 微服务的的基本架构,包括移动端、浏览器、桌面应用、异构的微服务体系等。 +linkTitle: 基本架构 +title: 前端 http 流量接入 Dubbo 后端微服务体系的基础架构 +type: docs +weight: 1 +--- + +不论你开发的是什么样的产品(电子商城、管理系统、手机 app 等),绝大多数下产品的流量入口都会是 http,用户可能通过浏览器、手机移动设备、桌面软件等来访问产品。在这种情况下,如何将后端开发的 Dubbo 微服务集群接入前端访问设备就成为一个需要解决的问题,其实也就是 http 与 rpc 之间的转换与连接问题。 + +总的来说,有中心化和去中心化两种架构模式。其中,中心化接入模式更具通用性,对后端 rpc 协议、前端网关没有太多特殊要求,但保证中心化应用的性能、稳定性是一个较大的挑战;去中心化模式由于不需要维护入口应用,因此可适应更大流量、更大规模的集群。 + +## 中心化接入方式 +中心化接入方式的架构图如下: +* 在后端服务与前端设备之间有一层网关,负责流量过滤、路由、限流等流量管理工作 +* 在后端集群中有一个连接 http 与 dubbo 服务的 “统一微服务入口应用”(通常也叫做 BFF,即Backend for Frontend)。 + + + +BFF 应用通常可以使用 Spring Web 等常用框架开发,应用发布一系列的 http 服务,接收网关或前端设备流量,同时负责按需发起 dubbo 调用。 + +{{% alert title="注意" color="info" %}} +`dubbo`、`triple` 协议都支持这种接入架构。另外,在配置 BFF 应用调用 dubbo 服务时,可以使用普通的 dubbo 配置方式,也可以使用泛化调用等方式: +* 配置接入 dubbo 协议时,使用 [泛化调用]() 的优势是可以避免对服务二进制包的依赖,实现配置动态生效的效果。 +* 配置接入 triple 协议时,可以使用 http 调用方式,同样可避免对服务二进制包的依赖,实现配置动态生效的效果。 +{{% /alert %}} + +## 去中心化接入方式 +与中心化架构相比,此方式并没有太大的差异,唯一的区别在于不需要额外的 BFF 应用,我们可以在网关直接调用后端 dubbo 服务。 + +但这种方式对网关有特别要求。如果后端是 dubbo 协议的话,则要求网关具备 `http -> dubbo` 协议转换的能力,但你会在接下来的文档中发现,我们可以通过多协议发布绕过协议转换,让网关直接通过 http 访问后端服务;如果后端是 triple 协议,就会更简单了,因为 triple 协议支持 application/json 格式的 http 请求。 + + + +## 总结 +使用不同的协议也会影响架构选择,triple 协议由于原生支持 HTTP 访问,因此对两种架构方式都可以无差别支持,并且接入原理上也会更简单直接。而 dubbo 协议作为 Dubbo2 时代主推的协议,由于是基于 tcp 的二进制协议,因此在接入方式上存在一些不同。 + +我们将在接下来的两篇文档中介绍 dubbo、triple 两种协议的具体前端流量接入方式,文档同样适用于中心化、去中心化架构。 + + diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/gateway/dubbo.md b/content/zh-cn/overview/mannual/java-sdk/tasks/gateway/dubbo.md new file mode 100644 index 000000000000..8909d162335e --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/gateway/dubbo.md @@ -0,0 +1,81 @@ +--- +aliases: + - /zh/overview/tasks/ecosystem/gateway/ + - /zh-cn/overview/tasks/ecosystem/gateway/ +description: | + 本文介绍借助 Apache Higress 实现 Dubbo Service 服务代理,后端服务使用 dubbo 通信协议。 +linkTitle: dubbo协议 +title: 通过网关将 http 流量接入 Dubbo 后端服务 +type: docs +weight: 2 +--- + +由于 dubbo 协议是基于 TCP 的二进制私有协议,因此更适合作为后端微服务间的高效 RPC 通信协议,这也导致 dubbo 协议对于前端流量接入不是很友好。在 Dubbo 框架中,有两种方式可以帮助开发者解决这个问题: +* **多协议发布【推荐】**,为 dubbo 协议服务暴露 rest 风格的 http 协议访问方式,这种模式架构上会变得非常简单,通用的网关产品即可支持。 +* **通过网关实现 `http->dubbo` 协议转换**,这种方式需要将 http 协议转换为后端服务能识别的 dubbo 协议,要求网关必须支持 dubbo 协议。 + +## 同时发布 http、dubbo 协议 +**如果我们能让一个服务同时发布 dubbo、http 协议,这样后端调用是基于高效的 dubbo 二进制协议,同时浏览器、web服务等前端设施也可以用 http 协议访问到相同的服务。** 好消息是,Dubbo 框架支持为同一个服务发布多个协议,并且支持客户端通过同一个端口以不同的协议访问服务,如下所示: + + + +为了实现同时发布 dubbo、http 协议,我们只需要在配置文件中增加一行配置即可: + +```yaml +dubbo: + protocol: + dubbo: dubbo + port: 20880 + ext-protocol: tri +``` + +增加 `ext-protocol: tri` 配置后,进程就可以在 20880 端口上提供 http 服务了,这点我们从之前的 triple 协议中有过具体了解了,启用应用后就可以在 20880 端口访问: + +```shell +curl \ + --header "Content-Type: application/json" \ + --data '["Dubbo"]' \ + http://localhost:20880/org.apache.dubbo.protocol.multiple.demo.DemoService/sayHello +``` + +此时,网关就可以直接以 http 方式接入后端 dubbo 服务,任何 http 网关都可以非常容易接入,操作非常简洁明了。 + +{{% alert title="注意" color="info" %}} +另外,关于 dubbo、triple 多协议发布的完整示例源码和讲解可参见 [dubbo+rest 双协议发布的示例](/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/multi-protocols/)。 +{{% /alert %}} + +如果你对 `/org.apache.dubbo.protocol.multiple.demo.DemoService/sayHello` 格式的前端访问路径不满意,可以选择发布 rest 风格的 http 接口,我们只需要在接口上增加注解即可(目前支持 Spring Web、JAX-RS 两种注解)。如下所示,假设我们已经有一个名为 DemoService 的 dubbo 服务,只需要增加以下注解: + +```java +@RestController +@RequestMapping("/triple") +public interface DemoService { + @GetMapping(value = "/demo") + String sayHello(); +} +``` + +这样,就能发布同时支持 dubbo、rest 两种协议的服务,对于 http 网关接入更为简单便捷,唯一成本是需要改造接口增加注解。 + +为 dubbo 协议服务增加了 http 访问方式之后,就可以很容易的将 dubbo 服务接入网关了,具体可以参见下一小节中的 [triple 协议网关接入](/zh-cn/overview/mannual/java-sdk/tasks/gateway/triple/) 示例,那里有详细的说明。 + +## http 转 dubbo 协议 +{{% alert title="注意" color="warning" %}} +如果您使用的是 Dubbo3 3.3.x 版本,在决定考虑此方案之前,我们强烈推荐您仔细评估本文前一节的 `多协议发布方案`。除非您因为某些特殊原因真的无法接受多协议发布带来的应用改造成本(实际上只是改一行配置而已),否则这个方案应该作为第二选择。 +{{% /alert %}} + +如果要从网关接入后端 dubbo 服务,则前端的 HTTP 流量要经过一层 `http -> dubbo` 的协议转换才能实现正常调用 + + + +如上图所示,从浏览器、手机或者 Web 服务器发送的 HTTP 请求,经过网关进行 http 到 dubbo 协议转换,网关最终转发 dubbo 协议到后端微服务集群。因此,我们需要一个支持 dubbo 协议转换的网关,来帮助实现协议转发,以下是该架构下网关需要实现的几个关键点: +* **协议转换**,支持 http 到 dubbo 的协议转换,包括参数映射。 +* **自动地址发现**,支持 Nacos、Zookeeper、Kubernetes 等主流注册中心,动态感知后端 dubbo 实例变化。 +* **结合 dubbo 协议的路由**,如在发起 dubbo 协议调用时,支持按照特定规则地址筛选、传递附加参数到 dubbo 后端服务。 + +目前市面上支持 dubbo 协议接入、且对以上三点提供比较完善支持的开源网关产品众多,包括大家 Higress、Apache APISIX、Apache Shenyu 等。接下来,让我们通过一些示例来了解网关产品搭配 Dubbo 的具体使用方法吧: +* [使用 Higress 代理 Dubbo 流量]({{< relref "../../../../../../blog/integration/how-to-proxy-dubbo-in-higress" >}}) +* [使用 Apache APISIX 代理 Dubbo 流量]({{< relref "../../../../../../blog/integration/how-to-proxy-dubbo-in-apache-apisix" >}}) +* [使用 Apache Shenyu 代理 Dubbo 流量]({{< relref "../../../../../../blog/integration/how-to-proxy-dubbo-in-apache-shenyu" >}}) + +如果您并没有使用现成的网关产品,而是使用自建的流量转换组件,您很有可能使用到了 Dubbo 框架中的 [**泛化调用**](/zh-cn/overview/mannual/java-sdk/tasks/framework/more/generic/) 机制,具体请参考相关文档了解详情。 diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/gateway/triple.md b/content/zh-cn/overview/mannual/java-sdk/tasks/gateway/triple.md new file mode 100644 index 000000000000..ef5ebe542cf4 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/gateway/triple.md @@ -0,0 +1,256 @@ +--- +aliases: + - /zh/overview/tasks/ecosystem/gateway/ + - /zh-cn/overview/tasks/ecosystem/gateway/ +description: | + 通过 Higress 云原生网关实现 Dubbo Service 代理,支持 triple 协议。 +linkTitle: triple协议 +title: 通过网关将 http 流量接入 Dubbo 后端服务 +type: docs +weight: 3 +--- + +在 [triple协议规范](/zh-cn/overview/reference/protocols/triple-spec/) 中我们曾详细介绍了 triple 对于浏览器、网关的友好性设计,其中非常重要的一点是 triple 同时支持跑在 HTTP/1、HTTP/2 上: +* 在后端服务之间使用高效的 triple 二进制协议。 +* 对于前端接入层,则支持所有标准 HTTP 工具如 cURL 等以标准 `application/json` 、`application/yaml` 等格式请求后端服务。 + +接下来我们就看一下,对于前端 HTTP 流量而言,如何通过一些通用的网关产品快速接入后端的 triple 微服务体系。 + +{{% alert title="注意" color="warning" %}} +使用 triple 协议后,不再需要泛化调用、`http -> dubbo` 协议转换等步骤,任何主流的网关设备都可以通过 http 流量直接访问后端 triple 协议服务。 +具体参见 [发布 REST 风格的服务](../../protocols/rest/) +{{% /alert %}} + +## 原生 HTTP 接入 + + + +如上图所示,从浏览器、手机或 Web 服务器过来的 HTTP 请求,网关可直接转发给后端 Dubbo 服务,后端服务之间则继续走 triple 二进制协议。**由于进出网关的都是标准的 HTTP 流量,网关不需要做任何的私有协议转换工作,不需要任何定制化逻辑,只需专注于流量路由等职责即可。** + +在真正的生产环境下,**唯一需要网关解决的只剩下地址发现问题,即如何动态感知后端 triple 服务的实例变化?** 好消息是,目前几款主流的开源网关产品如 Apache APISIX、Higress 等普遍支持以 Nacos、Zookeeper、Kubernetes 作为 upstream 数据源。 + +以下我们以 `Higress + Nacos + Dubbo` 的典型用法为例,详细说明整套机制的工作流程。 + + + +### 启动示例应用 + +本示例完整源码请参见 [dubbo-samples-gateway-higress-triple](https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-gateway/dubbo-samples-gateway-higress/dubbo-samples-gateway-higress-triple)。 + +该示例中定义并发布了一个定义为 `org.apache.dubbo.samples.gateway.api.DemoService` 的 triple 服务: + +```java +public interface DemoService { + String sayHello(String name); +} +``` + +接下来,我们演示如何启动 Dubbo 服务,并使用 Higress 网关转发请求到后端服务。 + +### 接入 Higress 网关 + +接下来,我们具体演示 Higress 网关接入应用的具体步骤。包括部署 Dubbo 应用、Nacos 注册中心、Higress 网关等。 + +#### 安装 Higress 和 Nacos + +以下示例部署在 Kubernetes 环境,因此请确保您已经连接到一个可用 Kubernetes 集群。 + +1. 安装 Higress,参考 [Higress安装部署文档](https://higress.io/zh-cn/docs/ops/deploy-by-helm) + +2. 安装 Nacos,运行 + +```shell +kubectl apply -f https://raw.githubusercontent.com/apache/dubbo-samples/master/2-advanced/dubbo-samples-gateway/dubbo-samples-gateway-higress/dubbo-samples-gateway-higress-triple/deploy/nacos/Nacos.yaml +``` + +#### 启动 Dubbo 应用 + +将以上示例应用打包为 docker image 后(这里我们使用官方示例提前打包好的镜像),以标准 Kubernetes Deployment 形式启动应用: + +```shell +kubectl apply -f https://raw.githubusercontent.com/apache/dubbo-samples/master/2-advanced/dubbo-samples-gateway/dubbo-samples-gateway-higress/dubbo-samples-gateway-higress-triple/deploy/provider/Deployment.yaml +``` + +具体的部署文件定义如下: + +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: gateway-higress-triple-provider + namespace: default + labels: + app: gateway-higress-triple-provider +spec: + replicas: 1 + selector: + matchLabels: + app: gateway-higress-triple-provider + template: + metadata: + labels: + app: gateway-higress-triple-provider + spec: + containers: + - name: gateway-higress-triple-provider + image: docker.io/allenyi/higress-triple:2.0.0 + imagePullPolicy: IfNotPresent + ports: + # 与容器暴露的端口一致 + - containerPort: 50052 + env: + # 配置Nacos注册中心地址,对应Dubbo服务配置中的${nacos.address:127.0.0.1} + - name: NACOS_ADDRESS + value: nacos-server.default.svc.cluster.local +``` + +#### 通过 Higress 转发请求到 Dubbo 服务 + +Higress 可以通过 McpBridge 来对接 Nacos 作为服务来源,在 K8s 集群中 apply 以下资源来配置 McpBridge: + +```shell +kubectl apply -f https://raw.githubusercontent.com/apache/dubbo-samples/master/2-advanced/dubbo-samples-gateway/dubbo-samples-gateway-higress/dubbo-samples-gateway-higress-triple/deploy/mcp/mcpbridge.yaml +``` + +以上安装的 McpBridge 资源的具体定义如下: + +```yaml +apiVersion: networking.higress.io/v1 +kind: McpBridge +metadata: + name: nacos-service-resource + namespace: higress-system +spec: + registries: + - domain: nacos-server.default.svc.cluster.local + nacosGroups: + - DEFAULT_GROUP + name: nacos-service-resource + port: 8848 + type: nacos2 +``` + +> 更多详细配置参考[McpBridge配置说明](https://higress.io/zh-cn/docs/user/mcp-bridge) + + +接下来我们创建如下 Ingress,从而创建一条指向 Dubbo 服务的 HTTP 路由: + +```shell +kubectl apply -f https://raw.githubusercontent.com/apache/dubbo-samples/master/2-advanced/dubbo-samples-gateway/dubbo-samples-gateway-higress/dubbo-samples-gateway-higress-triple/deploy/ingress/Ingress.yaml +``` + +这样,path 前缀为 `/org.apache.dubbo.samples.gateway.api.DemoService` 的请求就会被路由到我们刚刚创建的 Dubbo 服务上。 + +以上 apply 安装的具体资源定义如下: + +```yaml +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + annotations: + higress.io/destination: gateway-higress-triple-provider.DEFAULT-GROUP.public.nacos + name: demo + namespace: default #与应用部署namespace保持一致 +spec: + ingressClassName: higress + rules: + - http: + paths: + - backend: + resource: + apiGroup: networking.higress.io + kind: McpBridge + name: default + path: /org.apache.dubbo.samples.gateway.api.DemoService + pathType: Prefix +``` + +注意这里通过注解 higress.io/destination 指定路由最终要转发到的目标服务: `gateway-higress-triple-provider`,gateway-higress-triple-provider 为刚刚启动 Dubbo 服务的应用名(这里依赖 Dubbo3 默认注册的应用粒度地址列表)。 + +对于 Nacos 来源的服务,这里的目标服务格式为:“服务名称.服务分组.命名空间ID.nacos”,注意这里需要遵循 DNS 域名格式,因此服务分组中的下划线'_'被转换成了横杠'-'。命名空间未指定时,这里默认值为"public"。 + +> 更多流量治理相关配置参考[Ingress Annotation 配置说明](https://higress.io/zh-cn/docs/user/annotation)和[通过Ingress Annotation实现高阶流量治理](https://higress.io/zh-cn/docs/user/annotation-use-case) + +### 请求验证 + +通过 cURL 访问 Higress,可以实现对 triple 后端服务的调用: + +```shell +$ curl "localhost/org.apache.dubbo.samples.gateway.api.DemoService/sayHello?name=HigressTriple" + +"Hello HigressTriple" +``` + +{{% alert title="注意" color="info" %}} +这里要运行 `kubectl port-forward service/higress-gateway -n higress-system 80:80 443:443` 将集群内的 Higress 暴露出来才可访问。 +{{% /alert %}} + +`/org.apache.dubbo.samples.gateway.api.DemoService/sayHello/` 这种根据 Java 路径名与方法直接暴露的访问路径,虽然可以很容易调通,但对于前端来说并不友好。接下来我们一起看一下如何发布 REST 风格的 HTTP 服务。 + +## REST 风格接口 + +在前面的示例中,如类似 `http://127.0.0.1:9080/triple/demo/hello` 会是更符合前端使用的访问方式,要做到这一点,我们可以通过在 Higress 等网关配置 uri rewrite 重写,实现前端 `/triple/demo/hello` 到后端 `/org.apache.dubbo.samples.gateway.api.DemoService/sayHello/` 的映射。 + +除了配置网关 rewrite 重新规则之外,**Dubbo 框架还为 triple 服务暴露 REST 风格的 HTTP 访问路径提供了内置支持**,具体使用方式取决于你使用的是基于 [protobuf 的服务定义模式](/zh-cn/overview/mannual/java-sdk/tasks/protocols/triple/idl/),还是基于 [java 接口的服务定义模式](/zh-cn/overview/mannual/java-sdk/tasks/protocols/triple/interface/): +* Java 接口模式,通过直接为 java 接口增加注解可以同时发布 REST 风格服务,目前支持 Spring Web 与 JAX-RS 两套注解标准。 +* Protobuf 模式,通过使用 grpc-gateway 可发布 REST 风格服务。 + +### 为服务定义增加注解 +通过为 Java 接口增加以下任意一种注解,即可发布 triple 二进制、REST 风格的服务。这样配置之后,对于同一个服务,你既可以使用标准二进制 triple 格式访问服务,也可以使用 REST HTTP 方式以 JSON 格式访问服务。 + +Spring Web 风格注解: +```java +@RequestMapping("/triple/demo") +public interface DemoService { + + @RequestMapping(method = RequestMethod.GET, value = "/hello") + String sayHello(@RequestParam("name") String name); + +} +``` + +{{% alert title="注意" color="info" %}} +关于接口注解 +* 在之前的示例 [dubbo-samples-gateway-higress-triple](https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-gateway/dubbo-samples-gateway-higress/dubbo-samples-gateway-higress-triple) 中已经启用,可查看源码了解实际用法。 +* 在[【进阶学习 - 协议 - rest】](/zh-cn/overview/mannual/java-sdk/tasks/protocols/rest/)一节中有详细的说明和使用示例,也可以前往查看。 +{{% /alert %}} + +这时我们的路由前缀配置如下,Nacos 地址配置与之前保持一致,path 前缀改为访问更为友好的 `/triple/demo`: + +```yaml +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + annotations: + higress.io/destination: gateway-higress-triple-provider.DEFAULT-GROUP.public.nacos + name: demo + namespace: default +spec: + ingressClassName: higress + rules: + - http: + paths: + - backend: + resource: + apiGroup: networking.higress.io + kind: McpBridge + name: default + path: /triple/demo + pathType: Prefix +``` + +可以使用 `/triple/demo/hello` 访问服务: + +```shell +$ curl "localhost/triple/demo/hello?name=HigressTriple" + +"Hello HigressTriple" +``` + +{{% alert title="注意" color="info" %}} +本文描述内容,仅适用于 Dubbo 3.3.0 之后发布的 triple 协议版本。 +{{% /alert %}} + +## 参考连接 +* [使用 Apache APISIX 代理 triple 协议流量](/zh-cn/blog/2024/04/22/使用-apache-apisix-代理-dubbo-服务triple协议/) +* [Higress 实现基于 http 协议微服务发现与路由配置](https://higress.io/zh-cn/docs/user/spring-cloud) \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/mesh/_index.md b/content/zh-cn/overview/mannual/java-sdk/tasks/mesh/_index.md new file mode 100755 index 000000000000..ccce599fb53b --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/mesh/_index.md @@ -0,0 +1,44 @@ +--- +aliases: + - /zh/overview/tasks/mesh/ + - /zh-cn/overview/tasks/mesh/ +description: '演示多种部署形态的 Dubbo Mesh 解决方案,以及 Dubbo Mesh 如何帮助用户实现架构的平滑迁移。 ' +linkTitle: 服务网格 +no_list: true +title: 服务网格 +toc_hide: true +type: docs +weight: 70 +--- + + + +{{< blocks/section color="white" height="auto">}} +

+
+
+
+
+

+ Istio & Envoy 示例 +

+

演示 Dubbo 服务接入基于 Envoy 代理的 Istio 服务网格体系。

+
+
+
+
+
+
+

+ Istio & Proxyless 示例 +

+

演示 Dubbo Proxyless 接入 Istio 服务网格体系。

+
+
+
+
+
+
+ +{{< /blocks/section >}} diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/mesh/bookinfo-proxyless/_index.md b/content/zh-cn/overview/mannual/java-sdk/tasks/mesh/bookinfo-proxyless/_index.md new file mode 100755 index 000000000000..7b5fde9e4b20 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/mesh/bookinfo-proxyless/_index.md @@ -0,0 +1,48 @@ +--- +aliases: + - /zh/overview/tasks/mesh/bookinfo-proxyless/ + - /zh-cn/overview/tasks/mesh/bookinfo-proxyless/ +description: 通过完整的 Bookinfo 示例操作演示 Dubbo Proxyless 接入 Istio 服务网格体系。 +linkTitle: Proxyless Bookinfo +no_list: true +title: Proxyless Bookinfo 示例 +type: docs +weight: 70 +--- + + + +通过完整的 Bookinfo 示例操作演示 Dubbo 服务接入基于 Envoy 代理的 Istio 服务网格体系。 + +{{< blocks/section color="white" height="auto">}} +{{< /blocks/section >}} + +{{< blocks/section color="white" height="auto">}} +
+
+
+
+
+

+ Traffic Management +

+

Tasks that demonstrates how to use Istio's traffic routing features.

+
+
+
+
+
+
+

+ Security +

+

Demonstrates how to secure Dubbo proxyless mesh.

+
+
+
+
+
+
+ +{{< /blocks/section >}} diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/mesh/bookinfo-proxyless/security/_index.md b/content/zh-cn/overview/mannual/java-sdk/tasks/mesh/bookinfo-proxyless/security/_index.md new file mode 100755 index 000000000000..c289f9e83829 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/mesh/bookinfo-proxyless/security/_index.md @@ -0,0 +1,92 @@ +--- +aliases: + - /zh/overview/tasks/mesh/bookinfo-proxyless/security/ + - /zh-cn/overview/tasks/mesh/bookinfo-proxyless/security/ +description: Envoy Security Bookinfo 示例。 +linkTitle: security +no_list: true +title: Envoy Bookinfo 认证鉴权示例 +type: docs +weight: 20 +--- + + + +通过完整的 Bookinfo 示例操作演示 Dubbo 服务接入基于 Envoy 代理的 Istio 服务网格体系,如何配置认证鉴权体系。 + +{{< blocks/section color="white" height="auto">}} +{{< /blocks/section >}} + +{{< blocks/section color="white" height="auto">}} +
+
+
+
+
+

+ Request Routing +

+

This task shows you how to configure dynamic request routing to multiple versions of a microservice.

+
+
+
+
+
+
+

+ Traffic Shifting +

+

Shows you how to migrate traffic from an old to new version of a service.

+
+
+
+
+
+
+

+ TCP Traffic Shifting +

Shows you how to migrate TCP traffic from an old to new version of a TCP service.

+

+

+
+
+
+
+
+
+

+ Request Timeouts +

This task shows you how to set up request timeouts in Envoy using Istio.

+

+

+
+
+
+
+
+
+

+ Mirroring +

This task demonstrates the traffic mirroring/shadowing capabilities of Istio.

+

+

+
+
+
+
+
+
+

+ Locality Load Balancing +

This series of tasks demonstrate how to configure locality load balancing in Istio.

+

+

+
+
+
+
+
+
+ +{{< /blocks/section >}} diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/mesh/bookinfo-proxyless/security/request-routing.md b/content/zh-cn/overview/mannual/java-sdk/tasks/mesh/bookinfo-proxyless/security/request-routing.md new file mode 100644 index 000000000000..331e4113dee0 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/mesh/bookinfo-proxyless/security/request-routing.md @@ -0,0 +1,152 @@ +--- +aliases: + - /zh/overview/tasks/mesh/bookinfo-proxyless/security/request-routing/ + - /zh-cn/overview/tasks/mesh/bookinfo-proxyless/security/request-routing/ +description: This task shows you how to route requests dynamically to multiple versions of a microservice. +linkTitle: Request Routing +title: Request Routing +toc_hide: true +type: docs +weight: 1 +--- + + + +Before you begin +Setup Istio by following the instructions in the Installation guide. + +Deploy the Bookinfo sample application. + +Review the Traffic Management concepts doc. + +About this task +The Istio Bookinfo sample consists of four separate microservices, each with multiple versions. Three different versions of one of the microservices, reviews, have been deployed and are running concurrently. To illustrate the problem this causes, access the Bookinfo app’s /productpage in a browser and refresh several times. The URL is http://$GATEWAY_URL/productpage, where $GATEWAY_URL is the External IP address of the ingress, as explained in the Bookinfo doc. + +You’ll notice that sometimes the book review output contains star ratings and other times it does not. This is because without an explicit default service version to route to, Istio routes requests to all available versions in a round robin fashion. + +The initial goal of this task is to apply rules that route all traffic to v1 (version 1) of the microservices. Later, you will apply a rule to route traffic based on the value of an HTTP request header. + +Route to version 1 +To route to one version only, you configure route rules that send traffic to default versions for the microservices. + +If you haven’t already, follow the instructions in define the service versions. +Run the following command to create the route rules: +Istio classicGateway API +Istio uses virtual services to define route rules. Run the following command to apply virtual services that will route all traffic to v1 of each microservice: + +$ kubectl apply -f @samples/bookinfo/networking/virtual-service-all-v1.yaml@ +Because configuration propagation is eventually consistent, wait a few seconds for the virtual services to take effect. + +Display the defined routes with the following command: +Istio classicGateway API +$ kubectl get virtualservices -o yaml +- apiVersion: networking.istio.io/v1beta1 + kind: VirtualService + ... + spec: + hosts: + - details + http: + - route: + - destination: + host: details + subset: v1 +- apiVersion: networking.istio.io/v1beta1 + kind: VirtualService + ... + spec: + hosts: + - productpage + http: + - route: + - destination: + host: productpage + subset: v1 +- apiVersion: networking.istio.io/v1beta1 + kind: VirtualService + ... + spec: + hosts: + - ratings + http: + - route: + - destination: + host: ratings + subset: v1 +- apiVersion: networking.istio.io/v1beta1 + kind: VirtualService + ... + spec: + hosts: + - reviews + http: + - route: + - destination: + host: reviews + subset: v1 +You can also display the corresponding subset definitions with the following command: + +$ kubectl get destinationrules -o yaml +You have configured Istio to route to the v1 version of the Bookinfo microservices, most importantly the reviews service version 1. + +Test the new routing configuration +You can easily test the new configuration by once again refreshing the /productpage of the Bookinfo app in your browser. Notice that the reviews part of the page displays with no rating stars, no matter how many times you refresh. This is because you configured Istio to route all traffic for the reviews service to the version reviews:v1 and this version of the service does not access the star ratings service. + +You have successfully accomplished the first part of this task: route traffic to one version of a service. + +Route based on user identity +Next, you will change the route configuration so that all traffic from a specific user is routed to a specific service version. In this case, all traffic from a user named Jason will be routed to the service reviews:v2. + +This example is enabled by the fact that the productpage service adds a custom end-user header to all outbound HTTP requests to the reviews service. + +Istio also supports routing based on strongly authenticated JWT on ingress gateway, refer to the JWT claim based routing for more details. + +Remember, reviews:v2 is the version that includes the star ratings feature. + +Run the following command to enable user-based routing: +Istio classicGateway API +$ kubectl apply -f @samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml@ +You can confirm the rule is created using the following command: + +$ kubectl get virtualservice reviews -o yaml +apiVersion: networking.istio.io/v1beta1 +kind: VirtualService +... +spec: + hosts: + - reviews + http: + - match: + - headers: + end-user: + exact: jason + route: + - destination: + host: reviews + subset: v2 + - route: + - destination: + host: reviews + subset: v1 +On the /productpage of the Bookinfo app, log in as user jason. + +Refresh the browser. What do you see? The star ratings appear next to each review. + +Log in as another user (pick any name you wish). + +Refresh the browser. Now the stars are gone. This is because traffic is routed to reviews:v1 for all users except Jason. + +You have successfully configured Istio to route traffic based on user identity. + +Understanding what happened +In this task, you used Istio to send 100% of the traffic to the v1 version of each of the Bookinfo services. You then set a rule to selectively send traffic to version v2 of the reviews service based on a custom end-user header added to the request by the productpage service. + +Note that Kubernetes services, like the Bookinfo ones used in this task, must adhere to certain restrictions to take advantage of Istio’s L7 routing features. Refer to the Requirements for Pods and Services for details. + +In the traffic shifting task, you will follow the same basic pattern you learned here to configure route rules to gradually send traffic from one version of a service to another. + +Cleanup +Remove the application route rules: +Istio classicGateway API +$ kubectl delete -f @samples/bookinfo/networking/virtual-service-all-v1.yaml@ +If you are not planning to explore any follow-on tasks, refer to the Bookinfo cleanup instructions to shutdown the application. diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/mesh/bookinfo-proxyless/traffic/_index.md b/content/zh-cn/overview/mannual/java-sdk/tasks/mesh/bookinfo-proxyless/traffic/_index.md new file mode 100755 index 000000000000..6eca306ef193 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/mesh/bookinfo-proxyless/traffic/_index.md @@ -0,0 +1,92 @@ +--- +aliases: + - /zh/overview/tasks/mesh/bookinfo-proxyless/traffic/ + - /zh-cn/overview/tasks/mesh/bookinfo-proxyless/traffic/ +description: Envoy Traffic Management Bookinfo 示例。 +linkTitle: Traffic Management +no_list: true +title: Envoy Bookinfo 流量管控示例 +type: docs +weight: 10 +--- + + + +通过完整的 Bookinfo 示例操作演示 Dubbo 服务接入基于 Envoy 代理的 Istio 服务网格体系,如何进行流量管理。 + +{{< blocks/section color="white" height="auto">}} +{{< /blocks/section >}} + +{{< blocks/section color="white" height="auto">}} +
+
+
+
+
+

+ Request Routing +

+

This task shows you how to configure dynamic request routing to multiple versions of a microservice.

+
+
+
+
+
+
+

+ Traffic Shifting +

+

Shows you how to migrate traffic from an old to new version of a service.

+
+
+
+
+
+
+

+ TCP Traffic Shifting +

Shows you how to migrate TCP traffic from an old to new version of a TCP service.

+

+

+
+
+
+
+
+
+

+ Request Timeouts +

This task shows you how to set up request timeouts in Envoy using Istio.

+

+

+
+
+
+
+
+
+

+ Mirroring +

This task demonstrates the traffic mirroring/shadowing capabilities of Istio.

+

+

+
+
+
+
+
+
+

+ Locality Load Balancing +

This series of tasks demonstrate how to configure locality load balancing in Istio.

+

+

+
+
+
+
+
+
+ +{{< /blocks/section >}} diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/mesh/bookinfo-proxyless/traffic/request-routing.md b/content/zh-cn/overview/mannual/java-sdk/tasks/mesh/bookinfo-proxyless/traffic/request-routing.md new file mode 100644 index 000000000000..0dbdd0fd657f --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/mesh/bookinfo-proxyless/traffic/request-routing.md @@ -0,0 +1,152 @@ +--- +aliases: + - /zh/overview/tasks/mesh/bookinfo-proxyless/traffic/request-routing/ + - /zh-cn/overview/tasks/mesh/bookinfo-proxyless/traffic/request-routing/ +description: This task shows you how to route requests dynamically to multiple versions of a microservice. +linkTitle: Request Routing +title: Request Routing +toc_hide: true +type: docs +weight: 1 +--- + + + +Before you begin +Setup Istio by following the instructions in the Installation guide. + +Deploy the Bookinfo sample application. + +Review the Traffic Management concepts doc. + +About this task +The Istio Bookinfo sample consists of four separate microservices, each with multiple versions. Three different versions of one of the microservices, reviews, have been deployed and are running concurrently. To illustrate the problem this causes, access the Bookinfo app’s /productpage in a browser and refresh several times. The URL is http://$GATEWAY_URL/productpage, where $GATEWAY_URL is the External IP address of the ingress, as explained in the Bookinfo doc. + +You’ll notice that sometimes the book review output contains star ratings and other times it does not. This is because without an explicit default service version to route to, Istio routes requests to all available versions in a round robin fashion. + +The initial goal of this task is to apply rules that route all traffic to v1 (version 1) of the microservices. Later, you will apply a rule to route traffic based on the value of an HTTP request header. + +Route to version 1 +To route to one version only, you configure route rules that send traffic to default versions for the microservices. + +If you haven’t already, follow the instructions in define the service versions. +Run the following command to create the route rules: +Istio classicGateway API +Istio uses virtual services to define route rules. Run the following command to apply virtual services that will route all traffic to v1 of each microservice: + +$ kubectl apply -f @samples/bookinfo/networking/virtual-service-all-v1.yaml@ +Because configuration propagation is eventually consistent, wait a few seconds for the virtual services to take effect. + +Display the defined routes with the following command: +Istio classicGateway API +$ kubectl get virtualservices -o yaml +- apiVersion: networking.istio.io/v1beta1 + kind: VirtualService + ... + spec: + hosts: + - details + http: + - route: + - destination: + host: details + subset: v1 +- apiVersion: networking.istio.io/v1beta1 + kind: VirtualService + ... + spec: + hosts: + - productpage + http: + - route: + - destination: + host: productpage + subset: v1 +- apiVersion: networking.istio.io/v1beta1 + kind: VirtualService + ... + spec: + hosts: + - ratings + http: + - route: + - destination: + host: ratings + subset: v1 +- apiVersion: networking.istio.io/v1beta1 + kind: VirtualService + ... + spec: + hosts: + - reviews + http: + - route: + - destination: + host: reviews + subset: v1 +You can also display the corresponding subset definitions with the following command: + +$ kubectl get destinationrules -o yaml +You have configured Istio to route to the v1 version of the Bookinfo microservices, most importantly the reviews service version 1. + +Test the new routing configuration +You can easily test the new configuration by once again refreshing the /productpage of the Bookinfo app in your browser. Notice that the reviews part of the page displays with no rating stars, no matter how many times you refresh. This is because you configured Istio to route all traffic for the reviews service to the version reviews:v1 and this version of the service does not access the star ratings service. + +You have successfully accomplished the first part of this task: route traffic to one version of a service. + +Route based on user identity +Next, you will change the route configuration so that all traffic from a specific user is routed to a specific service version. In this case, all traffic from a user named Jason will be routed to the service reviews:v2. + +This example is enabled by the fact that the productpage service adds a custom end-user header to all outbound HTTP requests to the reviews service. + +Istio also supports routing based on strongly authenticated JWT on ingress gateway, refer to the JWT claim based routing for more details. + +Remember, reviews:v2 is the version that includes the star ratings feature. + +Run the following command to enable user-based routing: +Istio classicGateway API +$ kubectl apply -f @samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml@ +You can confirm the rule is created using the following command: + +$ kubectl get virtualservice reviews -o yaml +apiVersion: networking.istio.io/v1beta1 +kind: VirtualService +... +spec: + hosts: + - reviews + http: + - match: + - headers: + end-user: + exact: jason + route: + - destination: + host: reviews + subset: v2 + - route: + - destination: + host: reviews + subset: v1 +On the /productpage of the Bookinfo app, log in as user jason. + +Refresh the browser. What do you see? The star ratings appear next to each review. + +Log in as another user (pick any name you wish). + +Refresh the browser. Now the stars are gone. This is because traffic is routed to reviews:v1 for all users except Jason. + +You have successfully configured Istio to route traffic based on user identity. + +Understanding what happened +In this task, you used Istio to send 100% of the traffic to the v1 version of each of the Bookinfo services. You then set a rule to selectively send traffic to version v2 of the reviews service based on a custom end-user header added to the request by the productpage service. + +Note that Kubernetes services, like the Bookinfo ones used in this task, must adhere to certain restrictions to take advantage of Istio’s L7 routing features. Refer to the Requirements for Pods and Services for details. + +In the traffic shifting task, you will follow the same basic pattern you learned here to configure route rules to gradually send traffic from one version of a service to another. + +Cleanup +Remove the application route rules: +Istio classicGateway API +$ kubectl delete -f @samples/bookinfo/networking/virtual-service-all-v1.yaml@ +If you are not planning to explore any follow-on tasks, refer to the Bookinfo cleanup instructions to shutdown the application. diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/mesh/bookinfo-sidecar/_index.md b/content/zh-cn/overview/mannual/java-sdk/tasks/mesh/bookinfo-sidecar/_index.md new file mode 100755 index 000000000000..5d1be6f6d536 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/mesh/bookinfo-sidecar/_index.md @@ -0,0 +1,48 @@ +--- +aliases: + - /zh/overview/tasks/mesh/bookinfo-sidecar/ + - /zh-cn/overview/tasks/mesh/bookinfo-sidecar/ +description: 通过完整的 Bookinfo 示例操作演示 Dubbo 服务接入基于 Envoy 代理的 Istio 服务网格体系。 +linkTitle: Envoy Bookinfo +no_list: true +title: Envoy Bookinfo 示例 +type: docs +weight: 70 +--- + + + +通过完整的 Bookinfo 示例操作演示 Dubbo 服务接入基于 Envoy 代理的 Istio 服务网格体系。 + +{{< blocks/section color="white" height="auto">}} +{{< /blocks/section >}} + +{{< blocks/section color="white" height="auto">}} +
+
+
+
+
+

+ Traffic Management +

+

Tasks that demonstrates how to use Istio's traffic routing features.

+
+
+
+
+
+
+

+ Security +

+

Demonstrates how to secure Dubbo mesh.

+
+
+
+
+
+
+ +{{< /blocks/section >}} diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/mesh/bookinfo-sidecar/security/_index.md b/content/zh-cn/overview/mannual/java-sdk/tasks/mesh/bookinfo-sidecar/security/_index.md new file mode 100755 index 000000000000..a3f7360997dd --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/mesh/bookinfo-sidecar/security/_index.md @@ -0,0 +1,92 @@ +--- +aliases: + - /zh/overview/tasks/mesh/bookinfo-sidecar/security/ + - /zh-cn/overview/tasks/mesh/bookinfo-sidecar/security/ +description: Envoy Security Bookinfo 示例。 +linkTitle: security +no_list: true +title: Envoy Bookinfo 认证鉴权示例 +type: docs +weight: 20 +--- + + + +通过完整的 Bookinfo 示例操作演示 Dubbo 服务接入基于 Envoy 代理的 Istio 服务网格体系,如何配置认证鉴权体系。 + +{{< blocks/section color="white" height="auto">}} +{{< /blocks/section >}} + +{{< blocks/section color="white" height="auto">}} +
+
+
+
+
+

+ Request Routing +

+

This task shows you how to configure dynamic request routing to multiple versions of a microservice.

+
+
+
+
+
+
+

+ Traffic Shifting +

+

Shows you how to migrate traffic from an old to new version of a service.

+
+
+
+
+
+
+

+ TCP Traffic Shifting +

Shows you how to migrate TCP traffic from an old to new version of a TCP service.

+

+

+
+
+
+
+
+
+

+ Request Timeouts +

This task shows you how to set up request timeouts in Envoy using Istio.

+

+

+
+
+
+
+
+
+

+ Mirroring +

This task demonstrates the traffic mirroring/shadowing capabilities of Istio.

+

+

+
+
+
+
+
+
+

+ Locality Load Balancing +

This series of tasks demonstrate how to configure locality load balancing in Istio.

+

+

+
+
+
+
+
+
+ +{{< /blocks/section >}} diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/mesh/bookinfo-sidecar/security/request-routing.md b/content/zh-cn/overview/mannual/java-sdk/tasks/mesh/bookinfo-sidecar/security/request-routing.md new file mode 100644 index 000000000000..1fe3ef2259e6 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/mesh/bookinfo-sidecar/security/request-routing.md @@ -0,0 +1,152 @@ +--- +aliases: + - /zh/overview/tasks/mesh/bookinfo-sidecar/security/request-routing/ + - /zh-cn/overview/tasks/mesh/bookinfo-sidecar/security/request-routing/ +description: This task shows you how to route requests dynamically to multiple versions of a microservice. +linkTitle: Request Routing +title: Request Routing +toc_hide: true +type: docs +weight: 1 +--- + + + +Before you begin +Setup Istio by following the instructions in the Installation guide. + +Deploy the Bookinfo sample application. + +Review the Traffic Management concepts doc. + +About this task +The Istio Bookinfo sample consists of four separate microservices, each with multiple versions. Three different versions of one of the microservices, reviews, have been deployed and are running concurrently. To illustrate the problem this causes, access the Bookinfo app’s /productpage in a browser and refresh several times. The URL is http://$GATEWAY_URL/productpage, where $GATEWAY_URL is the External IP address of the ingress, as explained in the Bookinfo doc. + +You’ll notice that sometimes the book review output contains star ratings and other times it does not. This is because without an explicit default service version to route to, Istio routes requests to all available versions in a round robin fashion. + +The initial goal of this task is to apply rules that route all traffic to v1 (version 1) of the microservices. Later, you will apply a rule to route traffic based on the value of an HTTP request header. + +Route to version 1 +To route to one version only, you configure route rules that send traffic to default versions for the microservices. + +If you haven’t already, follow the instructions in define the service versions. +Run the following command to create the route rules: +Istio classicGateway API +Istio uses virtual services to define route rules. Run the following command to apply virtual services that will route all traffic to v1 of each microservice: + +$ kubectl apply -f @samples/bookinfo/networking/virtual-service-all-v1.yaml@ +Because configuration propagation is eventually consistent, wait a few seconds for the virtual services to take effect. + +Display the defined routes with the following command: +Istio classicGateway API +$ kubectl get virtualservices -o yaml +- apiVersion: networking.istio.io/v1beta1 + kind: VirtualService + ... + spec: + hosts: + - details + http: + - route: + - destination: + host: details + subset: v1 +- apiVersion: networking.istio.io/v1beta1 + kind: VirtualService + ... + spec: + hosts: + - productpage + http: + - route: + - destination: + host: productpage + subset: v1 +- apiVersion: networking.istio.io/v1beta1 + kind: VirtualService + ... + spec: + hosts: + - ratings + http: + - route: + - destination: + host: ratings + subset: v1 +- apiVersion: networking.istio.io/v1beta1 + kind: VirtualService + ... + spec: + hosts: + - reviews + http: + - route: + - destination: + host: reviews + subset: v1 +You can also display the corresponding subset definitions with the following command: + +$ kubectl get destinationrules -o yaml +You have configured Istio to route to the v1 version of the Bookinfo microservices, most importantly the reviews service version 1. + +Test the new routing configuration +You can easily test the new configuration by once again refreshing the /productpage of the Bookinfo app in your browser. Notice that the reviews part of the page displays with no rating stars, no matter how many times you refresh. This is because you configured Istio to route all traffic for the reviews service to the version reviews:v1 and this version of the service does not access the star ratings service. + +You have successfully accomplished the first part of this task: route traffic to one version of a service. + +Route based on user identity +Next, you will change the route configuration so that all traffic from a specific user is routed to a specific service version. In this case, all traffic from a user named Jason will be routed to the service reviews:v2. + +This example is enabled by the fact that the productpage service adds a custom end-user header to all outbound HTTP requests to the reviews service. + +Istio also supports routing based on strongly authenticated JWT on ingress gateway, refer to the JWT claim based routing for more details. + +Remember, reviews:v2 is the version that includes the star ratings feature. + +Run the following command to enable user-based routing: +Istio classicGateway API +$ kubectl apply -f @samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml@ +You can confirm the rule is created using the following command: + +$ kubectl get virtualservice reviews -o yaml +apiVersion: networking.istio.io/v1beta1 +kind: VirtualService +... +spec: + hosts: + - reviews + http: + - match: + - headers: + end-user: + exact: jason + route: + - destination: + host: reviews + subset: v2 + - route: + - destination: + host: reviews + subset: v1 +On the /productpage of the Bookinfo app, log in as user jason. + +Refresh the browser. What do you see? The star ratings appear next to each review. + +Log in as another user (pick any name you wish). + +Refresh the browser. Now the stars are gone. This is because traffic is routed to reviews:v1 for all users except Jason. + +You have successfully configured Istio to route traffic based on user identity. + +Understanding what happened +In this task, you used Istio to send 100% of the traffic to the v1 version of each of the Bookinfo services. You then set a rule to selectively send traffic to version v2 of the reviews service based on a custom end-user header added to the request by the productpage service. + +Note that Kubernetes services, like the Bookinfo ones used in this task, must adhere to certain restrictions to take advantage of Istio’s L7 routing features. Refer to the Requirements for Pods and Services for details. + +In the traffic shifting task, you will follow the same basic pattern you learned here to configure route rules to gradually send traffic from one version of a service to another. + +Cleanup +Remove the application route rules: +Istio classicGateway API +$ kubectl delete -f @samples/bookinfo/networking/virtual-service-all-v1.yaml@ +If you are not planning to explore any follow-on tasks, refer to the Bookinfo cleanup instructions to shutdown the application. diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/mesh/bookinfo-sidecar/traffic/_index.md b/content/zh-cn/overview/mannual/java-sdk/tasks/mesh/bookinfo-sidecar/traffic/_index.md new file mode 100755 index 000000000000..0d89f84427f3 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/mesh/bookinfo-sidecar/traffic/_index.md @@ -0,0 +1,92 @@ +--- +aliases: + - /zh/overview/tasks/mesh/bookinfo-sidecar/traffic/ + - /zh-cn/overview/tasks/mesh/bookinfo-sidecar/traffic/ +description: Envoy Traffic Management Bookinfo 示例。 +linkTitle: Traffic Management +no_list: true +title: Envoy Bookinfo 流量管控示例 +type: docs +weight: 10 +--- + + + +通过完整的 Bookinfo 示例操作演示 Dubbo 服务接入基于 Envoy 代理的 Istio 服务网格体系,如何进行流量管理。 + +{{< blocks/section color="white" height="auto">}} +{{< /blocks/section >}} + +{{< blocks/section color="white" height="auto">}} +
+
+
+
+
+

+ Request Routing +

+

This task shows you how to configure dynamic request routing to multiple versions of a microservice.

+
+
+
+
+
+
+

+ Traffic Shifting +

+

Shows you how to migrate traffic from an old to new version of a service.

+
+
+
+
+
+
+

+ TCP Traffic Shifting +

Shows you how to migrate TCP traffic from an old to new version of a TCP service.

+

+

+
+
+
+
+
+
+

+ Request Timeouts +

This task shows you how to set up request timeouts in Envoy using Istio.

+

+

+
+
+
+
+
+
+

+ Mirroring +

This task demonstrates the traffic mirroring/shadowing capabilities of Istio.

+

+

+
+
+
+
+
+
+

+ Locality Load Balancing +

This series of tasks demonstrate how to configure locality load balancing in Istio.

+

+

+
+
+
+
+
+
+ +{{< /blocks/section >}} diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/mesh/bookinfo-sidecar/traffic/request-routing.md b/content/zh-cn/overview/mannual/java-sdk/tasks/mesh/bookinfo-sidecar/traffic/request-routing.md new file mode 100644 index 000000000000..c2e66be1380d --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/mesh/bookinfo-sidecar/traffic/request-routing.md @@ -0,0 +1,152 @@ +--- +aliases: + - /zh/overview/tasks/mesh/bookinfo-sidecar/traffic/request-routing/ + - /zh-cn/overview/tasks/mesh/bookinfo-sidecar/traffic/request-routing/ +description: This task shows you how to route requests dynamically to multiple versions of a microservice. +linkTitle: Request Routing +title: Request Routing +toc_hide: true +type: docs +weight: 1 +--- + + + +Before you begin +Setup Istio by following the instructions in the Installation guide. + +Deploy the Bookinfo sample application. + +Review the Traffic Management concepts doc. + +About this task +The Istio Bookinfo sample consists of four separate microservices, each with multiple versions. Three different versions of one of the microservices, reviews, have been deployed and are running concurrently. To illustrate the problem this causes, access the Bookinfo app’s /productpage in a browser and refresh several times. The URL is http://$GATEWAY_URL/productpage, where $GATEWAY_URL is the External IP address of the ingress, as explained in the Bookinfo doc. + +You’ll notice that sometimes the book review output contains star ratings and other times it does not. This is because without an explicit default service version to route to, Istio routes requests to all available versions in a round robin fashion. + +The initial goal of this task is to apply rules that route all traffic to v1 (version 1) of the microservices. Later, you will apply a rule to route traffic based on the value of an HTTP request header. + +Route to version 1 +To route to one version only, you configure route rules that send traffic to default versions for the microservices. + +If you haven’t already, follow the instructions in define the service versions. +Run the following command to create the route rules: +Istio classicGateway API +Istio uses virtual services to define route rules. Run the following command to apply virtual services that will route all traffic to v1 of each microservice: + +$ kubectl apply -f @samples/bookinfo/networking/virtual-service-all-v1.yaml@ +Because configuration propagation is eventually consistent, wait a few seconds for the virtual services to take effect. + +Display the defined routes with the following command: +Istio classicGateway API +$ kubectl get virtualservices -o yaml +- apiVersion: networking.istio.io/v1beta1 + kind: VirtualService + ... + spec: + hosts: + - details + http: + - route: + - destination: + host: details + subset: v1 +- apiVersion: networking.istio.io/v1beta1 + kind: VirtualService + ... + spec: + hosts: + - productpage + http: + - route: + - destination: + host: productpage + subset: v1 +- apiVersion: networking.istio.io/v1beta1 + kind: VirtualService + ... + spec: + hosts: + - ratings + http: + - route: + - destination: + host: ratings + subset: v1 +- apiVersion: networking.istio.io/v1beta1 + kind: VirtualService + ... + spec: + hosts: + - reviews + http: + - route: + - destination: + host: reviews + subset: v1 +You can also display the corresponding subset definitions with the following command: + +$ kubectl get destinationrules -o yaml +You have configured Istio to route to the v1 version of the Bookinfo microservices, most importantly the reviews service version 1. + +Test the new routing configuration +You can easily test the new configuration by once again refreshing the /productpage of the Bookinfo app in your browser. Notice that the reviews part of the page displays with no rating stars, no matter how many times you refresh. This is because you configured Istio to route all traffic for the reviews service to the version reviews:v1 and this version of the service does not access the star ratings service. + +You have successfully accomplished the first part of this task: route traffic to one version of a service. + +Route based on user identity +Next, you will change the route configuration so that all traffic from a specific user is routed to a specific service version. In this case, all traffic from a user named Jason will be routed to the service reviews:v2. + +This example is enabled by the fact that the productpage service adds a custom end-user header to all outbound HTTP requests to the reviews service. + +Istio also supports routing based on strongly authenticated JWT on ingress gateway, refer to the JWT claim based routing for more details. + +Remember, reviews:v2 is the version that includes the star ratings feature. + +Run the following command to enable user-based routing: +Istio classicGateway API +$ kubectl apply -f @samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml@ +You can confirm the rule is created using the following command: + +$ kubectl get virtualservice reviews -o yaml +apiVersion: networking.istio.io/v1beta1 +kind: VirtualService +... +spec: + hosts: + - reviews + http: + - match: + - headers: + end-user: + exact: jason + route: + - destination: + host: reviews + subset: v2 + - route: + - destination: + host: reviews + subset: v1 +On the /productpage of the Bookinfo app, log in as user jason. + +Refresh the browser. What do you see? The star ratings appear next to each review. + +Log in as another user (pick any name you wish). + +Refresh the browser. Now the stars are gone. This is because traffic is routed to reviews:v1 for all users except Jason. + +You have successfully configured Istio to route traffic based on user identity. + +Understanding what happened +In this task, you used Istio to send 100% of the traffic to the v1 version of each of the Bookinfo services. You then set a rule to selectively send traffic to version v2 of the reviews service based on a custom end-user header added to the request by the productpage service. + +Note that Kubernetes services, like the Bookinfo ones used in this task, must adhere to certain restrictions to take advantage of Istio’s L7 routing features. Refer to the Requirements for Pods and Services for details. + +In the traffic shifting task, you will follow the same basic pattern you learned here to configure route rules to gradually send traffic from one version of a service to another. + +Cleanup +Remove the application route rules: +Istio classicGateway API +$ kubectl delete -f @samples/bookinfo/networking/virtual-service-all-v1.yaml@ +If you are not planning to explore any follow-on tasks, refer to the Bookinfo cleanup instructions to shutdown the application. diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/mesh/migration/_index.md b/content/zh-cn/overview/mannual/java-sdk/tasks/mesh/migration/_index.md new file mode 100755 index 000000000000..ed0ca6513731 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/mesh/migration/_index.md @@ -0,0 +1,43 @@ +--- +aliases: + - /zh/overview/tasks/mesh/migration/ + - /zh-cn/overview/tasks/mesh/migration/ +description: 演示 Dubbo Mesh 如何帮助用户实现架构的平滑迁移。 +linkTitle: Dubbo2 平滑迁移 +no_list: true +title: 传统 Dubbo 微服务集群如何平滑迁移到 Istio 服务网格体系 +type: docs +weight: 70 +--- + + + +{{< blocks/section color="white" height="auto">}} +
+
+
+
+
+

+ 地址同步问题 +

+

如何解决地址同步问题?

+
+
+
+
+
+
+

+ 协议识别问题 +

+

如何解决 Dubbo2+hessian2 协议问题?

+
+
+
+
+
+
+ +{{< /blocks/section >}} diff --git a/content/zh-cn/overview/tasks/mesh/migration/deploy-on-k8s.md b/content/zh-cn/overview/mannual/java-sdk/tasks/mesh/migration/deploy-on-k8s.md similarity index 99% rename from content/zh-cn/overview/tasks/mesh/migration/deploy-on-k8s.md rename to content/zh-cn/overview/mannual/java-sdk/tasks/mesh/migration/deploy-on-k8s.md index aa88e33a51a4..1dd6ba058287 100644 --- a/content/zh-cn/overview/tasks/mesh/migration/deploy-on-k8s.md +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/mesh/migration/deploy-on-k8s.md @@ -1,6 +1,7 @@ --- aliases: - /zh/overview/tasks/mesh/migration/deploy-on-k8s/ + - /zh-cn/overview/tasks/mesh/migration/deploy-on-k8s/ description: 该示例演示了直接以 API-SERVER 为注册中心,将 Dubbo 应用部署到 Kubernetes 并复用 Kubernetes Native Service 的使用示例。 此示例的局限在于需要授予每个 Dubbo 应用访问 API-SERVER 特定资源的权限,同时直接访问和监听 API-SERVER 对中小集群来说并没有什么问题, 但对于较大规模集群而言可能给 API-SERVER 的稳定性带来一定的考验。除此之外,可以考虑配合 Dubbo 控制面将 Dubbo 应用部署到 Kuberntes 的方案, 该方案无需授予 Dubbo 应用访问 API-SERVER 的权限,也无需为 API-SERVER 引连接过多数据面造成的稳定性而担心。 linkTitle: 协议识别 title: 协议识别 @@ -319,4 +320,4 @@ spec: port: 22222 failureThreshold: 30 periodSeconds: 10 -``` \ No newline at end of file +``` diff --git a/content/zh-cn/overview/tasks/mesh/migration/dubbo-mesh.md b/content/zh-cn/overview/mannual/java-sdk/tasks/mesh/migration/dubbo-mesh.md similarity index 99% rename from content/zh-cn/overview/tasks/mesh/migration/dubbo-mesh.md rename to content/zh-cn/overview/mannual/java-sdk/tasks/mesh/migration/dubbo-mesh.md index 59f70ba2d555..2160c8358e30 100644 --- a/content/zh-cn/overview/tasks/mesh/migration/dubbo-mesh.md +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/mesh/migration/dubbo-mesh.md @@ -1,6 +1,7 @@ --- aliases: - /zh/overview/tasks/mesh/migration/dubbo-mesh/ + - /zh-cn/overview/tasks/mesh/migration/dubbo-mesh/ description: 本示例演示了如何使用 Istio+Envoy 的 Service Mesh 部署模式开发 Dubbo3 服务。Dubbo3 服务使用 Triple 作为通信协议,通信过程经过 Envoy 数据面拦截,同时使用标准 Istio 的流量治理能力治理 Dubbo。 linkTitle: 地址同步 title: 地址同步 @@ -298,4 +299,4 @@ xml方式 provider-port="20885" provided-by="istio-dubbo-producer" provider-namespace="istio-demo"/> -``` \ No newline at end of file +``` diff --git a/content/zh-cn/overview/tasks/mesh/migration/proxyless.md b/content/zh-cn/overview/mannual/java-sdk/tasks/mesh/migration/proxyless.md similarity index 99% rename from content/zh-cn/overview/tasks/mesh/migration/proxyless.md rename to content/zh-cn/overview/mannual/java-sdk/tasks/mesh/migration/proxyless.md index 657a2dab8892..d6a0b18d8584 100644 --- a/content/zh-cn/overview/tasks/mesh/migration/proxyless.md +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/mesh/migration/proxyless.md @@ -1,6 +1,7 @@ --- aliases: - /zh/overview/tasks/mesh/migration/proxyless/ + - /zh-cn/overview/tasks/mesh/migration/proxyless/ description: "" linkTitle: 其他问题? title: 其他问题? diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/observability/_index.md b/content/zh-cn/overview/mannual/java-sdk/tasks/observability/_index.md new file mode 100755 index 000000000000..e01bba132fd0 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/observability/_index.md @@ -0,0 +1,10 @@ +--- +aliases: + - /zh/overview/tasks/observability/ + - /zh-cn/overview/tasks/observability/ +description: 基于 Admin、Metrics、Grafana 等可视化的观测集群状态。 +linkTitle: 观测服务 +title: 观测服务 +type: docs +weight: 4 +--- diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/observability/console.md b/content/zh-cn/overview/mannual/java-sdk/tasks/observability/console.md new file mode 100755 index 000000000000..8cd477158c51 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/observability/console.md @@ -0,0 +1,112 @@ +--- +aliases: + - /zh/docs3-v2/java-sdk/advanced-features-and-usage/observability/ + - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/observability/ +description: 可观测性 +linkTitle: 控制台 +title: 可观测性 +type: docs +weight: 1 +--- + +管理 Dubbo 最直接的方式就是通过 Dubbo 控制面(即 dubbo-control-plane)提供的可视化界面,之前我们在[【快速开始 - 部署 Dubbo 应用】]()一文的最后,也有用到它查看服务启动后的状态。 + +**`dubbo-control-plane` 支持可视化的展示、监控集群状态,还支持实时下发流量管控规则。** + +## 安装控制台 +为了体验效果,我们首先需要安装 dubbo-control-plane,以下是在 Linux 环境下安装 dubbo-control-plane 的具体步骤: +1. 下载 & 解压 + ```shell + curl -L https://dubbo.apache.org/releases/downloadDubbo.sh | sh - + + cd dubbo-$version + export PATH=$PWD/bin:$PATH + ``` +2. 安装 + ```shell + dubbo-cp run --mode universal --config conf/dubbo.yml + ``` + 注意,`conf/dubbo.yml` 配置需要按需调整,指向你要连接的注册中心等后台服务,具体请查看 dubbo-control-plane 架构中依赖的后台服务。 +3. 访问 `http://xxx` 即可打开控制台页面。 + ![页面截图]() + +{{% alert title="注意" color="info" %}} +* 请查看文档了解 dubbo-control-plane 详细安装步骤,包括多个平台的安装方法与配置指导。 +* 对于 Kubernetes 环境下的 Dubbo 服务开发(包括 dubbo-control-plane 安装),我们有专门的章节说明,对于 Kubernetes 环境下的开发者可以去参考。 +{{% /alert %}} + +## 功能介绍 +Admin 控制台提供了从开发、测试到流量治理等不同层面的丰富功能,功能总体上可分为以下几类: +* 服务状态与依赖关系查询 +* 服务在线测试与文档管理 +* 集群状态监控 +* 实例诊断 +* 流量管控 + +### 服务状态与依赖关系查询 +服务状态查询以接口为维度展示 dubbo 集群信息,包含服务提供者、消费者信息和服务的元数据等。元数据包含了服务定义、方法名和参数列表等信息。Admin 支持最新版本 dubbo3 所提供的应用级发现模型,以统一的页面交互展示了应用级&接口级地址信息,并以特殊的标记对记录进行区分。 + +#### 基于服务名查询 +![img](/imgs/v3/tasks/observability/admin/1-search-by-service.png) + +#### 基于应用名查询 +![img](/imgs/v3/tasks/observability/admin/1-search-by-appname.png) + +#### 基于实例地址查询 +![img](/imgs/v3/tasks/observability/admin/1-search-by-ip.png) + +#### 服务实例详情 +![img](/imgs/v3/tasks/observability/admin/1-service-detail.png) + +### 服务在线测试与文档管理 +#### 服务测试 +服务测试相,主要用于模拟服务消费方,验证 Dubbo 服务的使用方式与正确性。 + +![img](/imgs/v3/tasks/observability/admin/2-service-test2.png) + +![img](/imgs/v3/tasks/observability/admin/2-service-test.png) + +#### 服务 Mock +服务Mock通过无代码嵌入的方式将Consumer对Provider的请求进行拦截,动态的对Consumer的请求进行放行或返回用户自定义的Mock数据。从而解决在前期开发过程中,Consumer所依赖的Provider未准备就绪时,造成Consumer开发方的阻塞问题。 +只需要以下两步,即可享受服务Mock功能带来的便捷: + +第一步: +Consumer应用引入服务Mock依赖,添加JVM启动参数-Denable.dubbo.admin.mock=true开启服务Mock功能。 +```xml + + org.apache.dubbo.extensions + dubbo-mock-admin + ${version} + +``` + +第二步:在Dubbo Admin中配置对应的Mock数据。 + +![img](/imgs/v3/tasks/observability/admin/2-service-mock.png) + +#### 服务文档管理 +Admin 提供的接口文档,相当于 swagger 对于 RESTful 风格的 Web 服务的作用。使用该功能可以有效的管理 Dubbo 接口文档。 + +![img](/imgs/v3/tasks/observability/admin/2-service-doc.png) + +### 集群状态监控 +#### 首页大盘 +TBD + +#### Grafana +![img](/imgs/v3/tasks/observability/admin/3-grafana.png) + +#### Tracing +![img](/imgs/v3/tasks/observability/admin/3-tracing-zipkin.png) + +### 流量管控 +Admin 提供了四种路由规则的可视化管理支持,分别是条件路由规则、标签路由规则、动态配置规则、脚本路由规则,所提供的功能可以轻松实现黑白名单、灰度环境隔离、多套测试环境、金丝雀发布等服务治理诉求。接下来以条件路由为例,可以可视化的创建条件路由规则。 + +#### 条件路由 + +条件路由可以编写一些自定义路由规则实现服务治理的需求比如同区域优先、参数路由、黑白名单、读写分离等。路由规则在发起一次RPC调用前起到过滤目标服务器地址的作用,过滤后的地址列表,将作为消费端最终发起RPC调用的备选地址。 + +![img](/imgs/v3/tasks/observability/admin/4-traffic-management.png) + +请参考 [流量管控任务](../../traffic-management/) 中关于如何进行路由规则配置的更多详细描述。 + diff --git a/content/zh-cn/overview/tasks/observability/grafana.md b/content/zh-cn/overview/mannual/java-sdk/tasks/observability/grafana.md similarity index 83% rename from content/zh-cn/overview/tasks/observability/grafana.md rename to content/zh-cn/overview/mannual/java-sdk/tasks/observability/grafana.md index 03136446d331..517ba25cba4c 100644 --- a/content/zh-cn/overview/tasks/observability/grafana.md +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/observability/grafana.md @@ -1,6 +1,7 @@ --- aliases: - /zh/overview/tasks/observability/grafana/ + - /zh-cn/overview/tasks/observability/grafana/ description: "" linkTitle: Grafana no_list: true @@ -13,8 +14,8 @@ weight: 3 ## 在您开始之前 - 一个可以访问的 Kubernetes 集群 -- 正确安装并配置 [普罗米修斯服务](../../../reference/integrations/prometheus) -- 安装 [Grafana](../../../reference/integrations/grafana) +- 正确安装并配置 [普罗米修斯服务](/zh-cn/overview/reference/integrations/prometheus/#安装) +- 安装 [Grafana](/zh-cn/overview/reference/integrations/grafana/) - 部署 [示例应用](https://github.com/apache/dubbo-samples/tree/master/4-governance/dubbo-samples-metrics-spring-boot) 并开启指标采集 ## 确认组件正常运行 @@ -36,6 +37,17 @@ NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE grafana ClusterIP 10.0.244.130 3000/TCP 180s ``` +## 部署示例 + +```yaml +kubectl apply -f https://raw.githubusercontent.com/apache/dubbo-samples/master/4-governance/dubbo-samples-metrics-spring-boot/Deployment.yml +``` + +等待示例应用正常运行,通过以下命令确认应用状态: +```yaml +kubectl -n dubbo-demo get deployments +``` + ## 查看 Grafana 可视化面板 示例程序启动后会自动模拟服务调用,只需等待一会能在 Grafana 中可视化的看到 Metrics 指标。 diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/observability/logging.md b/content/zh-cn/overview/mannual/java-sdk/tasks/observability/logging.md new file mode 100644 index 000000000000..b3f919c9862f --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/observability/logging.md @@ -0,0 +1,361 @@ +--- +aliases: + - /zh/docs3-v2/java-sdk/advanced-features-and-usage/observability/logging/ + - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/observability/logging/ +description: Dubbo 框架的日志配置, +hide_summary: true +linkTitle: 日志管理 +no_list: true +title: 日志管理 +type: docs +weight: 3 +--- + +## 支持的日志框架 +Dubbo 支持以下日志框架,用户可根据业务应用实际使用的日志框架进行配置。 + +| 第三方日志框架 | 优先级 | 说明 | +| ------------------------------------- | ------------------------------------------ | ------------------------------------------ | +| Log4j | 最高(默认就用这个) | log4j 的直接适配,需要增加 log4j-core、log4j-api 依赖与 log4j.properties | +| SLF4J | 次高(当前推荐) | 可支持 log4j、log4j2、logback 等实现。如 logback 可添加slf4j-api、logback-classic、logback-core 依赖与 logback.xml | +| Log4j2 | 次低 | log4j2 的直接适配,需要增加 log4j2-core 依赖与 log4j2.xml 配置 | +| Common Logging(jcl就是common logging) | 次低(Log4j和SLF4J在项目中均没有就用这个) | 较少项目使用 | +| JDK log | 最低(最后的选择) | 较少项目使用 | + +{{% alert title="注意" color="warning" %}} +无论使用哪种日志框架,除了 Dubbo 侧配置外,还需要确保应用中加入正确的日志框架依赖和配置文件。 +{{% /alert %}} + +### 使用 slf4j +对于 spring boot 用户,通过在 `application.yaml` 或 `application.properties` 增加以下配置,开启 slf4j 日志: + +```yaml +dubbo: + application: + logger: slf4j +``` + +```properties +dubbo.application.logger=slf4j +``` + +除此之外,还可以使用使用 JVM 参数进行设置: +```shell +java -Ddubbo.application.logger=slf4j +``` + +#### 使用 slf4j-log4j2 提供日志输出 + +增加依赖: + +```xml + + + org.slf4j + slf4j-api + 1.7.30 + + + + org.apache.logging.log4j + log4j-slf4j-impl + 2.14.1 + + + + org.apache.logging.log4j + log4j-core + 2.14.1 + + + + org.apache.logging.log4j + log4j-api + 2.14.1 + +``` + +配置一个name是"org.apache.dubbo"的logger就可以了,然后关联到对应的appender。如下: + +```xml + + + + + + %d{yyyy-MM-dd HH:mm:ss} [%t] %-5level %logger{36} - %msg%n + + + + + + + + + + +``` + +#### 使用 slf4j-logback 提供日志输出 + +增加依赖: + +```xml + + + org.slf4j + slf4j-api + 1.7.30 + + + + + ch.qos.logback + logback-classic + 1.2.3 + + + + ch.qos.logback + logback-core + 1.2.3 + +``` + +增加 logback 配置文件: + +```xml + + + + UTF-8 + ${LOG_HOME_DUBBO}/MTP-DUBBO.log + + ${LOG_HOME_DUBBO}/DEMO-%d{yyyy-MM-dd}.%i-DUBBO.zip + 30 + + 100MB + + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + true + + + + + +``` + + +### 使用 log4j +对于 spring boot 用户,通过在 `application.yaml` 或 `application.properties` 增加以下配置,开启 log4j 日志: +```yaml +dubbo: + application: + logger: log4j +``` + +使用 log4j2: +```yaml +dubbo: + application: + logger: log4j2 +``` + +## 访问日志-accesslog + +如果想记录每一次请求的详细信息,可开启访问日志,类似于 apache/tomcat server 的访问日志。 + +在 `application.yaml` 文件中,可以通过以下方式,开启访问日志,日志内容将输出到当前应用正在使用的日志框架(如 log4j、logback 等)。 +```yaml +dubbo: + provider: + accesslog: true +``` + +也可以指定访问日志输出到指定文件: + +```yaml +dubbo: + provider: + accesslog: /home/dubbo/foo/bar.log +``` + +{{% alert title="注意" color="warning" %}} +无论要动态开启或关闭访问日志,请参考 [流量管控](../../traffic-management/accesslog/) 一节的具体说明。 +{{% /alert %}} + +## 动态修改日志级别 +自 3.3 版本开始,Dubbo 框架支持通过 http 或 telnet 命令,在运行态动态修改日志配置(级别、框架等)。以下是使用示例,关于 telnet 命令的更多内容,可查看 [qos 命令指南](/zh-cn/overview/mannual/java-sdk/reference-manual/qos/qos-list/)。 + +1. 查询日志配置 + 命令:`loggerInfo` + + **示例** + ```bash + > telnet 127.0.0.1 22222 + > loggerInfo + ``` + + **输出** + ``` + Trying 127.0.0.1... + Connected to localhost. + Escape character is '^]'. + ___ __ __ ___ ___ ____ + / _ \ / / / // _ ) / _ ) / __ \ + / // // /_/ // _ |/ _ |/ /_/ / + /____/ \____//____//____/ \____/ + dubbo>loggerInfo + Available logger adapters: [jcl, jdk, log4j, slf4j]. Current Adapter: [log4j]. Log level: INFO + ``` + +2. 修改日志级别 + 命令:`switchLogLevel {level}` + + level: `ALL`, `TRACE`, `DEBUG`, `INFO`, `WARN`, `ERROR`, `OFF` + + **示例** + ```bash + > telnet 127.0.0.1 22222 + > switchLogLevel WARN + ``` + + **输出** + ``` + Trying 127.0.0.1... + Connected to localhost. + Escape character is '^]'. + ___ __ __ ___ ___ ____ + / _ \ / / / // _ ) / _ ) / __ \ + / // // /_/ // _ |/ _ |/ /_/ / + /____/ \____//____//____/ \____/ + dubbo>loggerInfo + Available logger adapters: [jcl, jdk, log4j, slf4j]. Current Adapter: [log4j]. Log level: INFO + dubbo>switchLogLevel WARN + OK + dubbo>loggerInfo + Available logger adapters: [jcl, jdk, log4j, slf4j]. Current Adapter: [log4j]. Log level: WARN``` + ``` + +3. 修改日志输出框架 + 命令:`switchLogger {loggerAdapterName}` + + loggerAdapterName: `slf4j`, `jcl`, `log4j`, `jdk`, `log4j2` + + **示例** + ```bash + > telnet 127.0.0.1 22222 + > switchLogger slf4j + ``` + + **输出** + ``` + Trying 127.0.0.1... + Connected to localhost. + Escape character is '^]'. + ___ __ __ ___ ___ ____ + / _ \ / / / // _ ) / _ ) / __ \ + / // // /_/ // _ |/ _ |/ /_/ / + /____/ \____//____//____/ \____/ + dubbo>loggerInfo + Available logger adapters: [jcl, slf4j, log4j, jdk]. Current Adapter: [log4j]. Log level: INFO + dubbo>switchLogger slf4j + OK + dubbo>loggerInfo + Available logger adapters: [jcl, slf4j, log4j, jdk]. Current Adapter: [slf4j]. Log level: INFO + ``` + +## 工作原理 + +在 Dubbo 框架内所有的日志输出都是通过 LoggerFactory 这个静态工厂类来获得 Logger 的对象实体,并且抽离了一个 LoggerAdapter 用于对接第三方日志框架,所以就有了JDKLoggerAdapter, Log4jLoggerAdapter, SLF4JLoggerAdapter等一些实现子类,分别对接了不同 Log 第三方实现。既然 Dubbo 能够支持这么多log实现,那么这些实现在 Dubbo 中优先级是在呢么样的呢?这里的优先级是指未配置指定的 logger 提供方的情况下,由 Dubbo 框架自己选择。 + +Dubbo 日志的调用方式,针对不同的日志打印系统,采用统一的 API 调用及输出,如: + +```java +/** + * ChannelListenerDispatcher + */ +public class ChannelHandlerDispatcher implements ChannelHandler { + + private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(ChannelHandlerDispatcher.class); +``` + +Dubbo 采用的日志输出方式是首先从 dubbo.application.logger 系统变量中获取属性值,来判断到底采用哪种日志输出方式,如果没设置则按照默认的加载顺序加载相应的日志输出类,直到成功加载: + +顺序为:log4jLogger > slf4jLogger > JclLogger > JdkLogger + +LoggerFactory 在类加载过程中变量的初始化过程: + +```java +// search common-used logging frameworks +static { + String logger = System.getProperty("dubbo.application.logger", ""); + switch (logger) { + case Slf4jLoggerAdapter.NAME: + setLoggerAdapter(new Slf4jLoggerAdapter()); + break; + case JclLoggerAdapter.NAME: + setLoggerAdapter(new JclLoggerAdapter()); + break; + case Log4jLoggerAdapter.NAME: + setLoggerAdapter(new Log4jLoggerAdapter()); + break; + case JdkLoggerAdapter.NAME: + setLoggerAdapter(new JdkLoggerAdapter()); + break; + case Log4j2LoggerAdapter.NAME: + setLoggerAdapter(new Log4j2LoggerAdapter()); + break; + default: + List> candidates = Arrays.asList( + Log4jLoggerAdapter.class, + Slf4jLoggerAdapter.class, + Log4j2LoggerAdapter.class, + JclLoggerAdapter.class, + JdkLoggerAdapter.class + ); + boolean found = false; + // try to use the first available adapter + for (Class clazz : candidates) { + try { + LoggerAdapter loggerAdapter = clazz.getConstructor().newInstance(); + loggerAdapter.getLogger(LoggerFactory.class); + if (loggerAdapter.isConfigured()) { + setLoggerAdapter(loggerAdapter); + found = true; + break; + } + } catch (Exception | LinkageError ignored) { + // ignore + } + } + if (found) { + break; + } + + System.err.println("Dubbo: Unable to find a proper configured logger to log out."); + for (Class clazz : candidates) { + try { + LoggerAdapter loggerAdapter = clazz.getConstructor().newInstance(); + loggerAdapter.getLogger(LoggerFactory.class); + setLoggerAdapter(loggerAdapter); + found = true; + break; + } catch (Throwable ignored) { + // ignore + } + } + if (found) { + System.err.println("Dubbo: Using default logger: " + loggerAdapter.getClass().getName() + ". " + + "If you cannot see any log, please configure -Ddubbo.application.logger property to your preferred logging framework."); + } else { + System.err.println("Dubbo: Unable to find any available logger adapter to log out. Dubbo logs will be ignored. " + + "Please configure -Ddubbo.application.logger property and add corresponding logging library to classpath."); + } + } +} +``` + +上面这段静态块是在LoggerFactory里面,说明只要LoggerFactory类一加载就会去选择对应的日志提供方。大家可能会发现对日志的提供方其实是可以通过配置来指定的,因为静态块一开始是从当前jvm环境中获取dubbo.application.logger,这个参数是同java -Ddubbo.application.logger=xxxx去指定的,如果是放在容器里面,就需要配置在容器启动的jvm参数里面。 diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/observability/prometheus.md b/content/zh-cn/overview/mannual/java-sdk/tasks/observability/prometheus.md new file mode 100644 index 000000000000..8c01c21322b6 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/observability/prometheus.md @@ -0,0 +1,52 @@ +--- +aliases: + - /zh/overview/tasks/observability/prometheus/ + - /zh-cn/overview/tasks/observability/prometheus/ +description: "" +linkTitle: Prometheus +no_list: true +title: 从 Prometheus 查询 Metrics 监控指标 +type: docs +weight: 2 +--- + +## 准备条件 + +本文演示如何在 Kubernetes 环境下部署 Prometheus 并实现对 Dubbo 集群的监控数据统计与查询,你需要完成或具备以下内容: + +* 本地或远端 Kubernetes 集群 +* 确保 [Prometheus 正确安装](/zh-cn/overview/reference/integrations/prometheus/#安装) +* 部署 [示例应用](https://github.com/apache/dubbo-samples/tree/master/4-governance/dubbo-samples-metrics-spring-boot) 并开启指标采集 +* 使用 Prometheus dashboard 查询数据指标 + +## 确保 Prometheus 正确运行 + +验证 Prometheus 已经正确部署 + +```yaml +kubectl -n dubbo-system get svc prometheus-server +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +prometheus-server ClusterIP 10.109.160.254 9090/TCP 4m +``` + +## 部署示例 + +```yaml +kubectl apply -f https://raw.githubusercontent.com/apache/dubbo-samples/master/4-governance/dubbo-samples-metrics-spring-boot/Deployment.yml +``` + +等待示例应用正常运行,通过以下命令确认应用状态: +```yaml +kubectl -n dubbo-demo get deployments +``` + +## 查询 Prometheus + +获得 Prometheus 访问地址 `kubectl port-forward service/prometheus-server 9090:9090`, +打开浏览器,访问 localhost:9090/graph 即可打开 Prometheus 控制台。 + +接下来,执行 Prometheus 查询命令。可以在此确认 [Dubbo 支持的 Metrics 指标](/zh-cn/overview/reference/metrics/standard_metrics/)。 + +**1. 在 “Expression” 一览,输入 `dubbo_consumer_qps_total`,返回以下结果** + +![img](/imgs/v3/tasks/observability/prometheus.png) diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/observability/tracing/_index.md b/content/zh-cn/overview/mannual/java-sdk/tasks/observability/tracing/_index.md new file mode 100755 index 000000000000..575b24ef82bd --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/observability/tracing/_index.md @@ -0,0 +1,55 @@ +--- +aliases: + - /zh/overview/tasks/observability/tracing/ + - /zh-cn/overview/tasks/observability/tracing/ +description: "" +linkTitle: 全链路追踪 +no_list: true +title: 全链路追踪 +type: docs +weight: 5 +--- + + +{{< blocks/section color="white" height="auto">}} +
+
+ +
+
+
+
+

+ Zipkin 全链路追踪 +

+

演示如果通过 Zipkin 实现对 Dubbo 服务的全链路追踪。 +

+
+
+
+
+
+
+

+ Skywalking 全链路追踪 +

+

演示如果通过 Skywalking 实现对 Dubbo 服务的全链路追踪。 +

+
+
+
+
+
+
+

+ OTlp 全链路追踪 +

+

演示如果通过 OpenTelemetry 的 Otlp Collector 实现对 Dubbo 服务的全链路追踪。 +

+
+
+
+
+
+
+{{< /blocks/section >}} diff --git a/content/zh-cn/overview/tasks/observability/tracing/otlp.md b/content/zh-cn/overview/mannual/java-sdk/tasks/observability/tracing/otlp.md similarity index 93% rename from content/zh-cn/overview/tasks/observability/tracing/otlp.md rename to content/zh-cn/overview/mannual/java-sdk/tasks/observability/tracing/otlp.md index b014e994f057..99d5e1e63cdf 100644 --- a/content/zh-cn/overview/tasks/observability/tracing/otlp.md +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/observability/tracing/otlp.md @@ -1,12 +1,13 @@ --- aliases: - /zh/overview/tasks/observability/tracing/otlp/ -description: "" -linkTitle: OTlp + - /zh-cn/overview/tasks/observability/tracing/otlp/ +description: "这个案例展示了在 Dubbo 项目中以 OpenTelemetry 作为 Tracer,将 Trace 信息上报到 Otlp Collector,再由 collector 转发至 Zipkin、Jagger。" +linkTitle: OpenTelemetry no_list: true title: OTlp type: docs -weight: 1 +weight: 2 --- ## 概述 diff --git a/content/zh-cn/overview/tasks/observability/tracing/skywalking.md b/content/zh-cn/overview/mannual/java-sdk/tasks/observability/tracing/skywalking.md similarity index 95% rename from content/zh-cn/overview/tasks/observability/tracing/skywalking.md rename to content/zh-cn/overview/mannual/java-sdk/tasks/observability/tracing/skywalking.md index 07c3414ffdf8..c49b1e889863 100644 --- a/content/zh-cn/overview/tasks/observability/tracing/skywalking.md +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/observability/tracing/skywalking.md @@ -1,12 +1,13 @@ --- aliases: - /zh/overview/tasks/observability/tracing/skywalking/ -description: "" + - /zh-cn/overview/tasks/observability/tracing/skywalking/ +description: "本文演示如何将 Dubbo 接入 Skywalking 全链路监控体系" linkTitle: Skywalking no_list: true title: Skywalking type: docs -weight: 2 +weight: 4 --- 本文演示如何将 Dubbo 接入 Skywalking 全链路监控体系,完整示例请参考 dubbo-samples-tracing-skywalking。依赖的 Skywalking Agent 版本为 [skywalking micrometer-1.10 api](https://skywalking.apache.org/docs/skywalking-java/next/en/setup/service-agent/java-agent/application-toolkit-micrometer-1.10/). diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/observability/tracing/tracing.md b/content/zh-cn/overview/mannual/java-sdk/tasks/observability/tracing/tracing.md new file mode 100644 index 000000000000..9ea7be95c37f --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/observability/tracing/tracing.md @@ -0,0 +1,147 @@ +--- +aliases: + - /zh/docs3-v2/java-sdk/advanced-features-and-usage/observability/tracing/ + - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/observability/tracing/ +description: Dubbo 内置了全链路追踪能力,你可以通过引入 spring-boot-starter 或者相关依赖开启链路跟踪能力,通过将跟踪数据导出到一些主流实现如 Zipkin、Skywalking、Jaeger 等后端系统,可以实现全链路跟踪数据的分析与可视化展示。 +hide_summary: true +linkTitle: 链路追踪 +no_list: true +title: 全链路追踪使用与实现说明 +type: docs +weight: 1 +--- + +Dubbo 内置了全链路追踪能力,你可以通过引入 spring-boot-starter 或者相关依赖开启链路跟踪能力,通过将跟踪数据导出到一些主流实现如 Zipkin、Skywalking、Jaeger 等后端系统,可以实现全链路跟踪数据的分析与可视化展示。 + +Dubbo 目前借助 Micrometer Observation 完成 Tracing 的所有埋点工作,依赖 Micrometer 提供的各种 Bridge 适配,我们可以实现将 Tracing 导入各种后端系统,具体工作原理如下。 + +![micrometer-bridge](/imgs/docs3-v2/java-sdk/observability/micrometer-bridge.png) + +## 使用方式 + +以 Dubbo Spring Boot 应用为例,通过加入如下依赖即可开启链路追踪,并使用 zipkin exporter bridge 将链路追踪数据导入 Zipkin 后端系统。 + +```xml + + org.apache.dubbo + dubbo-spring-boot-tracing-otel-zipkin-starter + 3.2.1-SNAPSHOT + +``` + +更多完整示例请参见: +* [使用 Zipkin 实现 Dubbo 全链路追踪](/zh-cn/overview/tasks/observability/tracing/zipkin/) +* [使用 Skywalking 实现 Dubbo 全链路追踪](/zh-cn/overview/tasks/observability/tracing/skywalking/) + +## 关联日志 + +Dubbo Tracing 还实现了与日志系统的自动关联,即将 tracing-id、span-id 等信息自动置入日志 MDC 上下文,你只需要设置日志输出格式中包含类似 `%X{traceId:-},%X{spanId:-}]`,即可实现业务日志与 tracing 系统的自动关联,具体可参见 [Tracing 日志上下文配置示例](https://github.com/apache/dubbo-samples/blob/master/4-governance/dubbo-samples-tracing/dubbo-samples-spring-boot-tracing-otel-otlp/provider/src/main/resources/application.yml)。 + +## 工作原理 +### Tracing相关概念 + +- Span:基本工作单元。例如,发送 RPC 是一个新的 span,发送对 RPC 的响应也是如此。Span还有其他数据,例如description、带时间戳的事件、键值注释(标签)、导致它们的跨度的 ID 和进程 ID(通常是 IP 地址)。跨度可以启动和停止,并且它们会跟踪它们的时间信息。创建跨度后,您必须在将来的某个时间点停止它。 + +- Trace:一组形成树状结构的跨度。例如,如果您运行分布式大数据存储,则可能会通过请求形成跟踪PUT。 + +- Annotation/Event : 用于及时记录一个事件的存在。 + +- Tracing context:为了使分布式跟踪工作,跟踪上下文(跟踪标识符、跨度标识符等)必须通过进程(例如通过线程)和网络传播。 + +- Log correlation:部分跟踪上下文(例如跟踪标识符、跨度标识符)可以填充到给定应用程序的日志中。然后可以将所有日志收集到一个存储中,并通过跟踪 ID 对它们进行分组。这样就可以从所有按时间顺序排列的服务中获取单个业务操作(跟踪)的所有日志。 + +- Latency analysis tools:一种收集导出跨度并可视化整个跟踪的工具。允许轻松进行延迟分析。 + +- Tracer: 处理span生命周期的库(Dubbo 目前支持 OpenTelemetry 和 Brave)。它可以通过 Exporter 创建、启动、停止和报告 Spans 到外部系统(如 Zipkin、Jagger 等)。 + +- Exporter: 将产生的 Trace 信息通过 http 等接口上报到外部系统,比如上报到 Zipkin。 + +### SpringBoot Starters + +对于 SpringBoot 用户,Dubbo 提供了 Tracing 相关的 starters,自动装配 Micrometer 相关的配置代码,且用户可自由选择 Tracer 和Exporter。 + +#### OpenTelemetry 作为 Tracer,将 Trace 信息 export 到 Zipkin + +```yml + + org.apache.dubbo + dubbo-spring-boot-tracing-otel-zipkin-starter + ${version} + +``` + +#### OpenTelemetry 作为 Tracer,将 Trace 信息 export 到 OTlp Collector + +```yml + + org.apache.dubbo + dubbo-spring-boot-tracing-otel-otlp-starter + ${version} + +``` + +#### Brave 作为 Tracer,将 Trace 信息 export 到 Zipkin + +```yml + + org.apache.dubbo + dubbo-spring-boot-tracing-brave-zipkin-starter + ${version} + +``` + +#### 自由组装 Tracer 和 Exporter + +如果用户基于 Micrometer 有自定义的需求,想将 Trace 信息上报至其他外部系统观测,可参照如下自由组装 Tracer 和 Exporter: + +```yml + + + org.apache.dubbo + dubbo-spring-boot-observability-starter + ${version} + + + + io.micrometer + micrometer-tracing-bridge-otel + ${version} + + + + io.opentelemetry + opentelemetry-exporter-zipkin + ${version} + +``` + +```yml + + + org.apache.dubbo + dubbo-spring-boot-observability-starter + ${version} + + + + io.micrometer + micrometer-tracing-bridge-brave + ${version} + + + + io.zipkin.reporter2 + zipkin-reporter-brave + ${version} + +``` + +后续还会补齐更多的 starters,如 Jagger、SkyWalking等。 + +### Dubbo Bootstrap API + +对于像非 SpringBoot 的项目,可以使用 Dubbo API 使用Tracing。 + +详细案例可参考[代码地址](https://github.com/conghuhu/dubbo-samples/tree/master/4-governance/dubbo-samples-tracing/dubbo-sample-api-tracing-otel-zipkin) + + diff --git a/content/zh-cn/overview/tasks/observability/tracing/zipkin.md b/content/zh-cn/overview/mannual/java-sdk/tasks/observability/tracing/zipkin.md similarity index 97% rename from content/zh-cn/overview/tasks/observability/tracing/zipkin.md rename to content/zh-cn/overview/mannual/java-sdk/tasks/observability/tracing/zipkin.md index 3d3c5c36029d..42c00fe3496e 100644 --- a/content/zh-cn/overview/tasks/observability/tracing/zipkin.md +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/observability/tracing/zipkin.md @@ -1,12 +1,13 @@ --- aliases: - /zh/overview/tasks/observability/tracing/zipkin/ -description: "" + - /zh-cn/overview/tasks/observability/tracing/zipkin/ +description: "这个示例演示了 Dubbo 集成 Zipkin 全链路追踪的基础示例" linkTitle: Zipkin no_list: true title: Zipkin type: docs -weight: 1 +weight: 3 --- 这个示例演示了 Dubbo 集成 Zipkin 全链路追踪的基础示例,完整代码请参考 dubbo-samples-tracing-zipkin,此示例共包含三部分内容: diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/protocols/_index.md b/content/zh-cn/overview/mannual/java-sdk/tasks/protocols/_index.md new file mode 100755 index 000000000000..d4009fbfd385 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/protocols/_index.md @@ -0,0 +1,12 @@ +--- +aliases: + - /zh/overview/tasks/protocols/ + - /zh-cn/overview/tasks/protocols/ + - /zh-cn/overview/mannual/java-sdk/tasks/protocol/ +description: 演示 Dubbo 多协议的应用场景 +hide: true +linkTitle: 通信协议 +title: 通信协议 +type: docs +weight: 2 +--- diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/protocols/dubbo.md b/content/zh-cn/overview/mannual/java-sdk/tasks/protocols/dubbo.md new file mode 100644 index 000000000000..057591a935ff --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/protocols/dubbo.md @@ -0,0 +1,119 @@ +--- +aliases: + - /zh/overview/tasks/protocols/dubbo/ + - /zh-cn/overview/tasks/protocols/dubbo/ +description: "演示了如何开发基于 `dubbo` 协议通信的服务。" +linkTitle: dubbo协议 +title: "基于 TCP 的 RPC 通信协议 - dubbo" +type: docs +weight: 2 +--- + +本示例演示了如何开发基于 `dubbo` 协议通信的服务,可在此查看 [本示例的完整代码](https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-dubbo): + +{{% alert title="注意" color="info" %}} +为了保证老版本兼容性,Dubbo 3.3.0 及之前版本的默认协议都是 `dubbo`。但如果您是新用户,正在考虑使用 Dubbo 构建一套全新的微服务系统,我们推荐您在应用中明确配置使用 `triple` 协议。 +{{% /alert %}} + +## 运行示例 +你可以跟随以下步骤,尝试运行本文档对应的示例源码。 + +首先,可通过以下命令下载示例源码 +```shell +git clone --depth=1 https://github.com/apache/dubbo-samples.git +``` + +进入示例源码目录: +```shell +cd dubbo-samples/2-advanced/dubbo-samples-dubbo +``` + +使用 maven 打包示例: +```shell +mvn clean install -DskipTests +``` + +### 启动提供者 +运行以下命令启动提供者: + +```shell +java -jar ./dubbo-samples-dubbo-provider/target/dubbo-samples-dubbo-provider-1.0-SNAPSHOT.jar +``` + +### 启动消费者 +运行以下命令: + +```shell +java -jar ./dubbo-samples-dubbo-consumer/target/dubbo-samples-dubbo-consumer-1.0-SNAPSHOT.jar +``` + +## 源码讲解 + +### 定义服务 +首先是服务定义,使用 `dubbo` 协议时,我们首选需要通过 Java Interface 定义 Dubbo 服务。 +```java +public interface DemoService { + String sayHello(String name); +} +``` + +### 服务提供者 +其次,对于提供者一侧而言,需要提供服务的具体实现。 +```java +@DubboService +public class DemoServiceImpl implements DemoService { + @Override + public String sayHello(String name) { + return "Hello " + name; + } +} +``` + +配置使用 `dubbo` 协议: +```yaml +dubbo: + protocol: + name: dubbo + port: 20880 +``` + +### 服务消费者 + +配置服务引用,如下所示: +```java +@Component +public class Task implements CommandLineRunner { + @DubboReference(url = "dubbo://127.0.0.1:20880/org.apache.dubbo.protocol.dubbo.demo.DemoService") + private DemoService demoService; +} +``` + +接下来,就可以发起对远程服务的 RPC 调用了: +```java +demoService.sayHello("world"); +``` + +## 更多协议配置 + +### 序列化 +消费者与提供者之间的调用使用 dubbo 协议,**方法参数默认数据编码格式(即序列化)是 hessian2**,同时你也可以设置使用其他任意序列化协议,序列化不影响 dubbo 协议的正常工作(只会对编码性能有一些影响)。 + +```yaml +dubbo: + protocol: + name: dubbo + port: 20880 + serialization: fastjson2 +``` + +{{% alert title="注意" color="info" %}} +自 3.2.0 版本开始,Dubbo 增加了序列化协议的自动协商机制,如果满足条件 `两端都为 Dubbo3 特定版本 + 存在 Fastjson2 相关依赖`,则会自动使用 fastjson2 序列化协议,否则使用 hessian2 协议,协商对用户透明无感。 + +由于 Dubbo2 默认序列化协议是 hessian2,对于部分有拦截rpc调用payload的场景,比如sidecar等对链路payload有拦截与解析,在升级过程中需留意兼容性问题,其他用户不用担心。 +{{% /alert %}} + +### 共享连接 +对 dubbo 协议实现来说,**消费端机器A与提供者机器B之间默认是使用的同一个链接**,即不论在 A 与 B 之间有多少服务调用,默认都始终使用同一个 tcp 连接。当然,Dubbo 框架提供了方法可以让您调整 A 与 B 之间的 tcp 连接数。 + +此外,dubbo 协议还支持配置如 payload 限制、序列化、连接数、连接超时时间、心跳等,具体请参见[【参考手册 - dubbo协议】](/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/dubbo/)。 + diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/protocols/protocol.md b/content/zh-cn/overview/mannual/java-sdk/tasks/protocols/protocol.md new file mode 100755 index 000000000000..40a7e7a3ec5a --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/protocols/protocol.md @@ -0,0 +1,250 @@ +--- +description: "提供不同场景下的协议选型(triple、dubbo)指南,包含每个协议的基本配置方式、默认端口、适用场景等。" +linkTitle: 选择 RPC 协议 +title: Dubbo 支持的 RPC 通信协议 +type: docs +weight: 1 +--- + +Dubbo 作为一款 RPC 框架内置了高效的 RPC 通信协议,帮助解决服务间的编码与通信问题,目前支持的协议包括: + * triple,基于 HTTP/1、HTTP/2 的高性能通信协议,100% 兼容 gRPC,支持 Unary、Streming 等通信模式;支持发布 REST 风格的 HTTP 服务。 + * dubbo,基于 TCP 的高性能私有通信协议,缺点是通用性较差,更适合在 Dubbo SDK 间使用; + * 任意协议扩展,通过扩展 protocol 可以之前任意 RPC 协议,官方生态库提供 JsonRPC、thrift 等支持。 + +## 协议概览 + +### 使用哪个协议? + +**开发者该如何确定使用哪一种协议那?** 以下是我们从使用场景、性能、编程易用性、多语言互通等方面对多个主流协议的对比分析: + +| 协议 | 性能 | 网关友好 | 流式通信 | 多语言支持 | 编程API | 说明 | +| --- | --- | --- | --- | --- | --- | --- | +| triple | 高 | 高 | 支持,客户端流、服务端流、双向流 | 支持(Java、Go、Node.js、JavaScript、Rust) | Java Interface、Protobuf(IDL) | 在多语言兼容、性能、网关、Streaming、gRPC 等方面最均衡的协议实现,官方推荐。 | +| dubbo | 高 | 低 | 不支持 | 支持(Java、Go) | Java Interface | 性能最高的私有协议,但前端流量接入、多语言支持等成本较高 | +| rest | 低 | 高 | 不支持 | 支持 | Java Interface | rest 协议在前端接入、互通等方面具备最高的灵活性,但对比 rpc 存在性能、弱类型等缺点。**注意,rest 在 dubbo3 中仅是 triple 协议的一种发布形式** | + +{{% alert title="注意" color="warning" %}} +自 3.3 版本开始,triple 协议支持以 rest 风格发布标准的 http 服务,因此框架中实际已不存在独立的 rest protocol 扩展实现。只是在文档说明上,我们依然选择将 triple 与 rest 作为独立的协议实现分开讲解,请大家注意。 +{{% /alert %}} + +### 协议默认值 +以下是几个主要协议的具体开发、配置、运行态信息: + | 协议名称 | 配置值 | 服务定义方式 | 默认端口 | 传输层协议 | 序列化协议 | 是否默认 | + | --- | --- | --- | --- | --- | --- | --- | + | **triple** | tri | - Java Interface
- Protobuf(IDL) | 50051 | HTTP/1、HTTP/2 | Protobuf Binary、Protobuf JSON | 否 | + | **dubbo** | dubbo | - Java Interface | 20880 | TCP | Hessian、Fastjson2、JSON、JDK、Avro、Kryo 等 | **是** | + | **rest** | tri 或 rest | - Java Interface + SpringMVC
- Java Interface + JAX-RS | 50051 | HTTP/1、HTTP/2 | JSON | 否 | + + {{% alert title="注意" color="info" %}} + 考虑到对过往版本的兼容性,当前 Dubbo 各个发行版本均默认使用 `dubbo` 通信协议。**对于新用户而言,我们强烈建议在一开始就明确配置使用 `triple` 协议**,老用户也尽快参考文档 [实现协议的平滑迁移](/zh-cn/overview/mannual/java-sdk/reference-manual/upgrades-and-compatibility/migration/)。 + {{% /alert %}} + +接下来,我们一起看以下几个协议的基本使用方式。 + +## Triple 协议 +### 基本配置 +通过以下配置启用 triple 协议,默认端口为 50051,如果设置 `port: -1` 则会随机选取端口(从 50051 自增,直到找到第一个可用端口)。 + +```yaml +dubbo: + protocol: + name: tri + port: 50051 +``` + +### 服务定义方式 +使用 triple 协议时,开发者可以使用 `Java Interface`、`Protobuf(IDL)` 两种方式定义 Dubbo RPC 服务,两种服务定义模式下的协议能力是对等的,仅影响开发者的编程体验,具体选用那种开发模式,取决于使用者的业务背景。 + +#### 1. Java Interface +即通过声明一个 Java 接口的方式定义服务,我们在快速开始一节中看到的示例即是这种模式,**适合于没有跨语言诉求的开发团队,具备学习成本低的优势,Dubbo2 老用户可以零成本切换协议**。 + +服务定义范例: + +```java +public interface DemoService { + String sayHello(String name); +} +``` + +可以说只设置 `protocol="tri"` 就可以了,其他与老版本 dubbo 协议开发没有任何区别。请通过【进阶学习 - 通信协议】查看 [java Interface + Triple 协议的具体使用示例](/zh-cn/overview/mannual/java-sdk/tasks/protocols/triple/interface/)。 + +#### 2. Protobuf(IDL) +使用 Protobuf(IDL) 的方式定义服务,**适合于当前或未来有跨语言诉求的开发团队,同一份 IDL 服务可同时用于 Java/Go/Node.js 等多语言微服务开发,劣势是 protobuf 学习成本较高**。 + +```Protobuf +syntax = "proto3"; +option java_multiple_files = true; +package org.apache.dubbo.springboot.demo.idl; + +message GreeterRequest { + string name = 1; +} +message GreeterReply { + string message = 1; +} + +service Greeter{ + rpc greet(GreeterRequest) returns (GreeterReply); +} +``` + +通过 Dubbo 提供的 protoc 编译插件,将以上 IDL 服务定义预编译为相关 stub 代码,其中就包含 Dubbo 需要的 Interface 接口定义,因此在后续编码上区别并不大,只不过相比于前面的用户自定义 Java Interface 模式,这里由插件自动帮我们生成 Interface 定义。 + +```java +// Generated by dubbo protoc plugin +public interface Greeter extends org.apache.dubbo.rpc.model.DubboStub { + String JAVA_SERVICE_NAME = "org.apache.dubbo.springboot.demo.idl.Greeter"; + String SERVICE_NAME = "org.apache.dubbo.springboot.demo.idl.Greeter"; + + org.apache.dubbo.springboot.demo.idl.GreeterReply greet(org.apache.dubbo.springboot.demo.idl.GreeterRequest request); + // more generated codes here... +} +``` + +Protobuf 模式支持的序列化方式有 Protobuf、Protobuf-json 两种模式。请通过【进阶学习 - 通信协议】查看 [Protobuf (IDL) + Triple 协议的具体使用示例](/zh-cn/overview/mannual/java-sdk/tasks/protocols/triple/idl/)。 + +#### 3. 我该使用哪种编程模式,如何选择? + +| | 是 | 否 | +| --- | --- | --- | +| 公司的业务是否有用 Java 之外的其他语言,跨语言互通的场景是不是普遍? | Protobuf | Java 接口 | +| 公司里的开发人员是否熟悉 Protobuf,愿意接受 Protobuf 的额外成本吗? | Protobuf | Java 接口 | +| 是否有标准 gRPC 互通诉求? | Protobuf | Java 接口 | +| 是不是 Dubbo2 老用户,想零改造迁移到 triple 协议? | Java 接口 | Protobuf | + +### HTTP 接入方式 +triple 协议支持标准 HTTP 工具的直接访问,因此前端组件如浏览器、网关等接入非常边便捷,同时服务测试也变得更简单。 + +当服务启动后,可以使用 cURL 命令直接访问: +```shell +curl \ + --header "Content-Type: application/json" \ + --data '["Dubbo"]' \ + http://localhost:50052/org.apache.dubbo.springboot.demo.idl.Greeter/greet/ +``` + +以上默认使用 `org.apache.dubbo.springboot.demo.idl.Greeter/greet` 这种 HTTP 访问路径,且仅支持 post 方法,如果你想对外发布 REST 风格服务,请参考下文 REST 协议小节。 + +也可参考[【使用教程 - 前端网关接入】](/zh-cn/overview/mannual/java-sdk/tasks/gateway/triple/) + +## Dubbo 协议 +### 基本配置 +通过以下配置启用 dubbo 协议,默认端口为 20880,如果设置 `port: -1` 则会随机选取端口(从 20880 自增,直到找到第一个可用端口)。 + +```yaml +dubbo: + protocol: + name: dubbo + port: 20880 +``` + +### 服务定义方式 +dubbo 协议支持使用 `Java Interface` 方式定义 Dubbo RPC 服务,即通过声明一个 Java 接口的方式定义服务。序列化方式可以选用 Hessian、Fastjson2、JSON、Kryo、JDK、自定义扩展等任意编码协议,默认序列化协议为 Fastjson2。 + +```java +public interface DemoService { + String sayHello(String name); +} +``` + +{{% alert title="注意" color="info" %}} +自 3.2.0 版本开始,Dubbo 增加了序列化协议的自动协商机制,如果满足条件 `两端都为 Dubbo3 特定版本 + 存在 Fastjson2 相关依赖`,则会自动使用 fastjson2 序列化协议,否则使用 hessian2 协议,协商对用户透明无感。 + +由于 Dubbo2 默认序列化协议是 hessian2,对于部分有拦截rpc调用payload的场景,比如sidecar等对链路payload有拦截与解析,在升级过程中需留意兼容性问题。 +{{% /alert %}} + +* 关于 dubbo 协议的具体使用示例请参见【进阶学习 - 通信协议】中的 [dubbo 协议示例](/zh-cn/overview/mannual/java-sdk/tasks/protocols/dubbo/)。 + +### HTTP 接入方式 +由于 dubbo 协议无法支持 http 流量直接接入,因此需要有一层网关实现前端 http 协议到后端 dubbo 协议的转换过程(`http -> dubbo`)。Dubbo 框架提供了 `泛化调用` 能力,可以让网关在无服务接口定义的情况下对后端服务发起调用。 + + + +目前社区有很多开源网关产品(Higress、Shenyu、APISIX、Tengine等)支持 `http -> dubbo` 的,它们大部分都提供了可视化界面配置参数映射(泛化调用),同时还支持基于 Nacos、Zookeeper 等主流注册中心的自动地址发现,具体请查看 [【使用教程 - HTTP网关接入】](/zh-cn/overview/mannual/java-sdk/tasks/gateway/dubbo/)。 + +## REST 协议 +在本文前面我们曾提到,自 3.3 版本开始 triple 协议支持以 rest 风格发布标准的 http 服务,因此,如果我们发布 rest 风格的服务等同于使用 triple 协议,只不过,我们要在服务定义上加入特定的注解(Spring Web、JAX-RS)。 + +```yaml +dubbo: + protocol: + name: tri + port: 50051 +``` + +{{% alert title="注意" color="info" %}} +对于老版本的 rest 用户配置是 `name: rest`,用户可以选择将改为 `name: tri`。即使不修改也没有问题,Dubbo 框架会自动将 rest 转换为 triple 协议实现。 +{{% /alert %}} + +所以说,rest 只是 triple 协议的一种特殊的发布形式,为了实现 rest 格式发布,我们需要为服务接口定义增加注解。 + +### 注解 +目前 rest 协议仅支持 `Java 接口` 服务定义模式,相比于 dubbo 和 triple 协议,rest 场景下我们需要为 Interface 增加注解,支持 Spring MVC、JAX_RS 两种注解。 + +Spring MVC 服务定义范例: +```java +@RestController +@RequestMapping("/demo") +public interface DemoService { + @GetMapping(value = "/hello") + String sayHello(); +} +``` + +JAX-RS 服务定义范例: +```java +@Path("/demo") +public interface DemoService { + @GET + @Path("/hello") + String sayHello(); +} +``` + +如果你记得 triple 协议原生支持 cURL 访问,即类似 `org.apache.dubbo.springboot.demo.idl.Greeter/greet` 的访问模式。通过增加以上注解后,即可为 triple 服务额外增加 REST 风格访问支持。 + +关于 rest 协议的具体使用示例请参见【使用教程 - 通信协议】中的 [rest 协议示例](../rest/) + +## 多协议发布 +### 多端口多协议 +多协议发布是指为同一个服务同时提供多种协议访问方式,多协议可以是任意两个或多个协议的组合,比如下面的配置将同时发布了 dubbo、triple 协议: + +```yaml +dubbo: + protocols: + - name: tri + port: 50051 + - name: dubbo + port: 20880 +``` + +基于以上配置,如果应用中有服务 DemoService,则既可以通过 dubbo 协议访问 DemoService,也可以通过 triple 协议访问 DemoService,其工作原理图如下: + +多协议 + +1. 提供者实例同时监听两个端口 20880 和 50051 +2. 同一个实例,会在注册中心注册两条地址 url +3. 不同的消费端可以选择以不同协议调用同一个提供者发布的服务 + +对于消费端而言,如果用户没有明确配置,默认情况下框架会自动选择 `dubbo` 协议调用。Dubbo 框架支持配置通过哪个协议访问服务,如 `@DubboReference(protocol="tri")`,或者在 application.yml 配置文件中指定全局默认值: + +```yaml +dubbo: + consumer: + protocol: tri +``` + +### 单端口多协议 + +除了以上发布多个端口、注册多条 url 到注册中心的方式。对于 dubbo、triple 这两个内置协议,框架提供了在单个端口上同时发布 dubbo 和 triple 协议的能力。这对于老用户来说是一个非常重要的能力,因为它可以做到不增加任何负担的情况下,让使用 dubbo 协议的用户可以额外发布 triple 协议,这样当所有的应用都实现多协议发布之后,我们就可以设置消费端去通过 triple 协议发起调用了。 + +单端口多协议 + +单端口多协议的基本配置如下: + + ```yaml + dubbo: + protocol: + name: dubbo + ext-protocol: tri + ``` diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/protocols/rest.md b/content/zh-cn/overview/mannual/java-sdk/tasks/protocols/rest.md new file mode 100644 index 000000000000..985fee6fb06f --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/protocols/rest.md @@ -0,0 +1,188 @@ +--- +aliases: + - /zh/overview/tasks/protocols/ + - /zh-cn/overview/tasks/protocols/ +description: "演示了如何以标准 `rest` 请求访问 triple、dubbo 协议发布的服务。" +hide: true +linkTitle: rest协议 +title: 发布 REST 风格的服务 +type: docs +weight: 3 +--- + +{{% alert %}} +本文要讲的 "rest 协议" 实际上并不是一个真正的协议实现,而是关于如何使得 triple 协议支持以 rest 风格的 http 请求直接访问。 +我们将演示如何使用 rest 请求访问标准 triple 协议的 Dubbo 服务。 +{{% /alert %}} + +{{% alert title="注意" color="warning" %}} +从 Dubbo 3.3 版本开始,rest 协议已移至 extensions 库,由 triple 协议来对 Rest 提供更全面的支持,新版本的内置协议实现只剩下 triple 和 dubbo。 +
因此,当我们提到 rest 时,都是指 triple 协议的 rest 访问支持能力,具体参见 [Triple Rest用户手册](/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/tripe-rest-manual/) +{{% /alert %}} + +在讲解 [triple 协议示例](../triple/interface/#curl) 时,我们曾提到 triple 协议支持以 `application/json` 格式直接访问: + +```shell +curl \ + --header "Content-Type: application/json" \ + --data '["Dubbo"]' \ + http://localhost:50052/org.apache.dubbo.samples.api.GreetingsService/sayHi/ +``` + +如果你认为以上 +`http://localhost:50052/org.apache.dubbo.samples.api.GreetingsService/sayHi` 格式的 path 请求不够友好,还可以通过注解自定义 http 请求的路径和方法等参数, +目前已支持 内置,Spring Web和JAX-RS 三种注解格式。以下示例的完整代码请参见 [dubbo-samples-triple-rest](https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-triple-rest)。 + +### 下载并运行示例 + +```bash +# 获取示例代码 +git clone --depth=1 https://github.com/apache/dubbo-samples.git +cd dubbo-samples/2-advanced/dubbo-samples-triple-rest/dubbo-samples-triple-rest-basic +# 直接运行 +mvn spring-boot:run +# 或打包后运行 +mvn clean package -DskipTests +java -jar target/dubbo-samples-triple-rest-basic-1.0.0-SNAPSHOT.jar +``` + +当然,也可以直接用IDE导入工程后直接执行 +`org.apache.dubbo.rest.demo.BasicRestApplication#main` 来运行,并通过下断点 debug 的方式来深入理解原理。 + + +### 示例代码 + +```java +// 服务接口 +package org.apache.dubbo.rest.demo; + +import org.apache.dubbo.remoting.http12.rest.Mapping; +import org.apache.dubbo.remoting.http12.rest.Param; + +public interface DemoService { + String hello(String name); + + @Mapping(path = "/hi", method = HttpMethods.POST) + String hello(User user, @Param(value = "c", type = ParamType.Header) int count); +} + +// 服务实现 +@DubboService +public class DemoServiceImpl implements DemoService { + @Override + public String hello(String name) { + return "Hello " + name; + } + + @Override + public String hello(User user, int count) { + return "Hello " + user.getTitle() + ". " + user.getName() + ", " + count; + } +} + +// 模型 +@Data +public class User { + private String title; + private String name; +} +``` + + + +### 测试基本服务 + +```bash +curl -v "http://127.0.0.1:8081/org.apache.dubbo.rest.demo.DemoService/hello?name=world" +# 输出如下 +#> GET /org.apache.dubbo.rest.demo.DemoService/hello?name=world HTTP/1.1 +#> Host: 127.0.0.1:8081 +#> User-Agent: curl/8.7.1 +#> Accept: */* +#> +#* Request completely sent off +#< HTTP/1.1 200 OK +#< content-type: application/json +#< alt-svc: h2=":8081" +#< content-length: 13 +#< +#"Hello world" +``` + +代码讲解:
可以看到输出了 "Hello world" ,有双引号是因为默认输出 content-type 为 application/json
通过这个例子可以了解 Triple 默认将服务导出到 +`/{serviceInterface}/{methodName}`路径,并支持通过url方式传递参数 + + +### 测试高级服务 + +```bash +curl -v -H "c: 3" -d 'name=Yang' "http://127.0.0.1:8081/org.apache.dubbo.rest.demo.DemoService/hi.txt?title=Mr" +# 输出如下 +#> POST /org.apache.dubbo.rest.demo.DemoService/hi.txt?title=Mr HTTP/1.1 +#> Host: 127.0.0.1:8081 +#> User-Agent: curl/8.7.1 +#> Accept: */* +#> c: 3 +#> Content-Length: 9 +#> Content-Type: application/x-www-form-urlencoded +#> +#* upload completely sent off: 9 bytes +#< HTTP/1.1 200 OK +#< content-type: text/plain +#< alt-svc: h2=":8081" +#< content-length: 17 +#< +#Hello Mr. Yang, 3 +``` + +代码讲解:
可以看到输出 Hello Mr. Yang, 3 ,没有双引号是因为通过指定后缀 txt 的方式要求用 `text/plain` 输出
通过这个例子可以了解如何通过 Mapping 注解来定制路径,通过 Param 注解来定制参数来源,并支持通过 post body 或 url方式传递参数,详细说明参见: [Basic使用指南](/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/tripe-rest-manual/#GdlnC) + + +### 观察日志 + +可以通过打开 debug 日志的方式来了解rest的启动和响应请求过程 + +```yaml +logging: + level: + "org.apache.dubbo.rpc.protocol.tri": debug + "org.apache.dubbo.remoting": debug +``` + +打开后可以观察到 Rest 映射注册和请求响应过程 + +``` +# 注册mapping +DEBUG o.a.d.r.p.t.TripleProtocol : [DUBBO] Register triple grpc mapping: 'org.apache.dubbo.rest.demo.DemoService' -> invoker[tri://192.168.2.216:8081/org.apache.dubbo.rest.demo.DemoService] + INFO .r.p.t.r.m.DefaultRequestMappingRegistry : [DUBBO] BasicRequestMappingResolver resolving rest mappings for ServiceMeta{interface=org.apache.dubbo.rest.demo.DemoService, service=DemoServiceImpl@2a8f6e6} at url [tri://192.168.2.216:8081/org.apache.dubbo.rest.demo.DemoService] +DEBUG .r.p.t.r.m.DefaultRequestMappingRegistry : [DUBBO] Register rest mapping: '/org.apache.dubbo.rest.demo.DemoService/hi' -> mapping=RequestMapping{name='DemoServiceImpl#hello', path=PathCondition{paths=[org.apache.dubbo.rest.demo.DemoService/hi]}, methods=MethodsCondition{methods=[POST]}}, method=MethodMeta{method=org.apache.dubbo.rest.demo.DemoService.hello(User, int), service=DemoServiceImpl@2a8f6e6} +DEBUG .r.p.t.r.m.DefaultRequestMappingRegistry : [DUBBO] Register rest mapping: '/org.apache.dubbo.rest.demo.DemoService/hello' -> mapping=RequestMapping{name='DemoServiceImpl#hello~S', path=PathCondition{paths=[org.apache.dubbo.rest.demo.DemoService/hello]}}, method=MethodMeta{method=org.apache.dubbo.rest.demo.DemoService.hello(String), service=DemoServiceImpl@2a8f6e6} + INFO .r.p.t.r.m.DefaultRequestMappingRegistry : [DUBBO] Registered 2 REST mappings for service [DemoServiceImpl@44627686] at url [tri://192.168.2.216:8081/org.apache.dubbo.rest.demo.DemoService] in 11ms + +# 请求响应 +DEBUG .a.d.r.p.t.r.m.RestRequestHandlerMapping : [DUBBO] Received http request: DefaultHttpRequest{method='POST', uri='/org.apache.dubbo.rest.demo.DemoService/hi.txt?title=Mr', contentType='application/x-www-form-urlencoded'} +DEBUG .r.p.t.r.m.DefaultRequestMappingRegistry : [DUBBO] Matched rest mapping=RequestMapping{name='DemoServiceImpl#hello', path=PathCondition{paths=[/org.apache.dubbo.rest.demo.DemoService/hi]}, methods=MethodsCondition{methods=[POST]}}, method=MethodMeta{method=org.apache.dubbo.rest.demo.DemoService.hello(User, int), service=DemoServiceImpl@2a8f6e6} +DEBUG .a.d.r.p.t.r.m.RestRequestHandlerMapping : [DUBBO] Content-type negotiate result: request='application/x-www-form-urlencoded', response='text/plain' +DEBUG .d.r.h.AbstractServerHttpChannelObserver : [DUBBO] Http response body is: '"Hello Mr. Yang, 3"' +DEBUG .d.r.h.AbstractServerHttpChannelObserver : [DUBBO] Http response headers sent: {:status=[200], content-type=[text/plain], alt-svc=[h2=":8081"], content-length=[17]} +``` + +## 实际应用场景 + +接下来,我们看一下在 triple 协议支持 rest 格式访问后,能被应用于哪些场景中解决实际问题。 + +### Spring Cloud 互调 + +首先,第一个场景就是实现 Dubbo 体系与 http 微服务体系互通。 + +设想你是一条业务线负责人,你们有一套基于 Dubbo 开发的微服务集群,集群内服务间都是基于 triple 二进制协议通信;公司内还有一个重要业务,是跑在基于 Spring Cloud 开发的微服务集群上,而 Spring Cloud 集群内的服务间都是 http+json 协议通信。现在要实现这两个业务的互通,服务之间如何实现互调那?triple 协议支持 rest 格式访问可以解决这个问题,对于 Dubbo 微服务集群而言,相当于是对内使用 triple 二进制协议通信,对外交互使用 triple 提供的 rest 请求格式。 + +关于这部分的具体使用示例,请参考博客 [微服务最佳实践零改造实现 Spring Cloud、Apache Dubbo 互通](/zh-cn/blog/2023/10/07/微服务最佳实践零改造实现-spring-cloud-apache-dubbo-互通/)。 + +### 网关流量接入 + +支持 rest 格式访问的另外一个非常有价值的场景就是方便网关流量接入。二进制格式的 rpc 协议接入一直是个难题,之前 dubbo 还特意提供了 +`泛化调用` 来解决这个问题,网关可以基于泛化调用实现 `http -> dubbo` 协议转换来接入后端微服务集群。 + +现在,有了 rest 格式支持,无需任何网关做协议转换,即可实现去中心化接入。具体请参见 [HTTP 网关流量接入](../../gateway/) + diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/protocols/triple/_index.md b/content/zh-cn/overview/mannual/java-sdk/tasks/protocols/triple/_index.md new file mode 100755 index 000000000000..7fc9974eac39 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/protocols/triple/_index.md @@ -0,0 +1,12 @@ +--- +aliases: + - /zh/overview/tasks/protocols/ + - /zh-cn/overview/tasks/protocols/ +description: "演示了如何开发基于 `triple` 协议通信的服务。" +hide: true +linkTitle: triple协议 +title: "基于 HTTP1/2 的 RPC 通信协议 - triple" +type: docs +weight: 2 +--- + diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/protocols/triple/grpc.md b/content/zh-cn/overview/mannual/java-sdk/tasks/protocols/triple/grpc.md new file mode 100644 index 000000000000..0841c9457e27 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/protocols/triple/grpc.md @@ -0,0 +1,67 @@ +--- +aliases: + - /zh/overview/tasks/protocols/grpc/ +description: "演示了如何使用 triple 协议实现 Dubbo 服务与标准 gRPC 服务的互相调用。" +linkTitle: 发布/调用标准gRPC服务 +title: 使用 Dubbo 开发 gRPC 服务 +type: docs +weight: 5 +--- + +这个示例演示了如何使用 triple 协议实现 Dubbo 服务与标准 gRPC 服务的互相调用,可在此查看 [示例完整源码](https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-triple-grpc) + +![triple-grpc.png](/imgs/v3/tasks/protocol/triple-grpc.png) + +就像在 [Triple协议规范](https://dubbo.apache.org/zh-cn/overview/reference/protocols/triple/) 中所描述的,triple 协议与 gRPC 协议保持 100% 兼容,同时在易用性方面有了非常大的提升(比如支持 cURL、浏览器直接访问等),可以说 triple 是一个更好用的 gRPC 设计与实现。 + +## 运行示例 + +首先,可通过以下命令下载示例源码 +```shell +git clone --depth=1 https://github.com/apache/dubbo-samples.git +``` + +进入示例源码目录: +```shell +cd dubbo-samples/2-advanced/dubbo-samples-triple-grpc +``` + +接下来,我们分别从 dubbo 调用 grpc、grpc 调用 dubbo 两个不同的方向,看一下如何基于 triple 协议实现互调。 + +### 作为标准的 gRPC Server +在这一部分,我们会发布一个 Dubbo Triple Server,然后启动一个标准的 gRPC 消费端(示例采用谷歌官方发布的 grpc-java 编码)来调用 Triple 服务。 + +#### 启动 Dubbo server +确保你在 `dubbo-samples-triple-grpc` 目录,运行以下命令: + +```shell +$ mvn compile exec:java -Dexec.mainClass="org.apache.dubbo.samples.tri.grpc.interop.server.TriOpServer" +``` + +#### 使用标准 gRPC client 调用 Triple 服务 +打开一个新的终端,在 `dubbo-samples-triple-grpc` 目录运行以下命令: + +```shell +$ mvn compile exec:java -Dexec.mainClass="org.apache.dubbo.samples.tri.grpc.interop.server.GrpcClient" +``` + +### 作为标准的 gRPC Client +以下部分我们演示如何使用 triple 协议访问谷歌官方的 gRPC 服务(示例采用谷歌官方发布的 grpc-java 编写). + +#### 启动标准 gRPC server +```shell +$ mvn compile exec:java -Dexec.mainClass="org.apache.dubbo.samples.tri.grpc.interop.client.GrpcServer" +``` + +#### 使用 Dubbo client 调用标准 gRPC 服务 +```shell +$ mvn compile exec:java -Dexec.mainClass="org.apache.dubbo.samples.tri.grpc.interop.client.TriOpClient" +``` + +## 更多内容 + +本示例主要演示 triple 可以 100% 兼容谷歌发布的 gRPC 框架,而在 triple 相关部分具体代码与配置上,本示例与之前介绍的 [基于 protobuf 的 triple 示例完全一致](../idl/),因此我们不再重复讲解源代码与开发步骤。 + +本示例演示的是 unary 模式的通信兼容性,对于 streaming 模式同样适用。 + + diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/protocols/triple/idl.md b/content/zh-cn/overview/mannual/java-sdk/tasks/protocols/triple/idl.md new file mode 100644 index 000000000000..a19bfe3e9f46 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/protocols/triple/idl.md @@ -0,0 +1,290 @@ +--- +description: "Triple 协议支持使用 Protocol Buffers (Protobuf) 定义服务,对于因为多语言、gRPC、安全性等场景选型protobuf 的用户更友好。" +linkTitle: Protobuf(IDL)方式 +title: 使用 Protobuf(IDL) 开发 triple 通信服务 +type: docs +weight: 2 +--- + +本示例演示如何使用 Protocol Buffers 定义服务,并将其发布为对外可调用的 triple 协议服务。如果你有多语言业务互调、gRPC互通,或者熟悉并喜欢 Protobuf 的开发方式,则可以使用这种模式,否则可以考虑上一篇基于Java接口的 triple 开发模式。 + +可在此查看 [本示例的完整代码](https://github.com/apache/dubbo-samples/tree/master/1-basic/dubbo-samples-api-idl)。 + +{{% alert title="注意" color="info" %}} +本文使用的示例是基于原生 API 编码的,这里还有一个 [Spring Boot 版本的示例](https://github.com/apache/dubbo-samples/tree/master/1-basic/dubbo-samples-spring-boot-idl) 供参考,同样是 `protobuf+triple` 的模式,但额外加入了服务发现配置。 +{{% /alert %}} + +## 运行示例 + +首先,可通过以下命令下载示例源码: +```shell +git clone --depth=1 https://github.com/apache/dubbo-samples.git +``` + +进入示例源码目录: +```shell +cd dubbo-samples/1-basic/dubbo-samples-api-idl +``` + +编译项目,由 IDL 生成代码,这会调用 dubbo 提供的 protoc 插件生成对应的服务定义代码: +```shell +mvn clean compile +``` + +生成代码如下 + +```text +├── build +│   └── generated +│   └── source +│   └── proto +│   └── main +│   └── java +│   └── org +│   └── apache +│   └── dubbo +│   └── samples +│   └── tri +│   └── unary +│   ├── DubboGreeterTriple.java +│   ├── Greeter.java +│   ├── GreeterOuterClass.java +│   ├── GreeterReply.java +│   ├── GreeterReplyOrBuilder.java +│   ├── GreeterRequest.java +│   └── GreeterRequestOrBuilder.java +``` + +### 启动Server +运行以下命令启动 server。 +```shell +mvn compile exec:java -Dexec.mainClass="org.apache.dubbo.samples.tri.unary.TriUnaryServer" +``` + +### 访问服务 +有两种方式可以访问 Triple 服务: +* 以标准 HTTP 工具访问 +* 以 Dubbo client sdk 访问 + +#### cURL 访问 + +```shell +curl \ + --header "Content-Type: application/json" \ + --data '{"name":"Dubbo"}' \ + http://localhost:50052/org.apache.dubbo.samples.tri.unary.Greeter/greet/ +``` + +#### Dubbo client 访问 +运行以下命令,启动 Dubbo client 并完成服务调用 +```shell +mvn compile exec:java -Dexec.mainClass="org.apache.dubbo.samples.tri.unary.TriUnaryClient" +``` + +## 源码讲解 + +### 项目依赖 +由于使用 IDL 开发模式,因此要添加 dubbo、protobuf-java 等依赖,同时还要配置 protobuf-maven-plugin 等插件,用于生成桩代码。 + +```xml + + org.apache.dubbo + dubbo + ${dubbo.version} + + + com.google.protobuf + protobuf-java + 3.19.6 + + + com.google.protobuf + protobuf-java-util + 3.19.6 + +``` + +```xml + + org.xolstice.maven.plugins + protobuf-maven-plugin + 0.6.1 + + com.google.protobuf:protoc:${protoc.version}:exe:${os.detected.classifier} + build/generated/source/proto/main/java + + + dubbo + org.apache.dubbo + dubbo-compiler + ${dubbo.version} + org.apache.dubbo.gen.tri.Dubbo3TripleGenerator + + + + + + + compile + + + + +``` + +{{% alert title="protoc 插件版本说明" color="warning" %}} + +{{% /alert %}} + +### 服务定义 +使用 Protocol Buffers 定义 Greeter 服务 + +```protobuf +syntax = "proto3"; +option java_multiple_files = true; +package org.apache.dubbo.samples.tri.unary; + +message GreeterRequest { + string name = 1; +} +message GreeterReply { + string message = 1; +} + +service Greeter{ + rpc greet(GreeterRequest) returns (GreeterReply); +} +``` + +请注意以上 package 定义 `package org.apache.dubbo.samples.tri.unary;`,在此示例中 package 定义的路径将同时作为 java 包名和服务名前缀。这意味着 rpc 服务的完整定义是:`org.apache.dubbo.samples.tri.unary.Greeter`,与生成代码的路径完全一致。 + +但保持一致并不是必须的,你也可以将 java 包名与服务名前缀定义分开定义,对于一些跨语言调用的场景比较有用处。如以下 IDL 定义中: +* 完整服务名是 `greet.Greeter`,rpc 调用及服务发现过程中会使用这个值 +* java 包名则是 java_package 定义的 `org.apache.dubbo.samples.tri.unary`,生成的 java 代码会放在这个目录。 + +```protobuf +package greet; +option java_package = "org.apache.dubbo.samples.tri.unary;" +option go_package = "github.com/apache/dubbo-go-samples/helloworld/proto;greet"; +``` + +### 服务实现 +在运行 `mvn clean compile` 后可生成 Dubbo 桩代码。接下来继承生成的基础类 `DubboGreeterTriple.GreeterImplBase`,添加具体的业务逻辑实现: + +```java +public class GreeterImpl extends DubboGreeterTriple.GreeterImplBase { + @Override + public GreeterReply greet(GreeterRequest request) { + LOGGER.info("Server {} received greet request {}", serverName, request); + return GreeterReply.newBuilder() + .setMessage("hello," + request.getName()) + .build(); + } +} +``` + +注册服务到 server,其中 protocol 设置为 tri 代表开启 triple 协议。 + +```java +public class TriUnaryServer { + public static void main(String[] args) throws IOException { + ServiceConfig service = new ServiceConfig<>(); + service.setInterface(Greeter.class); + service.setRef(new GreeterImpl()); + + DubboBootstrap bootstrap = DubboBootstrap.getInstance(); + bootstrap.protocol(new ProtocolConfig(CommonConstants.TRIPLE, 50052)) + .service(service) + .start().await(); + } +} +``` + +### 编写 client 逻辑 +```java +public class TriUnaryClient { + public static void main(String[] args) throws IOException { + DubboBootstrap bootstrap = DubboBootstrap.getInstance(); + ReferenceConfig ref = new ReferenceConfig<>(); + ref.setInterface(Greeter.class); + ref.setUrl("tri://localhost:50052"); + + bootstrap.reference(ref).start(); + Greeter greeter = ref.get(); + final GreeterReply reply = greeter.greet(GreeterRequest.newBuilder().setName("name").build()); + } +} +``` + +## 常见问题 + +### protobuf 类找不到 + +由于 Triple 协议底层需要依赖 protobuf 协议进行传输,即使定义的服务接口不使用 protobuf 也需要在环境中引入 protobuf 的依赖。 + +```xml + + com.google.protobuf + protobuf-java + 3.19.4 + +``` + +同时,为了支持 `application/json` 格式请求直接访问,还需要增加如下依赖。 +```xml + + com.google.protobuf + protobuf-java-util + 3.19.4 + +``` + +### 生成的代码无法编译 +在使用 Protobuf 时,请尽量保持 dubbo 核心库版本与 protoc 插件版本一致,并运行 `mvn clean compile` 重新生成代码。 + +**1. 3.3.0 版本之后** + +3.3.0+ 版本开始使用 `dubbo-maven-plugin` 配置 protoc 插件,`dubbo-maven-plugin` 的版本必须保持和使用的内核 dubbo 版本一致: + +```xml + + org.apache.dubbo + dubbo-maven-plugin + ${dubbo.version} + + + + +``` + +**2. 3.3.0 版本之前** + +3.3.0 之前的版本使用 `protobuf-maven-plugin` 配置 protoc 插件,其中 `dubbo-compiler` 必须保持和使用的内核 dubbo 版本一致: + +```xml + + org.xolstice.maven.plugins + protobuf-maven-plugin + 0.6.1 + + com.google.protobuf:protoc:${protoc.version}:exe:${os.detected.classifier} + build/generated/source/proto/main/java + + + dubbo + org.apache.dubbo + dubbo-compiler + ${dubbo.version} + org.apache.dubbo.gen.tri.Dubbo3TripleGenerator + + + + + + + compile + + + + +``` \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/protocols/triple/interface.md b/content/zh-cn/overview/mannual/java-sdk/tasks/protocols/triple/interface.md new file mode 100644 index 000000000000..367b1138fb75 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/protocols/triple/interface.md @@ -0,0 +1,148 @@ +--- +aliases: + - /zh/docs3-v2/java-sdk/reference-manual/protocol/triple/pojo/ + - /zh-cn/docs3-v2/java-sdk/reference-manual/protocol/triple/pojo/ +description: "Triple 协议完全兼容 gRPC,但易用性更好不绑定 Protobuf,你可以继续使用 `Java 接口` 直接定义服务。" +linkTitle: Java接口方式 +title: 使用 Java 接口方式开发 triple 通信服务 +type: docs +weight: 1 +--- + +**不同于谷歌官方 gRPC 实现,Dubbo 实现的 triple 协议易用性更好(不绑定 Protobuf),你可以继续使用 `Java 接口` 直接定义服务。对于期望平滑升级、没有多语言业务或者不熟悉 Protobuf 的用户而言,`Java 接口`方式是最简单的使用 triple 的方式。** + +以下是一个使用`Java 接口`开发 Dubbo 服务的基本示例,示例使用 triple 协议通信,可在此查看 [本示例的完整代码](https://github.com/apache/dubbo-samples/tree/master/1-basic/dubbo-samples-api)。 + +{{% alert title="注意" color="info" %}} +本文使用的示例是基于原生 API 编码的,这里还有一个 [Spring Boot 版本的示例](https://github.com/apache/dubbo-samples/tree/master/1-basic/dubbo-samples-spring-boot) 供参考,同样是 `Java接口+triple` 的模式,此示例还额外加入了服务发现配置。 +{{% /alert %}} + +## 运行示例 +首先,可通过以下命令下载示例源码 +```shell +git clone --depth=1 https://github.com/apache/dubbo-samples.git +``` + +进入示例源码目录: +```shell +cd dubbo-samples/1-basic/dubbo-samples-api +``` + +### 启动Server +运行以下命令启动 server + +```bash +mvn -Dexec.mainClass=org.apache.dubbo.samples.provider.Application exec:java +``` + +### 启动Client + +有两种方式可以调用 server 发布的服务 +* 使用标准的 http 工具,如 cURL +* 使用 Dubbo SDK 开发一个 client + +#### cURL +```shell +curl \ + --header "Content-Type: application/json" \ + --data '["Dubbo"]' \ + http://localhost:50052/org.apache.dubbo.samples.api.GreetingsService/sayHi/ +``` + +#### SDK Client + +```bash +mvn -Dexec.mainClass=org.apache.dubbo.samples.client.Application exec:java +``` + +## 源码讲解 +如果您是 Dubbo 老用户,你会发现以下内容与之前 Dubbo2 的开发模式基本一样,只是协议名称从 `dubbo` 换成了 `tri`。 + +### 定义服务 +首先是服务定义,使用 Java 接口定义 Dubbo 服务。 +```java +public interface GreetingsService { + String sayHi(String name); +} +``` + +### 服务提供者 +其次,对于提供者一侧而言,需要提供服务的具体实现: +```java +public class GreetingsServiceImpl implements GreetingsService { + @Override + public String sayHi(String name) { + return "hi, " + name; + } +} +``` + +最后,是将服务发布出去: +```java +public static void main(String[] args) { + DubboBootstrap.getInstance() + .protocol(ProtocolBuilder.newBuilder().name("tri").port(50052).build()) + .service(ServiceBuilder.newBuilder().interfaceClass(GreetingsService.class).ref(new GreetingsServiceImpl()).build()) + .start() + .await(); +} +``` + +### 服务消费者 + +接下来,就可以发起对远程服务的 RPC 调用了: +```java +public static void main(String[] args) throws IOException { + ReferenceConfig reference = + ReferenceBuilder.newBuilder() + .interfaceClass(GreetingsService.class) + .url("tri://localhost:50052") + .build(); + DubboBootstrap.getInstance().reference(reference).start(); + GreetingsService service = reference.get(); + + String message = service.sayHi("dubbo"); +} +``` + +## 注意事项 + +### 序列化编码 + +Dubbo 是如何做到同时支持普通 Java 对象、Protobuf 对象的那?Dubbo 实现中有一个对象类型判断,首先判断参数类型是否为 protobuf 对象,如果不是。用一个 protobuf 对象将 request 和 response 进行包装(wrapper),将普通的 Java 对象传输在底层统一为 protobuf 对象传输。在 wrapper 对象内部声明序列化类型,来支持序列化的扩展。 + +wrapper 的 IDL 如下: +```proto +syntax = "proto3"; + +package org.apache.dubbo.triple; + +message TripleRequestWrapper { + // hessian4 + // json + string serializeType = 1; + repeated bytes args = 2; + repeated string argTypes = 3; +} + +message TripleResponseWrapper { + string serializeType = 1; + bytes data = 2; + string type = 3; +} +``` + +对于请求,使用`TripleRequestWrapper`进行包装,对于响应使用`TripleResponseWrapper`进行包装。 + +> 对于请求参数,可以看到 args 被`repeated`修饰,这是因为需要支持 java 方法的多个参数。当然,序列化只能是一种。序列化的实现沿用 Dubbo2 实现的 spi + +### 性能表现 +由于链路上传输的数据额外经过了一层序列化编码(如 hessian2),同时,server 端的方法调用基于反射,因此相比于 `protobuf+triple` 的编码模式,Java 接口方式在性能上会存在一定的下降。 + +Protobuf 模式固然有一定的性能优势,但易用性与使用成本也会陡然增加,我们建议还是优先考虑业务场景,如果没有多语言业务、dubbo2老用户,则继续保持 Java 接口模式是一个比较好、低成本的选择。 + +### gRPC兼容性 +由于 gRPC 仅支持 protobuf 模式,因此本文介绍的 `接口+triple` 的模式无法与谷歌官方原生的 gRPC 协议互调。 + +### 前端流量接入 +对于来自前端的 HTTP 流量(比如浏览器或 web 应用),要想通过网关接入 triple,就要走 triple 内置的 `application/json` 模式发起调用,具体请参见[【使用教程-HTTP网关接入】](/zh-cn/overview/mannual/java-sdk/tasks/gateway/triple/)。 \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/protocols/triple/streaming.md b/content/zh-cn/overview/mannual/java-sdk/tasks/protocols/triple/streaming.md new file mode 100644 index 000000000000..19ac9a12db5e --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/protocols/triple/streaming.md @@ -0,0 +1,325 @@ +--- +aliases: + - /zh/docs3-v2/java-sdk/reference-manual/protocol/triple/streaming/ + - /zh-cn/docs3-v2/java-sdk/reference-manual/protocol/triple/streaming/ +description: "演示了服务端流、双向流等 Streaming 流式通信的基本使用方法。" +linkTitle: Streaming流式通信 +title: Streaming 通信 +type: docs +weight: 4 +--- +在 [选择 RPC 通信协议](../../protocol/) 一节提到,Streaming 是 Dubbo3 新提供的一种 RPC 数据传输模式,适用于以下场景: + +- 接口需要发送大量数据,这些数据无法被放在一个 RPC 的请求或响应中,需要分批发送,但应用层如果按照传统的多次 RPC 方式无法解决顺序和性能的问题,如果需要保证有序,则只能串行发送 +- 流式场景,数据需要按照发送顺序处理, 数据本身是没有确定边界的 +- 推送类场景,多个消息在同一个调用的上下文中被发送和处理 + +Streaming 分为以下三种: +- SERVER_STREAM(服务端流) +- CLIENT_STREAM(客户端流) +- BIDIRECTIONAL_STREAM(双向流) + +以下示例演示 triple streaming 流式通信的基本使用方法,涵盖了客户端流、服务端流、双向流等三种模式,示例使用 Protocol Buffers 的服务开发模式,对于 Java 接口模式的开发者可以在本文最后查看相应说明。可在此查看 [本示例完整代码](https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-triple-streaming)。 + +## 运行示例 + +首先,可通过以下命令下载示例源码: +```shell +git clone --depth=1 https://github.com/apache/dubbo-samples.git +``` + +进入示例源码目录: +```shell +cd dubbo-samples/2-advanced/dubbo-samples-triple-streaming +``` + +编译项目,由 IDL 生成代码,这会调用 dubbo 提供的 protoc 插件生成对应的服务定义代码: +```shell +mvn clean compile +``` + +### 启动server + +运行以下命令,启动 server: +```shell +$ mvn compile exec:java -Dexec.mainClass="org.apache.dubbo.samples.tri.streaming.TriStreamServer" +``` + +#### 启动client +运行以下命令,启动 client: + +```shell +$ mvn compile exec:java -Dexec.mainClass="org.apache.dubbo.samples.tri.streaming.TriStreamClient" +``` + +## 源码解读 +与 [使用 Protobuf(IDL) 开发 triple 协议服务](../idl/) 一节中提到的一样,这个示例使用 protobuf 定义服务,因此示例需要的依赖、配置等基本是一致的,请参考那一节了解完整详情。接下来,我们将重点讲解流式通信部分的内容。 + +### protobuf服务定义 + +```protobuf +syntax = "proto3"; +option java_multiple_files = true; +package org.apache.dubbo.samples.tri.streaming; + +message GreeterRequest { + string name = 1; +} +message GreeterReply { + string message = 1; +} + +service Greeter{ + rpc biStream(stream GreeterRequest) returns (stream GreeterReply); + rpc serverStream(GreeterRequest) returns (stream GreeterReply); +} +``` + +在上面的 proto 文件中,我们定义了两个方法: +* `biStream(stream GreeterRequest) returns (stream GreeterReply)` 双向流 +* `serverStream(GreeterRequest) returns (stream GreeterReply)` 服务端流 + +### 生成代码 +接下来,我们需要从 .proto 服务定义生成 Dubbo 客户端和服务器接口。protoc dubbo 插件可以帮助我们生成需要的代码,在使用 Gradle 或 Maven 时,protoc 构建插件可以生成必要的代码作为构建的一部分。具体 maven 配置及代码生成步骤我们在 [上一节](/zh-cn/overview/mannual/java-sdk/tasks/protocols/triple/idl/) 中有具体的描述。 + +target/generated-sources/protobuf/java/org/apache/dubbo/samples/tri/streaming/ 目录中可以发现如下生成代码,其中我们将重点讲解 `DubboGreeterTriple.java`: + +``` +├── DubboGreeterTriple.java +├── Greeter.java +├── GreeterOuterClass.java +├── GreeterReply.java +├── GreeterReplyOrBuilder.java +├── GreeterRequest.java +└── GreeterRequestOrBuilder.java +``` + +### Server +首先,让我们看一下如何定义服务实现并启动提供者: +1. 实现 IDL 代码生成过程中定义的服务基类,提供自定义的业务逻辑。 +2. 运行 Dubbo 服务以侦听来自客户端的请求并返回服务响应。 + +#### 提供服务实现 GreeterImplBase +定义类 `GreeterImpl` 实现 `DubboGreeterTriple.GreeterImplBase`。 + +```java +public class GreeterImpl extends DubboGreeterTriple.GreeterImplBase { + // ... +} +``` +##### 服务端流 + +`GreeterImpl` 实现了所有 rpc 定义中的方法。接下里,我们看一下 server-side streaming 的具体定义。 + +不同于普通的方法定义,`serverStream` 方法有两个参数,第一个参数 `request` 是入参,第二个参数 `responseObserver` 为响应值,其参数类型是 `StreamObserver`。在方法实现中,我们不停的调用 `responseObserver.onNext(...)` 将结果发送回消费方,并在最后调用 `onCompleted()` 表示流式响应结束。 + +```java +@Override +public void serverStream(GreeterRequest request, StreamObserver responseObserver) { + LOGGER.info("receive request: {}", request.getName()); + for (int i = 0; i < 10; i++) { + GreeterReply reply = GreeterReply.newBuilder().setMessage("reply from serverStream. " + i).build(); + responseObserver.onNext(reply); + } + responseObserver.onCompleted(); +} +``` + +##### 双向流 +双向流方法 `biStream` 的参数和返回值都是 `StreamObserver<...>` 类型。但需要注意的是,它与我们传统方法定义中参数是请求值、返回值是响应的理解是反过来的,在这里,参数 `StreamObserver responseObserver` 是响应,我们通过 responseObserver 不停的写回响应。 + +请注意这里`请求流`与`响应流`是独立的,我们在写回响应流数据的过程中,随时可能有请求流到达,对于每个流而言,值都是有序的。 + +```java +@Override +public StreamObserver biStream(StreamObserver responseObserver) { + return new StreamObserver() { + @Override + public void onNext(GreeterRequest data) { + GreeterReply resp = GreeterReply.newBuilder().setMessage("reply from biStream " + data.getName()).build(); + responseObserver.onNext(resp); + } + + @Override + public void onError(Throwable throwable) { + + } + + @Override + public void onCompleted() { + + } + }; +} +``` + +#### 启动 server +启动 Dubbo 服务的过程与普通应用完全一致: + +```java +public static void main(String[] args) throws IOException { + ServiceConfig service = new ServiceConfig<>(); + service.setInterface(Greeter.class); + service.setRef(new GreeterImpl("tri-stub")); + + ApplicationConfig applicationConfig = new ApplicationConfig("tri-stub-server"); + applicationConfig.setQosEnable(false); + + DubboBootstrap bootstrap = DubboBootstrap.getInstance(); + bootstrap.application(applicationConfig) + .registry(new RegistryConfig(TriSampleConstants.ZK_ADDRESS)) + .protocol(new ProtocolConfig(CommonConstants.TRIPLE, TriSampleConstants.SERVER_PORT)) + .service(service) + .start(); +} +``` + +### Client +和普通的 Dubbo 服务调用一样,我们首先需要声明 rpc 服务引用: + +```java +public static void main(String[] args) throws IOException { + ReferenceConfig ref = new ReferenceConfig<>(); + ref.setInterface(Greeter.class); + ref.setProtocol(CommonConstants.TRIPLE); + + DubboBootstrap.getInstance().reference(ref).start(); + Greeter greeter = ref.get(); +} +``` + +接下来,我们就可以利用 `greeter` 像调用本地方法一样发起调用了。 + +#### 服务端流 +调用 `serverStream()` 传入能够处理流式响应的 `SampleStreamObserver` 对象,调用发起后即快速返回,之后流式响应会不停的发送到 `SampleStreamObserver`。 + +```java +GreeterRequest request = GreeterRequest.newBuilder().setName("server stream request.").build(); +greeter.serverStream(request, new SampleStreamObserver()); +``` + +以下是 `SampleStreamObserver` 类的具体定义,包含其收到响应后的具体处理逻辑。 + +```java +private static class SampleStreamObserver implements StreamObserver { + @Override + public void onNext(GreeterReply data) { + LOGGER.info("stream <- reply:{}", data); + } + + // ...... +} +``` + +#### 双向流 +调用 `greeter.biStream()` 方法会立即返回一个 `requestStreamObserver`,同时,需要为方法传入一个能处理响应的 observer 对象 `new SampleStreamObserver()`。 + +接下来,我们就可以用才刚才返回值中得到的 `requestStreamObserver` 持续发送请求 `requestStreamObserver.onNext(request)`;此时,如果有响应返回,则会由 `SampleStreamObserver` 接收处理,其定义请参考上文。 + +```java +StreamObserver requestStreamObserver = greeter.biStream(new SampleStreamObserver()); +for (int i = 0; i < 10; i++) { + GreeterRequest request = GreeterRequest.newBuilder().setName("name-" + i).build(); + requestStreamObserver.onNext(request); +} +requestStreamObserver.onCompleted(); +``` + +## 其他 +### Java接口模式下的流式通信 +对于不使用 Protobuf 的用户而言,你可以直接在接口中定义 streaming 格式的方法,这样你就能使用流式通信了。 + +#### 接口定义 +```java +public interface WrapperGreeter { + // 双向流 + StreamObserver sayHelloStream(StreamObserver response); + // 服务端流 + void sayHelloServerStream(String request, StreamObserver response); +} +``` + +其中,`org.apache.dubbo.common.stream.StreamObserver` 是 Dubbo 框架提供的流式通信参数类型,请务必按照以上示例所示的方式定义 + +> Stream 方法的方法入参和返回值是严格约定的,为防止写错而导致问题,Dubbo3 框架侧做了对参数的检查, 如果出错则会抛出异常。 +> 对于 `双向流(BIDIRECTIONAL_STREAM)`, 需要注意参数中的 `StreamObserver` 是响应流,返回参数中的 `StreamObserver` 为请求流。 + +#### 实现类 +```java +public class WrapGreeterImpl implements WrapGreeter { + + //... + + @Override + public StreamObserver sayHelloStream(StreamObserver response) { + return new StreamObserver() { + @Override + public void onNext(String data) { + System.out.println(data); + response.onNext("hello,"+data); + } + + @Override + public void onError(Throwable throwable) { + throwable.printStackTrace(); + } + + @Override + public void onCompleted() { + System.out.println("onCompleted"); + response.onCompleted(); + } + }; + } + + @Override + public void sayHelloServerStream(String request, StreamObserver response) { + for (int i = 0; i < 10; i++) { + response.onNext("hello," + request); + } + response.onCompleted(); + } +} +``` + +#### 调用方式 +```java +delegate.sayHelloServerStream("server stream", new StreamObserver() { + @Override + public void onNext(String data) { + System.out.println(data); + } + + @Override + public void onError(Throwable throwable) { + throwable.printStackTrace(); + } + + @Override + public void onCompleted() { + System.out.println("onCompleted"); + } +}); + + +StreamObserver request = delegate.sayHelloStream(new StreamObserver() { + @Override + public void onNext(String data) { + System.out.println(data); + } + + @Override + public void onError(Throwable throwable) { + throwable.printStackTrace(); + } + + @Override + public void onCompleted() { + System.out.println("onCompleted"); + } +}); +for (int i = 0; i < n; i++) { + request.onNext("stream request" + i); +} +request.onCompleted(); +``` diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/rate-limit/_index.md b/content/zh-cn/overview/mannual/java-sdk/tasks/rate-limit/_index.md new file mode 100755 index 000000000000..dc231b35c7aa --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/rate-limit/_index.md @@ -0,0 +1,11 @@ +--- +aliases: + - /zh/overview/tasks/rate-limit/ + - /zh-cn/overview/tasks/rate-limit/ +description: 演示 Dubbo 熔断、限流、降级等场景工作方式 +hide: true +linkTitle: 限流降级 +title: 限流降级 +type: docs +weight: 8 +--- diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/adaptive-concurrency-control.md b/content/zh-cn/overview/mannual/java-sdk/tasks/rate-limit/adaptive-concurrency-control.md similarity index 85% rename from content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/adaptive-concurrency-control.md rename to content/zh-cn/overview/mannual/java-sdk/tasks/rate-limit/adaptive-concurrency-control.md index 71629f8d3bf3..ebb60201fd1a 100644 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/adaptive-concurrency-control.md +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/rate-limit/adaptive-concurrency-control.md @@ -1,18 +1,16 @@ --- -description: 自适应限流 +description: "自适应限流,区别于普通限流策略,其具备自动调整限流策略是否生效、限流阈值的能力,heuristic flow control。" linkTitle: 自适应限流 title: 自适应限流 type: docs -weight: 28 +weight: 3 --- -## 功能说明 -自适应限流的设计与实现思路请参考 [Dubbo 自适应限流功能](../../../../../reference/proposals/heuristic-flow-control/)。自适应限流能够确保分布式系统稳定性和可靠性,例如在服务提供商资源有限且多变的场景下。 + +自适应限流的设计与实现思路请参考 [Dubbo 自适应限流功能](/zh-cn/overview/reference/proposals/heuristic-flow-control/#自适应限流)。自适应限流能够确保分布式系统稳定性和可靠性,例如在服务提供商资源有限且多变的场景下。 ## 使用场景 - 服务降级预防:当服务提供者因资源耗尽而性能下降时,使用自适应限流暂时减少其接受的请求数直至恢复正常。 - - 峰值流量处理:当服务流量突然激增时,自适应流量限制可以通过动态减少接受的请求数量来帮助防止服务过载。 - - 不可预测流量处理:服务提供商可能会遇到不可预测的流量,第三方应用程序使用服务时可能会偶尔产生流量,自适应流量限制可以根据当前系统负载调整允许的最大并发请求数并防止过载。 ## 使用方式 diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/rate-limit/concurrency-control.md b/content/zh-cn/overview/mannual/java-sdk/tasks/rate-limit/concurrency-control.md new file mode 100644 index 000000000000..46b9c13a30be --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/rate-limit/concurrency-control.md @@ -0,0 +1,101 @@ +--- +aliases: + - /zh/docs3-v2/java-sdk/advanced-features-and-usage/performance/concurrency-control/ + - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/performance/concurrency-control/ +description: "Dubbo 框架内置的并发控制或者限流策略,通过限制从同一客户端到同一服务的并发请求数,防止恶意请求使服务器过载,确保服务的稳定性,并防止使用过多资源。" +linkTitle: 框架内置限流 +title: Dubbo 框架内置的并发控制策略 +type: docs +weight: 2 +--- + +Dubbo 通过 Filter 拦截器机制,内置了并发控制策略实现。限制从同一客户端到同一服务的并发请求数,防止恶意请求使服务器过载,确保服务的稳定性,并防止使用过多资源。 + +* 控制某些服务的最大并发请求数,确保其他服务的资源可用性。系统过载和确保系统稳定性。 +* 允许在需求增加时更平滑地扩展服务。 +* 确保服务在高峰使用时间保持可靠和稳定。 + +{{% alert title="注意" color="warning" %}} +这种方式要求用户准确的预先评估系统能处理的并发数,而准确的评估系统处理能力并不是一件容易的事情,因此 Dubbo 还提供了自适应限流模式,根据系统负载自动识别系统健康程度并进行限流保护,可以在此查看 [自适应限流模式使用文档](../adaptive-concurrency-control)。 +{{% /alert %}} + +## 限流策略配置 +### 限制服务器端并发执行数(服务粒度) + +限制 `com.foo.BarService` 的每个方法,服务器端并发执行(或占用线程池线程数)不能超过 10 个 + +XML 方式: +```xml + +``` + +注解方式: +```java +@DubboService(executes=10) +private DemoServiceImpl implements DemoService{} +``` + +### 限制服务器端并发执行数(方法粒度) + +限制 `com.foo.BarService` 的 `sayHello` 方法,服务器端并发执行(或占用线程池线程数)不能超过 10 个 + +XML 方式: +```xml + + + +``` + +注解方式: +```java +@DubboService(executes=10, methods = {@Method(name="sayHello",executes=10)}) +private DemoServiceImpl implements DemoService{} +``` + +### 限制消费端并发调用数(服务粒度) + +限制 `com.foo.BarService` 的每个方法,每客户端并发执行(或占用连接的请求数)不能超过 10 个 + +XML 方式: +```xml + +``` + +注解方式: +```java +@DubboReference(actives=10) +private DemoService demoService; +``` + +### 限制消费端并发调用数(方法粒度) + +限制 `com.foo.BarService` 的 `sayHello` 方法,每客户端并发执行(或占用连接的请求数)不能超过 10 个 + +XML 方式: +```xml + + + +``` + +注解方式: +```java +@DubboReference(actives=10, methods = {@Method(name="sayHello",executes=10)}) +private DemoService demoService; +``` + +> 如果提供端 `@DubboService` 和消费端 `@DubboReference` 都配了 actives,则消费端配置值优先级更高,参见:[配置的覆盖策略](https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/config/principle/)。 + +## 最小并发数负载均衡 + +配置服务的客户端的 `loadbalance` 属性为 `leastactive`,此 Loadbalance 会调用并发数最小的 Provider(Consumer端并发数)。 + +```xml + +``` + +**或** + +```xml + +``` \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/rate-limit/sentinel.md b/content/zh-cn/overview/mannual/java-sdk/tasks/rate-limit/sentinel.md new file mode 100644 index 000000000000..c375214ec0aa --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/rate-limit/sentinel.md @@ -0,0 +1,228 @@ +--- +aliases: + - /zh-cn/overview/tasks/ecosystem/rate-limit/ + - /zh-cn/overview/what/ecosystem/rate-limit/ + - /zh-cn/overview/what/ecosystem/rate-limit/sentinel/ + - /zh/overview/tasks/rate-limit/sentinel/ + - /zh-cn/overview/tasks/rate-limit/sentinel/ +description: "使用 Sentinel 保护您的 Dubbo 应用,防止应用因个别服务的突发流量过载而出现稳定性问题。" +linkTitle: Sentinel限流 +title: 使用 Sentinel 应对突发流量,保护您的应用 +type: docs +weight: 1 +--- + +在复杂的生产环境下可能部署着成千上万的 Dubbo 服务实例,流量持续不断地进入,服务之间进行相互调用。但是分布式系统中可能会因流量激增、系统负载过高、网络延迟等一系列问题,导致某些服务不可用,如果不进行相应的控制可能导致级联故障,影响服务的可用性,因此如何对流量进行合理的控制,成为保障服务稳定性的关键。 + +[Sentinel](https://github.com/alibaba/Sentinel) 是阿里中间件团队开源的,面向分布式服务架构的轻量级流量控制产品,主要以流量为切入点,从**流量控制**、**熔断降级**、**系统负载保护**等多个维度来帮助用户保护服务的稳定性。 + +本文提供 Dubbo 整合 Sentinel 限流降级的最佳实践。 + +## 快速接入 Sentinel + +Sentinel 通过对服务提供方和服务消费方的限流提升服务在极端场景下的可用性,接下来我们看看 Sentinel 对服务提供方和服务消费方限流的技术实现方式。 + +使用时我们只需引入以下模块(以 Maven 为例): + +```xml + + com.alibaba.csp + sentinel-apache-dubbo3-adapter + 1.8.6 + + + + com.alibaba.csp + sentinel-transport-simple-http + 1.8.6 + +``` + +引入此依赖后,Dubbo 的服务接口和方法(包括调用端和服务端)就会成为 Sentinel 中的资源,在配置了规则后就可以自动享受到 Sentinel 的防护能力。 + +> `sentinel-apache-dubbo3-adapter` 中包含 Sentinel Filter 实现,加入依赖之后会自动开启。如若不希望开启 Sentinel Dubbo Adapter 中的某个 Filter,可通过配置关闭,如 `dubbo.provider.filter="-sentinel.dubbo.consumer.filter"`。 + + +## 示例详解 + +可在此查看以下 [示例的完整源码](https://github.com/apache/dubbo-samples/tree/master/4-governance/dubbo-samples-sentinel)。 + + +### Provider 端限流 + +对服务提供方的流量控制可分为 **服务提供方的自我保护能力** 和 **服务提供方对服务消费方的请求分配能力** 两个维度。 + + +#### 基于 QPS 设定限流 +为了保护 Provider 不被激增的流量拖垮影响稳定性,可以给 Provider 配置 **QPS 模式** 的限流,这样当每秒的请求量超过设定的阈值时会自动拒绝多出来的请求。 + +以下是示例中配置的 **服务级别** 的 QPS 限流配置,最大 QPS 设定为 10: + +```java +// Limit DemoService to 10 QPS +FlowRule flowRule = new FlowRule(); +// Note: the resource name here is the interface name. +flowRule.setResource(DemoService.class.getName()); +flowRule.setCount(10); +flowRule.setLimitApp("default"); +flowRule.setGrade(RuleConstant.FLOW_GRADE_QPS); +FlowRuleManager.loadRules(Collections.singletonList(flowRule)); +``` + +以下是示例中配置的 **方法级别** 的 QPS 限流配置,最大 QPS 设定为 5: + +```java +// Limit sayHelloAgain method to 10 QPS +FlowRule flowRule = new FlowRule(); +// Note: the resource name here includes the method signature. +flowRule.setResource(DemoService.class.getName() + ":sayHelloAgain(java.lang.String)"); +flowRule.setCount(5); +flowRule.setLimitApp("default"); +flowRule.setGrade(RuleConstant.FLOW_GRADE_QPS); +FlowRuleManager.loadRules(Collections.singletonList(flowRule)); +``` + +启动消费端进程并持续发起调用,以下是限流生效后 provider 端打印的日志: + +``` +2018-07-24 17:13:43|1|com.alibaba.csp.sentinel.demo.dubbo.FooService:sayHello(java.lang.String),FlowException,default,|5,0 +``` + +在 Provider 对应的 metrics 日志中也有记录: + +``` +1532423623000|2018-07-24 17:13:43|com.alibaba.csp.sentinel.demo.dubbo.FooService|15|0|15|0|3 +1532423623000|2018-07-24 17:13:43|com.alibaba.csp.sentinel.demo.dubbo.FooService:sayHello(java.lang.String)|10|5|10|0|0 +``` + +#### 基于 QPS 限流(针对特定消费者) + +上一节中的 QPS 限流值是针对所有消费端流量的,你也可以对来自特定消费端(以 dubbo 应用名识别)的 QPS 进行限流,通过设置 `flowRule.setLimitApp("sentinel-consumer");` 即可,其中 `sentinel-consumer` 为发起调用的消费端应用名: + +```java +//...... +// Note: this will take effect only for the specific consumer whose app name is "sentinel-consumer". +flowRule.setLimitApp("sentinel-consumer"); +flowRule.setGrade(RuleConstant.FLOW_GRADE_QPS); +FlowRuleManager.loadRules(Collections.singletonList(flowRule)); +``` + +在限流日志中会也会记录调用方的名称,如下面的日志中的 `sentinel-consumer` 即为调用方名称: + +``` +2018-07-25 16:26:48|1|com.alibaba.csp.sentinel.demo.dubbo.FooService:sayHello(java.lang.String),FlowException,default,demo-consumer|5,0 +``` + +> 注意:为了使 `limitApp` 生效,开发者需要调用调用 `RpcContext.getContext.setAttachment("dubboApplication", "sentinel-consumer")` 标识自己的身份,如果消费端引入了 `sentinel-apache-dubbo3-adapter` 则不需要额外调用以上方法了。 + +#### 设置限流发生后执行的方法 + +调用 `DubboAdapterGlobalConfig.setProviderFallback()` 可以设置限流发生后的方法回调,这样就能在限流后做更多的定制动作。 + +```java +DubboAdapterGlobalConfig.setProviderFallback((invoker, invocation, ex) -> { + System.out.println("Blocked by Sentinel: " + ex.getClass().getSimpleName() + ", " + invocation); + return AsyncRpcResult.newDefaultAsyncResult(ex.toRuntimeException(), invocation); +}); +``` + +### Consumer 端限流 + +对服务消费方的流量控制可分为 **控制并发线程数** 和 **服务降级** 两个维度。 + +#### 并发线程数限流 + +推荐给 Consumer 配置**线程数模式**限流,来保证自身不被不稳定服务所影响。采用基于线程数的限流模式后,我们不需要再显式地去进行线程池隔离,Sentinel 会控制资源的线程数,超出的请求直接拒绝,直到堆积的线程处理完成,可以达到**信号量隔离**的效果。 + + +以下方法设置消费端的最大并发线程数,方法 `sayHelloConsumerFlowControl` 的并发调用在超过 3 个线程时就会发生限流: + +```java +FlowRule flowRule = new FlowRule(); +flowRule.setResource("org.apache.dubbo.samples.sentinel.DemoService:sayHelloConsumerFlowControl(java.lang.String)"); +flowRule.setCount(3); +flowRule.setGrade(RuleConstant.FLOW_GRADE_THREAD); +FlowRuleManager.loadRules(Collections.singletonList(flowRule)); +``` + +通过调用以下方法,可以设置限流发生时的回调方法(可选): + +```java +DubboAdapterGlobalConfig.setConsumerFallback((invoker, invocation, ex) -> { + System.out.println("Blocked by Sentinel: " + ex.getClass().getSimpleName() + ", " + invocation); + return AsyncRpcResult.newDefaultAsyncResult(ex.toRuntimeException(), invocation); +}); +``` + +#### 服务熔断降级 + +当服务依赖于多个下游服务,而某个下游服务调用非常慢时,会严重影响当前服务的调用。这里我们可以利用 Sentinel 熔断降级的功能,为调用端配置基于平均 RT 的[降级规则](https://github.com/alibaba/Sentinel/wiki/%E7%86%94%E6%96%AD%E9%99%8D%E7%BA%A7)。这样当调用链路中某个服务调用的平均 RT 升高,在一定的次数内超过配置的 RT 阈值,Sentinel 就会对此调用资源进行降级操作,接下来的调用都会立刻拒绝,直到过了一段设定的时间后才恢复,从而保护服务不被调用端短板所影响。同时可以配合 fallback 功能使用,在被降级的时候提供相应的处理逻辑。 + +以下方法设置 `sayHelloConsumerDowngrade` 的降级策略,当接口调用失败率达到 70% 时,方法调用自动降级: + +```java +@Component +static class SentinelDowngradeConfig implements CommandLineRunner { + @Override + public void run(String... args) { + List rules = new ArrayList<>(); + DegradeRule rule = new DegradeRule(); + rule.setResource("org.apache.dubbo.samples.sentinel.DemoService:sayHelloConsumerDowngrade(java.lang.String)"); + rule.setGrade(CircuitBreakerStrategy.ERROR_RATIO.getType()); + rule.setCount(0.7); // Threshold is 70% error ratio + rule.setMinRequestAmount(100); + rule.setStatIntervalMs(30000); // 30s + rule.setTimeWindow(10); + rules.add(rule); + DegradeRuleManager.loadRules(rules); + } +} +``` + +## Sentinel控制台 + +Sentinel 的控制台可以作为流量控制、熔断降级规则统一配置和管理的入口,同时它为用户提供了多个维度的监控功能。在 Sentinel 控制台上: +* 动态下发配置规则并实时查看流量控制效果 +* 查看机器列表以及健康情况 + + +### 应用如何接入控制台 +接入 Sentinel 控制台的步骤如下(**缺一不可**): + +1. 按照 [Sentinel 控制台文档](https://github.com/alibaba/Sentinel/wiki/%E6%8E%A7%E5%88%B6%E5%8F%B0) 启动控制台 +2. 应用引入 `sentinel-transport-simple-http` 依赖,以便控制台可以拉取对应应用的相关信息 +3. 给应用添加相关的启动参数,启动应用。需要配置的参数有: + - `-Dcsp.sentinel.api.port`:客户端的 port,用于上报相关信息(默认为 8719) + - `-Dcsp.sentinel.dashboard.server`:控制台的地址 + - `-Dproject.name`:应用名称,会在控制台中显示 + + +这样在启动应用后就能在控制台找到对应的应用了。 + +### 控制台功能简介 + +- **单台设备监控**:当在机器列表中看到您的机器,就代表着已经成功接入控制台,可以查看单台设备的设备名称、IP地址、端口号、健康状态和心跳时间等信息。 + +![sentinel-dashboard](/imgs/v3/tasks/sentinel/dashboard-1.png) + +- **链路监控**:簇点链路实时的去拉取指定客户端资源的运行情况,它提供了两种展示模式,一种用书状结构展示资源的调用链路;另外一种则不区分调用链路展示资源的运行情况。通过链路监控,可以查看到每个资源的流控和降级的历史状态。 + +树状链路 + +![sentinel-dashboard](/imgs/v3/tasks/sentinel/dashboard-2.png) + +平铺链路 + +![sentinel-dashboard](/imgs/v3/tasks/sentinel/dashboard-3.png) + +- **聚合监控**:同一个服务下的所有机器的簇点信息会被汇总,实现实时监控,精确度达秒级。 + +![sentinel-dashboard](/imgs/v3/tasks/sentinel/dashboard-4.png) + +- **规则配置**:可以查看已有的限流、降级和系统保护规则,并实时地进行配置。 + +![sentinel-dashboard](/imgs/v3/tasks/sentinel/dashboard-5.png) + +## 参考链接 + +关于 Sentinel 的更多使用方式可以参考 [Sentinel 官网](https://sentinelguard.io/zh-cn/index.html) diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/security/_index.md b/content/zh-cn/overview/mannual/java-sdk/tasks/security/_index.md new file mode 100755 index 000000000000..8a213e0f2de8 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/security/_index.md @@ -0,0 +1,10 @@ +--- +aliases: + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/security/ +description: 演示 Dubbo 配置安全策略的方式 +hide: true +linkTitle: 安全策略 +title: 安全策略 +type: docs +weight: 12 +--- diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/security/auth.md b/content/zh-cn/overview/mannual/java-sdk/tasks/security/auth.md similarity index 94% rename from content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/security/auth.md rename to content/zh-cn/overview/mannual/java-sdk/tasks/security/auth.md index d3e8b6cd17d7..aa3fe59d48b8 100644 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/security/auth.md +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/security/auth.md @@ -2,6 +2,7 @@ aliases: - /zh/docs3-v2/java-sdk/advanced-features-and-usage/security/auth/ - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/security/auth/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/security/auth/ description: 了解 Dubbo 服务鉴权 linkTitle: 服务鉴权 title: 服务鉴权 @@ -47,4 +48,4 @@ weight: 23 ### 服务消费端 只需要配置好对应的证书等信息即可,之后会自动地在对这些需要认证的接口发起调用前进行签名操作,通过与鉴权服务的交互,用户无需在代码中配置 AK/SK 这些敏感信息,并且在不重启应用的情况下刷新 AK/SK,达到权限动态下发的目的。 -> 该方案目前已经提交给 Dubbo 开源社区,并且完成了基本框架的合并,除了 AK/SK 的鉴权方式之外,通过 SPI 机制支持用户可定制化的鉴权认证以及适配公司内部基础设施的密钥存储。 \ No newline at end of file +> 该方案目前已经提交给 Dubbo 开源社区,并且完成了基本框架的合并,除了 AK/SK 的鉴权方式之外,通过 SPI 机制支持用户可定制化的鉴权认证以及适配公司内部基础设施的密钥存储。 diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/security/class-check.md b/content/zh-cn/overview/mannual/java-sdk/tasks/security/class-check.md similarity index 98% rename from content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/security/class-check.md rename to content/zh-cn/overview/mannual/java-sdk/tasks/security/class-check.md index 3f28338a7030..56b12c0153fd 100644 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/security/class-check.md +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/security/class-check.md @@ -2,6 +2,7 @@ aliases: - /zh/docs3-v2/java-sdk/advanced-features-and-usage/security/class-check/ - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/security/class-check/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/security/class-check/ description: 了解 Dubbo 类检查机制 linkTitle: 类检查机制 title: 类检查机制 diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/security/tls.md b/content/zh-cn/overview/mannual/java-sdk/tasks/security/tls.md similarity index 90% rename from content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/security/tls.md rename to content/zh-cn/overview/mannual/java-sdk/tasks/security/tls.md index 8d980a5c6fe4..06ae0537e3c8 100644 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/security/tls.md +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/security/tls.md @@ -2,11 +2,13 @@ aliases: - /zh/docs3-v2/java-sdk/advanced-features-and-usage/security/tls/ - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/security/tls/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/security/tls/ + - /zh-cn/overview/mannual/java-sdk/reference-manual/protocol/tls/ description: ' 了解在 Dubbo 的 TLS 保证传输安全' linkTitle: TLS支持 title: TLS支持 type: docs -weight: 1 +weight: 10 --- @@ -59,4 +61,4 @@ if (!mutualTls) {} 为尽可能保证应用启动的灵活性,TLS Cert 的指定还能通过 -D 参数或环境变量等方式来在启动阶段根据部署环境动态指定,参考 Dubbo [配置读取规则](/zh-cn/docs/advanced/config-rule) -> 在服务调用的安全性上,Dubbo 在后续的版本中会持续投入,其中服务发现/调用的鉴权机制预计在接下来的版本中就会和大家见面。 \ No newline at end of file +> 在服务调用的安全性上,Dubbo 在后续的版本中会持续投入,其中服务发现/调用的鉴权机制预计在接下来的版本中就会和大家见面。 diff --git a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/security/token-authorization.md b/content/zh-cn/overview/mannual/java-sdk/tasks/security/token-authorization.md similarity index 92% rename from content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/security/token-authorization.md rename to content/zh-cn/overview/mannual/java-sdk/tasks/security/token-authorization.md index 6376462295c6..24b380af2887 100644 --- a/content/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/security/token-authorization.md +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/security/token-authorization.md @@ -2,6 +2,7 @@ aliases: - /zh/docs3-v2/java-sdk/advanced-features-and-usage/security/token-authorization/ - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/security/token-authorization/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/security/token-authorization/ description: 了解 Dubbo 权限控制的配置和使用 linkTitle: 权限控制 title: 权限控制 @@ -55,4 +56,4 @@ weight: 2 ```xml -``` \ No newline at end of file +``` diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/service-discovery/_index.md b/content/zh-cn/overview/mannual/java-sdk/tasks/service-discovery/_index.md new file mode 100755 index 000000000000..26f412b27334 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/service-discovery/_index.md @@ -0,0 +1,10 @@ +--- +aliases: + - /zh/docs3-v2/java-sdk/advanced-features-and-usage/others/ + - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/others/ +description: 注册中心与服务发现 +linkTitle: 服务发现 +title: 注册中心、服务发现与负载均衡 +type: docs +weight: 4 +--- diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/service-discovery/kubernetes.md b/content/zh-cn/overview/mannual/java-sdk/tasks/service-discovery/kubernetes.md new file mode 100644 index 000000000000..69278d23c6c3 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/service-discovery/kubernetes.md @@ -0,0 +1,25 @@ +--- +aliases: + - /zh/docs3-v2/java-sdk/advanced-features-and-usage/performance/loadbalance/ + - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/performance/loadbalance/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/others/graceful-shutdown/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/consistent-hash/ +description: "通过示例演示基于 Kubernetes Service 的服务发现模式。" +linkTitle: 使用Kubernetes注册中心 +title: 基于 Kubernetes Service 的服务发现 +type: docs +weight: 5 +--- + +上面两节我们分别讲解了 Nacos、Zookeeper 两种注册中心模式,它们更像是传统的注册中心解决方案。在 Kubernetes 部署环境下,Dubbo 支持基于 Kubernetes Service 的服务发现模式,其基本工作原理如下图所示: + + + +在这种模式下,服务发现与用户的部署运维操作形成统一,用户定义标准的 Kubernetes Service、Deployment,并将其部署到 Kubernetes,之后 Control Plane 通过监控 APISERVER 资源并与 SDK 进程联动,形成一整套的服务发现体系。 + +关于使用 Kubernetes 作为注册中心的具体实践案例,请参考 [Kubernetes Service 部署]() 一节了解更多细节。 + + + + + diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/service-discovery/loadbalance.md b/content/zh-cn/overview/mannual/java-sdk/tasks/service-discovery/loadbalance.md new file mode 100644 index 000000000000..a373e96ae62d --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/service-discovery/loadbalance.md @@ -0,0 +1,120 @@ +--- +aliases: + - /zh/docs3-v2/java-sdk/advanced-features-and-usage/performance/loadbalance/ + - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/performance/loadbalance/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/others/graceful-shutdown/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/consistent-hash/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/performance/loadbalance/ +description: "Dubbo 支持的消费端负载均衡策略及其使用方法" +linkTitle: 负载均衡 +title: 负载均衡策略与配置细节 +type: docs +weight: 1 +--- + +Dubbo 内置了 client-based 负载均衡机制,如下是当前支持的负载均衡算法,结合上文提到的自动服务发现机制,消费端会自动使用 `Weighted Random LoadBalance 加权随机负载均衡策略` 选址调用。 + +如果要调整负载均衡算法,以下是 Dubbo 框架内置的负载均衡策略: + +| 算法 | 特性 | 备注 | 配置值 | +| :-------------------------- | :---------------------- | :---------------------------------------------- | :---------------------------------------------- | +| Weighted Random LoadBalance | 加权随机 | 默认算法,默认权重相同 | random (默认) | +| RoundRobin LoadBalance | 加权轮询 | 借鉴于 Nginx 的平滑加权轮询算法,默认权重相同 | roundrobin | +| LeastActive LoadBalance | 最少活跃优先 + 加权随机 | 背后是能者多劳的思想 | leastactive | +| Shortest-Response LoadBalance | 最短响应优先 + 加权随机 | 更加关注响应速度 | shortestresponse | +| ConsistentHash LoadBalance | 一致性哈希 | 确定的入参,确定的提供者,适用于有状态请求 | consistenthash | +| P2C LoadBalance | Power of Two Choice | 随机选择两个节点后,继续选择“连接数”较小的那个节点。 | p2c | +| Adaptive LoadBalance | 自适应负载均衡 | 在 P2C 算法基础上,选择二者中 load 最小的那个节点 | adaptive | + +## 全局配置 +Dubbo 框架的默认策略是 `random` 加权随机负载均衡。如果要调整策略,只需要设置 `loadbalance` 相应取值即可,每种负载均衡策略取值请参见文档最上方表格。 + +为所有服务调用指定全局配置: +```yaml +dubbo: + consumer: + loadbalance: roundrobin +``` + +## 接口级配置 +可以为每个服务指定不同的负载均衡策略。 + +在 provider 端设置,作为 consumer 侧默认值 +```java +@DubboService(loadbalance = "roundrobin") +public class DemoServiceImpl implements DemoService {} +``` + +在 consumer 端设置,具备更高优先级 +```java +@DubboReference(loadbalance = "roundrobin") +private DemoService demoService; +``` + +## 方法级配置 +也可以指定方法(method)级别的负载均衡策略。 + +在 Spring Boot 开发模式下,配置 method 级别参数有以下几种方式: + +**JavaConfig** +```java +@Configuration +public class DubboConfiguration { + @Bean + public ServiceBean demoService() { + MethodConfig method = new MethodConfig(); + method.setName("sayHello"); + method.setLoadbalance("roundrobin"); + + ServiceBean service = new ServiceBean(); + service.setInterface(DemoService.class); + service.setRef(new DemoServiceImpl()); + service.addMethod(method) + return service; + } +} +``` + +```java +@Autowire +private DemoService demoService; + +@Configuration +public class DubboConfiguration { + @Bean + public ReferenceBean demoService() { + MethodConfig method = new MethodConfig(); + method.setName("sayHello"); + method.setLoadbalance("roundrobin"); + + ReferenceBean reference = new ReferenceBean<>(); + reference.setInterface(DemoService.class); + reference.addMethod(method); + return reference; + } +} +``` + +**dubbo.properties** +```properties +dubbo.reference.org.apache.dubbo.samples.api.DemoService.sayHello.loadbalance=roundrobin +``` + +## 一致性哈希配置 + +默认采用第一个参数作为哈希 key,如果需要切换参数,可以指定 `hash.arguments` 属性 + +```java +ReferenceConfig referenceConfig = new ReferenceConfig(); +// ... init +Map parameters = new HashMap(); +parameters.put("hash.arguments", "1"); +parameters.put("sayHello.hash.arguments", "0,1"); +referenceConfig.setParameters(parameters); +referenceConfig.setLoadBalance("consistenthash"); +referenceConfig.get(); +``` + +## 自适应负载均衡配置 + +只需要在 consumer 或 provider 端将 `loadbalance` 设置为 `p2c` 或者 `adaptive` 即可,可在此查看 [工作原理](/zh-cn/overview/reference/proposals/heuristic-flow-control) diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/service-discovery/nacos.md b/content/zh-cn/overview/mannual/java-sdk/tasks/service-discovery/nacos.md new file mode 100644 index 000000000000..871130d721c7 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/service-discovery/nacos.md @@ -0,0 +1,219 @@ +--- +aliases: + - /zh/docs3-v2/java-sdk/advanced-features-and-usage/performance/loadbalance/ + - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/performance/loadbalance/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/others/graceful-shutdown/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/consistent-hash/ +description: "通过示例演示如何使用 Nacos 作为注册中心实现自动服务发现。" +linkTitle: 使用Nacos注册中心 +title: 使用 Nacos 作为注册中心实现自动服务发现 +type: docs +weight: 4 +--- + +本示例演示 Nacos 作为注册中心实现自动服务发现,示例基于 Spring Boot 应用展开,可在此查看 [完整示例代码](https://github.com/apache/dubbo-samples/tree/master/3-extensions/registry/dubbo-samples-nacos) + +## 1 基本配置 + +### 1.1 增加依赖 +增加 dubbo、nacos-client 依赖: +```xml + + + org.apache.dubbo + dubbo + 3.3.0 + + + com.alibaba.nacos + nacos-client + 2.1.0 + + +``` + +对于 Spring Boot 应用,可以使用如下 spring-boot-starter: +```xml + + org.apache.dubbo + dubbo-spring-boot-starter + 3.3.0 + + + org.apache.dubbo + dubbo-nacos-spring-boot-starter + 3.3.0 + +``` + +### 1.2 Nacos 版本 +Nacos 版本映射关系: +| Dubbo | 推荐 Nacos 版本 | Nacos 兼容范围 | +| --- | --- | --- | +| 3.3.0 | 2.2.3 | 2.x | +| 3.2.21 | 2.1.0 | 2.x | +| 3.1.11 | 2.0.9 | 2.x | +| 3.0.10 | 2.0.9 | 2.x | +| 2.7.21 | 1.x | 1.x | +| 2.6.0 | 1.x | 1.x | + +### 1.3 配置并启用 Nacos + +```yaml +# application.yml (Spring Boot) +dubbo + registry + address: nacos://localhost:8848 + register-mode: instance # 新用户请设置此值,表示启用应用级服务发现,可选值 interface、instance、all,默认值为 all,未来版本将切换默认值为 instance +``` +或 +```properties +# dubbo.properties +dubbo.registry.address=nacos://localhost:8848 +dubbo.registry.register-mode=instance +``` +或 +```xml + +``` + +## 2 高级配置 + +### 2.1 认证 + +```yaml +# application.yml (Spring Boot) +dubbo + registry + address: nacos://localhost:8848?username=nacos&password=nacos + register-mode: instance +``` + +或 + +```properties +# dubbo.properties +dubbo.registry.address: nacos://nacos:nacos@localhost:8848 +# 新用户请设置此值,表示启用应用级服务发现,可选值 interface、instance、all,默认值为 all,未来版本将切换默认值为 instance +dubbo.registry.register-mode=instance +``` + +### 2.2 自定义命名空间 + +```yaml +# application.yml (Spring Boot) +dubbo: + registry: + address: nacos://localhost:8848?namespace=5cbb70a5-xxx-xxx-xxx-d43479ae0932 + register-mode: instance # 新用户请设置此值,表示启用应用级服务发现,可选值 interface、instance、all +``` + +或者 + +```yaml +# application.yml (Spring Boot) +dubbo: + registry: + address: nacos://localhost:8848 + register-mode: instance # 新用户请设置此值,表示启用应用级服务发现,可选值 interface、instance、all + parameters.namespace: 5cbb70a5-xxx-xxx-xxx-d43479ae0932 +``` + +### 2.3 自定义分组 + +```yaml +# application.yml +dubbo: + registry: + address: nacos://localhost:8848 + register-mode: instance # 新用户请设置此值,表示启用应用级服务发现,可选值 interface、instance、all + group: dubbo +``` + +> 如果不配置的话,group 是由 Nacos 默认指定。group 和 namespace 在 Nacos 中代表不同的隔离层次,通常来说 namespace 用来隔离不同的用户或环境,group 用来对同一环境内的数据做进一步归组。 + +### 2.4 注册接口级消费者 +Dubbo 3.0.0 版本以后,增加了是否注册消费者的参数,如果需要将消费者注册到 nacos 注册中心上,需要将参数(register-consumer-url)设置为true,默认是false。 +```yaml +# application.yml +dubbo: + registry: + register-mode: instance # 新用户请设置此值,表示启用应用级服务发现,可选值 interface、instance、all + address: nacos://localhost:8848?register-consumer-url=true +``` +或者 +```yaml +# application.yml +dubbo: + registry: + address: nacos://localhost:8848 + register-mode: instance # 新用户请设置此值,表示启用应用级服务发现,可选值 interface、instance、all + parameters.register-consumer-url: true +``` + +### 2.5 更多配置 + +参数名 | 中文描述| 默认值 +---|---|--- +username|连接Nacos Server的用户名|nacos +paasword|连接Nacos Server的密码|nacos +backup|备用地址|空 +namespace|命名空间的ID|public +group|分组名称|DEFAULT_GROUP +register-consumer-url|是否注册消费端|false +com.alibaba.nacos.naming.log.filename|初始化日志文件名|naming.log +endpoint|连接Nacos Server指定的连接点,可参考[文档](https://nacos.io/zh-cn/blog/address-server.html)|空 +endpointPort|连接Nacos Server指定的连接点端口,可以参考[文档](https://nacos.io/zh-cn/blog/address-server.html)|空 +endpointQueryParams|endpoint查参数询|空 +isUseCloudNamespaceParsing|是否解析云环境中的namespace参数|true +isUseEndpointParsingRule|是否开启endpoint 参数规则解析|true +namingLoadCacheAtStart|启动时是否优先读取本地缓存|true +namingCacheRegistryDir|指定缓存子目录,位置为 .../nacos/{SUB_DIR}/naming|空 +namingClientBeatThreadCount|客户端心跳的线程池大小|机器的CPU数的一半 +namingPollingThreadCount|客户端定时轮询数据更新的线程池大小|机器的CPU数的一半 +namingRequestDomainMaxRetryCount|client通过HTTP向Nacos Server请求的重试次数|3 +namingPushEmptyProtection|在服务没有有效(健康)实例时,是否开启保护,开启后则会使用旧的服务实例|false +push.receiver.udp.port|客户端UDP的端口|空 + +在nacos-server@`1.0.0`版本后,支持客户端通过上报一些包含特定的元数据的实例到服务端来控制实例的一些行为。 + +参数名 | 中文描述| 默认值 +---|---|--- +preserved.heart.beat.timeout|该实例在不发送心跳后,从健康到不健康的时间(毫秒)|15000 +preserved.ip.delete.timeout|该实例在不发送心跳后,被服务端下掉该实例的时间(毫秒)|30000 +preserved.heart.beat.interval|该实例在客户端上报心跳的间隔时间(毫秒)|5000 +preserved.instance.id.generator|该实例的id生成策略,值为`snowflake`时,从0开始增加|simple +preserved.register.source|注册实例注册时服务框架类型(例如Dubbo,Spring Cloud等)|空 + + 这些参数都可以类似 `namespace` 的方式通过通过参数扩展配置到 Nacos,如 + + ```properties + dubbo.registry.parameters.preserved.heart.beat.timeout=5000 + ``` + +## 3 工作原理 + +在前面的一节中,我们讲解了应用级服务发现与接口级服务发现的区别,以下是两种模式在 Nacos 实现中的具体存储结构。 + +### 3.1 Dubbo2 注册数据 + +随后,重启您的 Dubbo 应用,Dubbo 的服务提供和消费信息在 Nacos 控制台中可以显示: + +![dubbo-registry-nacos-1.png](/imgs/blog/dubbo-registry-nacos-1.png) + +如图所示,服务名前缀为 `providers:` 的信息为服务提供者的元信息,`consumers:` 则代表服务消费者的元信息。点击“**详情**”可查看服务状态详情: + +![image-dubbo-registry-nacos-2.png](/imgs/blog/dubbo-registry-nacos-2.png) + +### 3.2 Dubbo3 注册数据 +应用级服务发现的 "服务名" 为应用名 + +> Dubbo3 默认采用 "应用级服务发现 + 接口级服务发现" 的双注册模式,因此会发现应用级服务(应用名)和接口级服务(接口名)同时出现在 Nacos 控制台,可以通过配置 `dubbo.registry.register-mode=instance/interface/all` 来改变注册行为。 + +### 3.3 客户端缓存 + +### 3.4 心跳检测 + +### 3.5 + + diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/service-discovery/registry.md b/content/zh-cn/overview/mannual/java-sdk/tasks/service-discovery/registry.md new file mode 100644 index 000000000000..667c3cb0d22f --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/service-discovery/registry.md @@ -0,0 +1,273 @@ +--- +aliases: + - /zh/docs3-v2/java-sdk/advanced-features-and-usage/performance/loadbalance/ + - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/performance/loadbalance/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/others/graceful-shutdown/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/consistent-hash/ +description: "Dubbo 服务发现的工作方式、基本使用方法与配置细节,涵盖延迟注册、优雅上下线、启动时检查、断网恢复、推空保护等。" +linkTitle: 服务发现 +title: 服务发现的工作方式、基本使用方法与配置细节 +type: docs +weight: 1 +--- +Dubbo 支持基于注册中心的自动实例发现机制,即 Dubbo 提供者注册实例地址到注册中心,Dubbo 消费者通过订阅注册中心变更事件自动获取最新实例变化,从而确保流量始终转发到正确的节点之上。Dubbo 目前支持 Nacos、Zookeeper、Kubernetes Service 等多种注册中心接入。 + +## 注册中心 +以下是 Dubbo 服务发现接入的一些主流注册中心实现,更多扩展实现与工作原理请查看 [注册中心参考手册](/zh-cn/overview/mannual/java-sdk/reference-manual/registry/overview/): + +| 注册中心 | 配置值 | 服务发现模型 | 是否支持鉴权 | spring-boot-starter | +| --- | --- | --- | --- | --- | +| Nacos | nacos | 应用级、接口级 | 是 | dubbo-nacos-spring-boot-starter | +| Zookeeper | zookeeper | 应用级、接口级 | 是 | - dubbo-zookeeper-spring-boot-starter
- dubbo-zookeeper-curator5-spring-boot-starter | +| Kubernetes Service | 参考独立使用文档 | 应用级 | 是 | 无 | + +## 延迟注册 +如果你的服务需要预热时间,比如初始化缓存、等待相关资源就位等,可以使用 `delay` 参数进行延迟注册。如果是在 Spring 应用中,则 `delay = n(n > 0)` 延迟的时间是 Spring 上下文初始化完成后开始算起。 + +```java +@DubboService(delay = 5000) +public class DemoServiceImpl implements DemoService { +} +``` + +以上配置后,应用将延迟 5 秒暴露此服务(应用启动 5s 后发布该服务到注册中心)。或者可以配置全局默认值,让所有服务都延迟 5s 后注册: + +```yaml +dubbo: + provider: + delay: 5000 +``` + +{{% alert title="手动注册" color="warning" %}} +通过配置 `delay = -1`,可以禁止框架自动发布服务到注册中心,直到用户通过调用 [online](/zh-cn/overview/mannual/java-sdk/reference-manual/qos/qos-list/) 等命令手动完成发布,可以用这个特性配合部署系统实现服务的优雅上线,让用户对上线时机有更好的控制。具体配置如下: + +```yaml +dubbo: + provider: + delay: -1 + application: + manual-register: true +``` +{{% /alert %}} + +## 优雅上下线 +通过控制服务实例发布到注册中心、从注册中心摘除的时机,可以让每个实例平滑的处理所有运行中的请求,做到部署期间的流量无损。以下是推荐的上下线操作顺序: + +### 优雅上线 +1. 配置实例地址延迟(或手动)注册,具体请参考上一节的延迟注册配置方式。 +2. 消费端收到新注册的地址实例后,会对新实例进行预热,即以一定的比例分配少部分流量到新实例,逐步增加比例直到与其他实例对等。 + + 预热的计算主要有两个因素,第一个是实例启动时间 timestamp,第二个是预热的总时长 warmup,预热总时长可通过 `` 参数设置。计算公式类似: + + + +### 优雅下线 +优雅下线的推荐步骤如下: +1. 在尝试停止 Dubbo 进程之前,先调用 [offline](/zh-cn/overview/mannual/java-sdk/reference-manual/qos/qos-list/) 从注册中心摘除实例地址(建议操作完成后额外等待几秒钟,以确保注册中心地址下线事件生效)。 +2. 通过 `kill pid` 尝试停止 Dubbo 进程,此时框架会依次检查以下环节: + * 2.1 框架向所有消费方(通过遍历其持有的 channel 链接)发送 readonly 事件,收到事件的消费方将会停止往该实例发送新的请求。此动作默认开启。 + * 2.2 框架会等待一定的时间,等待线程池中所有运行中的请求处理完成,默认是 `10000` 毫秒,可通过 `-Ddubbo.service.shutdown.wait=20000` 调整等待时间。 +3. 以上步骤执行完成后,Dubbo 进程自动停止。 + +{{% alert title="注意" color="info" %}} +有些场景下,需要在代码中控制地址注册、摘除的时机,可以通过调用以下代码实现: + +```java + +``` + +```java + +``` +{{% /alert %}} + +## 多注册中心 +Dubbo 支持在同一应用内配置多个注册中心,一个或一组服务可同时注册到多个注册中心,一个或一组服务可同时订阅多个中心的地址,对于订阅方而言,还可以设置如何调用来自多个注册中心的地址(优先调用某一个注册中心或者其他策略)。 + +指定全局默认的一个或多个注册中心,所有的服务默认都注册到或订阅配置的注册中心: +```yaml +dubbo + registries + beijingRegistry + register-mode: instance #新用户建议使用,老用户如继续使用老服务发现模型则删除此配置 + address: zookeeper://localhost:2181 + shanghaiRegistry + register-mode: instance #新用户建议使用,老用户如继续使用老服务发现模型则删除此配置 + address: zookeeper://localhost:2182 +``` + +指定某个服务注册到多个注册中心: + +```java +@DubboService(registry = {"beijingRegistry"}) +public class DemoServiceImpl implements DemoService {} +``` + +指定某个服务订阅来自多个注册中心的地址: + +```java +@DubboReference(registry = {"beijingRegistry"}) +private DemoService demoService +``` + +关于多注册中心的更多配置、使用场景说明请参见[【参考手册 - 注册中心 - 多注册中心】](/zh-cn/overview/mannual/java-sdk/reference-manual/registry/multiple-registry/) + +## 应用级vs接口级 +Dubbo3 在兼容 Dubbo2 `接口级服务发现`的同时,定义了新的`应用级服务发现`模型,关于它们的含义与工作原理请参考 [应用级服务发现](/zh-cn/overview/mannual/java-sdk/reference-manual/registry/service-discovery-application-vs-interface/)。Dubbo3 具备自动协商服务发现模型的能力,因此老版本 Dubbo2 用户可以无缝升级 Dubbo3。 + +{{% alert title="注意" color="warning" %}} +如果你是 Dubbo 新用户,强烈建议增加以下配置项目,以明确指示框架使用应用级服务发现: +```yml +dubbo: + registry: + address: "nacos://127.0.0.1:8848" + register-mode: instance # 新用户请设置此值,表示启用应用级服务发现,可选值 interface、instance、all +``` + +老用户均建议参考 [应用级服务发现迁移指南](/zh-cn/overview/mannual/java-sdk/reference-manual/upgrades-and-compatibility/migration-service-discovery/) 完成平滑迁移。 +{{% /alert %}} + +## 只注册 +如果有两个镜像环境,两个注册中心,有一个服务只在其中一个注册中心有部署,另一个注册中心还没来得及部署,而两个注册中心的其它应用都需要依赖此服务。这个时候,可以让服务提供者方只注册服务到另一注册中心,而不从另一注册中心订阅服务。该机制通常用于提供程序相对静态且不太可能更改的场景或者提供程序和使用者互不依赖的场景。 + +```yaml +dubbo: + registry: + subscribe: false +``` + +## 只订阅 + +为方便开发测试,经常会在线下共用一个所有服务可用的注册中心,这时,如果一个正在开发中的服务提供者注册,可能会影响消费者不能正常运行。可以让服务提供者开发方,只订阅服务(开发的服务可能依赖其它服务),而不注册正在开发的服务,通过直连测试正在开发的服务。 + +![/user-guide/images/subscribe-only.jpg](/imgs/user/subscribe-only.jpg) + +```yaml +dubbo: + registry: + register: false +``` + +## 权限控制 +通过令牌验证在注册中心控制权限,以决定要不要下发令牌给消费者,可以防止消费者绕过注册中心访问提供者。另外通过注册中心可灵活改变授权方式,而不需修改或升级提供者。 + +![/user-guide/images/dubbo-token.jpg](/imgs/user/dubbo-token.jpg) + +增加以下配置: +```yaml +dubbo: + provider: + token: true #UUID +``` +或者 +```yaml +dubbo: + provider: + token: 123456 +``` + +## 指定注册地址 +当服务提供者启动时,Dubbo 框架会自动扫描本机可用的网络设备地址,并将其中一个有效ip地址注册到注册中心。扫描遵循以下原则或顺序: + +1. 未联网时,返回 127.0.0.1 +2. 在阿里云服务器中,返回私有地址,如: 172.18.46.234 +3. 在本机测试时,返回公有地址,如: 30.5.10.11 + +对于有多个网络设备的情况,Dubbo 会随机选择其中一个,此时如果注册的 ip 地址不符合预期,可以通过以下方式指定地址。 + +* -D 参数指定框架读取的网卡地址,如 `-Ddubbo.network.interface.preferred=eth0`。 +* 系统环境变量指定上报到注册中心的 ip,如 `DUBBO_IP_TO_REGISTRY=30.5.10.11` + + +最后,还可以通过在 protocol 中指定 tcp 监听地址,因为监听地址会默认用作发送到注册中心的地址 +```yaml +dubbo: + protocol: + name: dubbo + port: 20880 + host: 30.5.10.11 # 也可以是域名,如 dubbo.apache.org +``` + +{{% alert title="注意" color="primary" %}} +Dubbo 框架会默认监听 `0.0.0.0:20880`,如果指定了 host,则框架会转而监听 `30.5.10.11:20880`。 +{{% /alert %}} + +## 启动时检查 + +### 消费端地址列表检查 +Dubbo 缺省会在启动时检查依赖的服务是否可用,不可用时(这里指地址列表为空)会抛出异常,阻止应用初始化完成,以便上线时能及早发现问题,默认 `check="true"`。 + +可以通过 `check="false"` 关闭检查,比如,测试时,有些服务不关心,或者出现了循环依赖,必须有一方先启动。注意如果 `check="false"` 且启动时无地址可用,此时总是会正常返回 rpc 引用,但如果此时发起调用就会出现 “无地址可用异常”,当服务地址列表恢复时,rpc 应用会自动可用。 + +**1. 使用场景** +- 单向依赖:有依赖关系(建议默认设置)和无依赖关系(可以设置 check=false) +- 相互依赖:即循环依赖,(不建议设置 check=false) +- 延迟加载处理 + +> check 只用来启动时检查,运行时没有相应的依赖仍然会报错。 + +**2. 配置方式** +```java +@DubboReference(check = false) +private DemoService demoService; +``` + +```yaml +dubbo: + consumer: + check: false +``` +### 注册中心连通性检查 +除了检查消费者端地址列表之外,Dubbo 还支持与注册中心的连通性检查。默认情况下,不论是提供者、消费者,如果启动阶段连接不上注册中心都会导致进程启动失败。 + +可以关闭注册中心启动时检查,即使注册中心连接失败进程也会继续正常启动。框架会记录所有失败的注册、订阅动作,并在注册中心链接恢复后尝试重新注册、订阅,直到所有失败事件都重试成功。 + +```yaml +dubbo: + registry: + check: false +``` + +## 注册中心缓存 + +当某个服务尝试向注册中心订阅地址时,此时注册中心应该同步返回获当前可用的地址列表,如果此时因网络故障等原因导致读取可用地址列表失败,框架会查询本地缓存的注册中心地址并返回(如不想使用使用缓存地址,可通过设置 `check=true` 快速失败抛出异常)。失败的订阅动作会被放入一个重试队列,定期重试直到成功,以确保故障恢复后可及时读到最新地址列表。 + +注册中心缓存文件的默认存放路径是:`${HOME}/.dubbo/dubbo-registry-{application-name}-{address}.cache`,以一定的间隔定期刷新。 + +如果不需要注册中心本地文件缓存,可通过以下配置关闭: +```yml +dubbo: + registry: + file-cache: false +``` + +## 断网恢复 + +### 注册中心断网恢复 + +当 dubbo 进程与注册中心之间的链接中断后,dubbo 框架会自动尝试恢复,并确保链接恢复后所有的已注册或订阅的服务都正常恢复。 + +### 消费端地址断网恢复 + +Dubbo 消费端进程可以通过 tcp 链接自动跟踪提供端实例的可用性,当发现实例不可用时,消费端会自动将不可用的实例转移到不可用地址池,以确保正常的服务调用不受影响。Dubbo 会自动探测被拉黑的不可用地址池,当发现 tcp 链接恢复后,自动从不可用地址池移除。 + +## 推空保护 +推空保护是对消费端而言的,当推空保护开启后,消费端进程会忽略注册中心推送过来的空地址事件(会继续保留当前内存已有地址列表)。这是避免在一些异常场景下误将注册中心地址列表清空,导致服务调用不可用。 + +推空保护默认关闭,可通过以下方式开启 +```yaml +dubbo: + registry: + enableEmptyProtection: true +``` + +## 直连提供者 +如果你的项目开启了服务发现,但在测试中想调用某个特定的 ip,可通过设置对端 ip 地址的 [直连模式](/zh-cn/overview/mannual/java-sdk/tasks/framework/more/explicit-target/) 绕过服务发现机制进行调用。 + +## 问题排查 +相比于 client 到 server 的 RPC 直连调用,开启服务发现后,常常会遇到各种个样奇怪的调用失败问题,以下是一些常见的问题与排查方法。 + +1. **消费方找不到可用地址 (No Provider available)**,这里有详细的 [具体原因排查步骤](/zh-cn/overview/mannual/java-sdk/tasks/troubleshoot/no-provider/)。 +2. **忘记配置注册中心**,从 3.3.0 开始,不配置注册中心地址的情况下,应用也是能够正常启动的,只是应用的任何服务都不会注册到注册中心,或者从注册中心订阅地址列表。 +3. **注册中心连不上**,如果配置了 `check=false`,虽然进程启动成功,可能服务注册、订阅并没有成功。 +4. **消费方因没有有效的地址而启动报错**,可以通过配置ReferenceConfig跳过可用地址列表检查,注解示例为 `@DubboRerefence(check=false)`。 diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/service-discovery/zookeeper.md b/content/zh-cn/overview/mannual/java-sdk/tasks/service-discovery/zookeeper.md new file mode 100644 index 000000000000..faf88af98de8 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/service-discovery/zookeeper.md @@ -0,0 +1,218 @@ +--- +aliases: + - /zh/docs3-v2/java-sdk/advanced-features-and-usage/performance/loadbalance/ + - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/performance/loadbalance/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/others/graceful-shutdown/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/consistent-hash/ +description: "通过示例演示如何使用 Zookeeper 作为注册中心实现自动服务发现。" +linkTitle: 使用Zookeeper注册中心 +title: 使用 Zookeeper 作为注册中心实现自动服务发现 +type: docs +weight: 3 +--- + +本示例演示 Zookeeper 作为注册中心实现自动服务发现,示例基于 Spring Boot 应用展开,可在此查看 [完整示例代码](https://github.com/apache/dubbo-samples/tree/master/3-extensions/registry/dubbo-samples-zookeeper) + +## 1 基本配置 +### 1.1 增加 Maven 依赖 +添加 dubbo、zookeeper 等依赖。`dubbo-spring-boot-starter` 将自动为应用增加 Zookeeper 相关客户端的依赖,减少用户使用 Zookeeper 成本,如使用中遇到版本兼容问题,用户也可以选择自行添加 Curator、Zookeeper Client 等依赖。 + +对于 Spring Boot 应用而言,可使用如下依赖: +```xml + + org.apache.dubbo + dubbo-spring-boot-starter + 3.3.0 + + + + org.apache.dubbo + dubbo-zookeeper-spring-boot-starter + 3.3.0 + + +``` + +其中,dubbo-zookeeper-spring-boot-starter 或 `dubbo-zookeeper-curator5-spring-boot-starter` 负责管理 zookeeper 相关依赖。 + + +{{% alert title="注意" color="info" %}} +如果您不使用 Spring Boot,也可以使用以下方式管理依赖 + +```xml + + + org.apache.dubbo + dubbo + 3.3.0 + + + + + org.apache.dubbo + dubbo-dependencies-zookeeper + 3.3.0 + pom + + + +``` +{{% /alert %}} + +### 1.2 选择 Zookeeper 版本 + +由于 Dubbo 使用 Curator 作为与 Zookeeper Server 交互的编程客户端,因此,要特别注意 Zookeeper Server 与 Dubbo 版本依赖的兼容性。 + +Dubbo 提供了 Zookeeper 依赖的辅助管理组件,开发者可根据当前使用的 Zookeeper Server 版本选择依赖版本: + +**1. 如果您是 Dubbo3 3.3 版本及以上用户,请根据如下表格选择组件:** + +| **Zookeeper Server 版本** | **Dubbo 依赖** | **Dubbo Starter 依赖(SpringBoot用户)** | +| --- | --- | --- | +| 3.4.x 及以下 | dubbo-dependencies-zookeeper | dubbo-zookeeper-spring-boot-starter | +| 3.5.x 及以上 | dubbo-dependencies-zookeeper-curator5 | dubbo-zookeeper-curator5-spring-boot-starter | + +**2. 如果您是 Dubbo3 3.2 及以下、Dubbo2 2.7.x 用户:** + +| **Zookeeper Server 版本** | **Dubbo 依赖** | **Dubbo Starter 依赖(SpringBoot用户)** | +| --- | --- | --- | +| 3.4.x 及以下 | dubbo-dependencies-zookeeper | 不支持(自行管理) | +| 3.5.x 及以上 | 不支持(自行管理) | 不支持(自行管理) | + +{{% alert title="注意" color="info" %}} +* Dubbo 3.3.0 版本开始正式支持 JDK 17,如果您使用 JDK 17,则必须选用 dubbo-dependencies-zookeeper-curator5 或 dubbo-zookeeper-curator5-spring-boot-starter 依赖,对应的 Zookeeper Server 推荐是 3.8.0 版本及以上。 +{{% /alert %}} + + +### 1.3 配置并启用 Zookeeper +```yaml +# application.yml +dubbo + registry + address: zookeeper://localhost:2181 + register-mode: instance # 新用户请设置此值,表示启用应用级服务发现,可选值 interface、instance、all,默认值为 all,未来版本将切换默认值为 instance +``` +或 +```properties +# dubbo.properties +dubbo.registry.address=zookeeper://localhost:2181 +# 新用户请设置此值,表示启用应用级服务发现,可选值 interface、instance、all,默认值为 all,未来版本将切换默认值为 instance +dubbo.registry.register-mode=instance +``` +或 +```xml + +``` + +`address` 是启用 zookeeper 注册中心唯一必须指定的属性,而在生产环境下,`address` 通常被指定为集群地址,如 + +`address=zookeeper://10.20.153.10:2181?backup=10.20.153.11:2181,10.20.153.12:2181` + +protocol 与 address 分开配置的模式也可以,如 + +`` + +## 2 高级配置 +### 2.1 认证与鉴权 + +如果 Zookeeper 开启认证,Dubbo 支持指定 username、password 的方式传入身份标识。 + +```yaml +# application.yml +dubbo + registry + address: zookeeper://localhost:2181 + register-mode: instance # 新用户请设置此值,表示启用应用级服务发现,可选值 interface、instance、all + username: hello + password: 1234 +``` + +也可以直接将参数扩展在 address 上 `address=zookeeper://hello:1234@localhost:2181` + +### 2.2 分组隔离 +通过指定 `group` 属性,可以在同一个 Zookeeper 集群内实现微服务地址的逻辑隔离。比如可以在一套集群内隔离出多套开发环境,在地址发现层面实现隔离。 + +```yaml +# application.yml +dubbo + registry + address: zookeeper://localhost:2181 + register-mode: instance # 新用户请设置此值,表示启用应用级服务发现,可选值 interface、instance、all + group: daily1 +``` + +### 2.3 其他扩展配置 +配置连接、会话过期时间 +```yaml +# application.yml +dubbo + registry + address: zookeeper://localhost:2181 + register-mode: instance # 新用户请设置此值,表示启用应用级服务发现,可选值 interface、instance、all + timeout: 30 * 1000* # 连接超时时间,默认 30s + session: 60 * 1000* # 会话超时时间,默认 60s +``` + +Zookeeper 注册中心还支持其他一些控制参数,具体可参见[Registry 配置项手册](../../config/properties#registry) + +## 3 工作原理 +在前面的一节中,我们讲解了应用级服务发现与接口级服务发现的区别,在 Zookeeper 实现中,它们的存储结构也存在较大差异。总体来说,Zookeeper 注册中心实现支持以下高可用能力: + +* 当提供者出现断电等异常停机时,注册中心能自动删除提供者信息 +* 当注册中心重启时,能自动恢复注册数据,以及订阅请求 +* 当会话过期时,能自动恢复注册数据,以及订阅请求 +* 当设置 `registry.check=false` 时,记录失败注册和订阅请求,后台定时重试 + +### 3.1 接口级节点结构 + +![/user-guide/images/zookeeper.jpg](/imgs/user/zookeeper.jpg) + +流程: +* 服务提供者启动时: 向 `/dubbo/com.foo.BarService/providers` 目录下写入自己的 URL 地址。 +* 服务消费者启动时: 订阅 `/dubbo/com.foo.BarService/providers` 目录下的提供者 URL 地址。并向 `/dubbo/com.foo.BarService/consumers` 目录下写入自己的 URL 地址 +* 监控中心启动时: 订阅 `/dubbo/com.foo.BarService` 目录下的所有提供者和消费者 URL 地址。 + +可通过 `registry.group` 设置 zookeeper 的根节点,不配置将使用默认的 `/dubbo` 根节点。 + +### 3.2 应用级节点结构 + +#### 3.2.1 地址列表 + + +应用级服务发现的地址结构比接口级更精简,它以应用名为粒度分发地址列表。服务提供者启动时,向 `/services/app` 目录下写入自己的 URL 地址,相比于接口级别的 URL,应用级别的 URL 更简单,只包含一些实例级别的参数,如 `tri://ip:port?region=hangzhou`。 + +可通过 `registry.group` 设置 zookeeper 的根节点,如设置 `registry.group=dubbo` 后,地址根节点变为 `/dubbo`。不配置将使用默认的 `/services` 根节点。在与 Spring Cloud Gateway 共用情况下,使用 `/services` 根节点会导致 dubbo 地址被 gateway 消费,此时可考虑设置独立 group。 + +{{% alert title="注意" color="info" %}} +在应用级服务发现模型中,接口级别的配置信息由消费者与提供者之间自行协商同步,不再由注册中心负责同步,从而大大减少了注册中心地址同步压力。 +{{% /alert %}} + +#### 3.2.2 接口应用映射 +在应用级服务发现中,zookeeper 注册中心还会存储一份额外的元数据,用于解决 `接口名到应用名` 之间的映射关系,其存储结构如下: + + + +service1 节点的 value 值是应用列表,可通过 `get /dubbo/mapping/service1` 查看:app1,app2 + +#### 3.2.3 元数据 +如果您用的是应用级服务发现的集中式元数据模式(默认是点对点的元数据模式,可通过 `dubbo.registry.metadata-type=remote` 开启)。在开启集中式元数据模式后,zookeeper 中还会发现以下节点内容: + + + +每个 revision 下是该应用的部署元数据信息,包含完整的接口服务列表及其配置信息。 + + + diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/traffic-management/_index.md b/content/zh-cn/overview/mannual/java-sdk/tasks/traffic-management/_index.md new file mode 100755 index 000000000000..6811d4244be4 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/traffic-management/_index.md @@ -0,0 +1,118 @@ +--- +aliases: [/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/traffic/] +description: 演示 Dubbo 流量治理特性的使用方式。 +linkTitle: 流量管控 +no_list: true +title: 流量管控 +type: docs +weight: 5 +--- + +我们通过一个使用 Dubbo 开发的商城微服务项目,演示 Dubbo 流量管控规则的基本使用方法,包括如下场景: + +{{< blocks/section color="white" height="auto">}} +
+
+
+
+
+

+ 调整超时时间 +

+

通过在运行期动态的调整服务超时时间,可以有效的应对超时设置不合理、系统突发情况等导致的服务频繁超时、服务阻塞等问题,提升系统稳定性。

+
+
+
+
+
+
+

+ 增加重试次数 +

+

在服务初次调用失败后,通过重试能有效的提升总体调用成功率。

+
+
+
+
+
+
+

+ 访问日志 +

+

访问日志可以很好的记录某台机器在某段时间内处理的所有服务请求信息,运行态动态的开启访问日志对于排查问题非常有帮助。 +

+
+
+
+
+
+
+

+ 同机房/区域优先 +

+

同机房/区域优先是指应用调用服务时,优先调用同机房/区域的服务提供者,避免了跨区域带来的网络延时,从而减少了调用的响应时间。 +

+
+
+
+
+
+
+

+ 环境隔离 +

+

通过为集群中的某一个或多个应用划分逻辑隔离环境,可用于灰度环境或多套测试环境搭建。 +

+
+
+
+
+
+
+

+ 参数路由 +

+

如基于用户 ID 路由流量,将一小部分用户请求转发到最新发布的产品版本,以验证新版本的稳定性、获取用户的产品体验反馈等。 +

+
+
+
+
+
+
+

+ 权重比例 +

+

通过规则动态调整单个或一组机器的权重,可以在运行态改变请求流量的分布,实现动态的按比例的流量路由。 +

+
+
+
+
+
+
+

+ 服务降级 +

+

服务降级的核心目标就是针对这些弱依赖项,在弱依赖不可用或调用失败时,通过返回降级结果尽可能的维持功能完整。 +

+
+
+
+
+
+
+

+ 固定机器导流 +

+

通过将请求固定的转发某一台提供者机器,帮助快速复现开发或线上问题。 +

+
+
+
+
+
+
+ +{{< /blocks/section >}} diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/traffic-management/accesslog.md b/content/zh-cn/overview/mannual/java-sdk/tasks/traffic-management/accesslog.md new file mode 100644 index 000000000000..71a04e45436d --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/traffic-management/accesslog.md @@ -0,0 +1,87 @@ +--- +aliases: + - /zh/overview/tasks/traffic-management/accesslog/ + - /zh-cn/overview/tasks/traffic-management/accesslog/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/accesslog/ +description: "" +linkTitle: 访问日志 +title: 通过动态开启访问日志跟踪服务调用情况 +type: docs +weight: 3 +--- + + + +访问日志可以很好的记录某台机器在某段时间内处理的所有服务请求信息,包括请求接收时间、远端 IP、请求参数、响应结果等,运行态动态的开启访问日志对于排查问题非常有帮助。 + +## 开始之前 +* [部署 Shop 商城项目](../#部署商场系统) +* 部署并打开 [Dubbo Admin](../.././../reference/admin/architecture/) + +## 任务详情 + +商城的所有用户服务都由 `User` 应用的 UserService 提供,通过这个任务,我们为 `User` 应用的某一台或几台机器开启访问日志,以便观察用户服务的整体访问情况。 + +### 动态开启访问日志 + +Dubbo 通过 `accesslog` 标记识别访问日志的开启状态,我们可以指定日志文件的输出位置,也可以单独打开某台机器的访问日志。 + +![accesslog.png](/imgs/v3/tasks/accesslog/accesslog1.png) + +#### 操作步骤 +1. 打开 Dubbo Admin 控制台 +2. 在左侧导航栏选择【服务治理】>【动态配置】 +3. 点击 "创建",输入应用名 `shop-user` 并勾选 "开启访问日志"(此时访问日志将和普通日志打印在一起)。 + +![Admin 访问日志设置截图](/imgs/v3/tasks/accesslog/accesslog_admin.png) + +再次访问登录页面,登录到 `User` 应用的任意一台机器,可以看到如下格式的访问日志。 + +```text +[2022-12-30 12:36:31.15900] -> [2022-12-30 12:36:31.16000] 192.168.0.103:60943 -> 192.168.0.103:20884 - org.apache.dubbo.samples.UserService login(java.lang.String,java.lang.String) ["test",""], dubbo version: 3.2.0-beta.4-SNAPSHOT, current host: 192.168.0.103 +[2022-12-30 12:36:33.95900] -> [2022-12-30 12:36:33.95900] 192.168.0.103:60943 -> 192.168.0.103:20884 - org.apache.dubbo.samples.UserService getInfo(java.lang.String) ["test"], dubbo version: 3.2.0-beta.4-SNAPSHOT, current host: 192.168.0.103 +[2022-12-30 12:36:31.93500] -> [2022-12-30 12:36:34.93600] 192.168.0.103:60943 -> 192.168.0.103:20884 - org.apache.dubbo.samples.UserService getInfo(java.lang.String) ["test"], dubbo version: 3.2.0-beta.4-SNAPSHOT, current host: 192.168.0.103 +``` + +#### 规则详解 + +**规则 key :** shop-user + +**规则体** + +```yaml +configVersion: v3.0 +enabled: true +configs: + - side: provider + parameters: + accesslog: true +``` + +以下是开启访问日志的关键配置 + +```yaml +parameters: + accesslog: true +``` + +accesslog 的有效值如下: +* `true` 或 `default` 时,访问日志将随业务 logger 一同输出,此时可以在应用内提前配置 `dubbo.accesslog` appender 调整日志的输出位置和格式 +* 具体的文件路径如 `/home/admin/demo/dubbo-access.log`,这样访问日志将打印到指定的文件内 + +在 Admin 界面,还可以单独指定开启某一台机器的访问日志,以方便精准排查问题,对应的后台规则如下: + +```yaml +configVersion: v3.0 +enabled: true +configs: + - match + address: + oneof: + - wildcard: "{ip}:*" + side: provider + parameters: + accesslog: true +``` + +其中,`{ip}` 替换为具体的机器地址即可。 diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/traffic-management/architecture.md b/content/zh-cn/overview/mannual/java-sdk/tasks/traffic-management/architecture.md new file mode 100755 index 000000000000..b52f3ba13c42 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/traffic-management/architecture.md @@ -0,0 +1,201 @@ +--- +aliases: + - /zh/overview/tasks/traffic-management/ + - /zh-cn/overview/tasks/traffic-management/ +description: 演示 Dubbo 流量治理特性的使用方式。 +linkTitle: 示例应用架构 +title: 示例应用架构 +type: docs +weight: 1 +--- + +此任务基于一个简单的线上商城微服务系统演示了 Dubbo 的流量管控能力。 + +{{% alert title="注意" color="warning" %}} +本示例展示的所有能力均基于 [Dubbo 路由规则](/zh-cn/overview/what/core-features/traffic/introduction/) 实现,如想了解具体工作原理可查看详情。 +{{% /alert %}} + + +线上商城的架构图如下: + +![shop-arc](/imgs/v3/traffic/shop-arc.png) + +系统由 5 个微服务应用组成: +* `Frontend 商城主页`,作为与用户交互的 web 界面,通过调用 `User`、`Detail`、`Order` 等提供用户登录、商品展示和订单管理等服务。 +* `User 用户服务`,负责用户数据管理、身份校验等。 +* `Order 订单服务`,提供订订单创建、订单查询等服务,依赖 `Detail` 服务校验商品库存等信息。 +* `Detail 商品详情服务`,展示商品详情信息,调用 `Comment` 服务展示用户对商品的评论记录。 +* `Comment 评论服务`,管理用户对商品的评论数据。 + +## 部署商场系统 + +为方便起见,我们将整个系统部署在 Kubernetes 集群,执行以下命令即可完成商城项目部署,项目源码示例在 [dubbo-samples/task](https://github.com/apache/dubbo-samples/tree/master/10-task/dubbo-samples-shop)。 + +```sh +kubectl apply -f https://raw.githubusercontent.com/apache/dubbo-samples/master/10-task/dubbo-samples-shop/deploy/All.yml +``` + +完整的部署架构图如下: + +![shop-arc](/imgs/v3/traffic/shop-arc-deploy2.png) + +`Order 订单服务`有两个版本 `v1` 和 `v2`,`v2` 是订单服务优化后发布的新版本。 +* 版本 v1 只是简单的创建订单,不展示订单详情 +* 版本 v2 在订单创建成功后会展示订单的收货地址详情 + +`Detail` 和 `Comment` 服务也分别有两个版本 `v1` 和 `v2`,我们通过多个版本来演示流量导流后的效果。 +* 版本 `v1` 默认为所有请求提供服务 +* 版本 `v2` 模拟被部署在特定的区域的服务,因此 `v2` 实例会带有特定的标签 + +执行以下命令,确定所有服务、Pod都已正常运行: +```sh +$ kubectl get services -n dubbo-demo + +``` + +```sh +$ kubectl get pods -n dubbo-demo + +``` + +为了保障系统完整性,除了商城相关的几个微服务应用,示例还在后台拉起了 Nacos 注册配置中心、Dubbo Admin 控制台 和 Skywalking 全链路追踪系统。 + +```sh +$ kubectl get services -n dubbo-system + +``` + +```sh +$ kubectl get pods -n dubbo-system + +``` + +## 获得访问地址 +执行以下命令,将集群端口映射到本地端口: + +```sh +kubectl port-forward -n dubbo-demo deployment/shop-frontend 8080:8080 +``` + +```sh +kubectl port-forward -n dubbo-system service/dubbo-admin 38080:38080 +``` + +```sh +kubectl port-forward -n dubbo-system service/skywalking-oap-dashboard 8082:8082 +``` + +此时,打开浏览器,即可通过以下地址访问: +* 商城首页 `http://localhost:8080` +* Dubbo Admin 控制台 `http://localhost:38080` +* Skywalking 控制台 `http://localhost:8082` + +## 任务项 +接下来,试着通过如下任务项给商城增加一些流量管控规则吧。 + +{{< blocks/section color="white" height="auto">}} +
+
+
+
+
+

+ 调整超时时间 +

+

通过在运行期动态的调整服务超时时间,可以有效的应对超时设置不合理、系统突发情况等导致的服务频繁超时、服务阻塞等问题,提升系统稳定性。

+
+
+
+
+
+
+

+ 增加重试次数 +

+

在服务初次调用失败后,通过重试能有效的提升总体调用成功率。

+
+
+
+
+
+
+

+ 访问日志 +

+

访问日志可以很好的记录某台机器在某段时间内处理的所有服务请求信息,运行态动态的开启访问日志对于排查问题非常有帮助。 +

+
+
+
+
+
+
+

+ 同机房/区域优先 +

+

同机房/区域优先是指应用调用服务时,优先调用同机房/区域的服务提供者,避免了跨区域带来的网络延时,从而减少了调用的响应时间。 +

+
+
+
+
+
+
+

+ 环境隔离 +

+

通过为集群中的某一个或多个应用划分逻辑隔离环境,可用于灰度环境或多套测试环境搭建。 +

+
+
+
+
+
+
+

+ 参数路由 +

+

如基于用户 ID 路由流量,将一小部分用户请求转发到最新发布的产品版本,以验证新版本的稳定性、获取用户的产品体验反馈等。 +

+
+
+
+
+
+
+

+ 权重比例 +

+

通过规则动态调整单个或一组机器的权重,可以在运行态改变请求流量的分布,实现动态的按比例的流量路由。 +

+
+
+
+
+
+
+

+ 服务降级 +

+

服务降级的核心目标就是针对这些弱依赖项,在弱依赖不可用或调用失败时,通过返回降级结果尽可能的维持功能完整。 +

+
+
+
+
+
+
+

+ 固定机器导流 +

+

通过将请求固定的转发某一台提供者机器,帮助快速复现开发或线上问题。 +

+
+
+
+
+
+
+ +{{< /blocks/section >}} diff --git a/content/zh-cn/overview/tasks/traffic-management/arguments.md b/content/zh-cn/overview/mannual/java-sdk/tasks/traffic-management/arguments.md similarity index 98% rename from content/zh-cn/overview/tasks/traffic-management/arguments.md rename to content/zh-cn/overview/mannual/java-sdk/tasks/traffic-management/arguments.md index 7a32622c1182..91eaca43d7da 100644 --- a/content/zh-cn/overview/tasks/traffic-management/arguments.md +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/traffic-management/arguments.md @@ -1,6 +1,7 @@ --- aliases: - /zh/overview/tasks/traffic-management/arguments/ + - /zh-cn/overview/tasks/traffic-management/arguments/ description: "" linkTitle: 参数路由 title: 根据请求参数引导流量分布 diff --git a/content/zh-cn/overview/tasks/traffic-management/host.md b/content/zh-cn/overview/mannual/java-sdk/tasks/traffic-management/host.md similarity index 97% rename from content/zh-cn/overview/tasks/traffic-management/host.md rename to content/zh-cn/overview/mannual/java-sdk/tasks/traffic-management/host.md index db0375140c6e..59529b3a6ae0 100644 --- a/content/zh-cn/overview/tasks/traffic-management/host.md +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/traffic-management/host.md @@ -1,6 +1,7 @@ --- aliases: - /zh/overview/tasks/traffic-management/host/ + - /zh-cn/overview/tasks/traffic-management/host/ description: "" linkTitle: 固定机器导流 title: 将流量点对点引导到一台机器 (如排查问题) @@ -65,4 +66,4 @@ conditions: 为了不影响其他任务效果,通过 Admin 删除或者禁用刚刚配置的条件路由规则。 ## 其他事项 -在生产环境中引导流量到固定机器要做好安全性评估,避免单机负载过高影响系统稳定性,另外,云原生背景下的 IP 地址的变化更加频繁,IP 地址可能随时会失效,要注意及时清理绑定特定 IP 的路由规则。 \ No newline at end of file +在生产环境中引导流量到固定机器要做好安全性评估,避免单机负载过高影响系统稳定性,另外,云原生背景下的 IP 地址的变化更加频繁,IP 地址可能随时会失效,要注意及时清理绑定特定 IP 的路由规则。 diff --git a/content/zh-cn/overview/tasks/traffic-management/isolation.md b/content/zh-cn/overview/mannual/java-sdk/tasks/traffic-management/isolation.md similarity index 88% rename from content/zh-cn/overview/tasks/traffic-management/isolation.md rename to content/zh-cn/overview/mannual/java-sdk/tasks/traffic-management/isolation.md index dd854a7d289f..b9cc840a0cee 100644 --- a/content/zh-cn/overview/tasks/traffic-management/isolation.md +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/traffic-management/isolation.md @@ -1,6 +1,7 @@ --- aliases: - /zh/overview/tasks/traffic-management/isolation/ + - /zh-cn/overview/tasks/traffic-management/isolation/ description: "" linkTitle: 环境隔离 title: 通过标签实现流量隔离环境(灰度、多套开发环境等) @@ -36,6 +37,34 @@ weight: 5 kubectl apply -f https://raw.githubusercontent.com/apache/dubbo-samples/master/10-task/dubbo-samples-shop/deploy/Gray.yml ``` +{{% alert title="如何为机器或实例打标?" color="info" %}} + +**方法一:通过 `dubbo.labels` 或 `DUBBO_LABELS` 指定需要增加到 URL 中的键值对。** + +```properties +# JVM 参数 +-Ddubbo.labels = "tag1=value1; tag2=value2" + +# 环境变量 +DUBBO_LABELS = "tag1=value1; tag2=value2" +``` + +最终生成的 URL 会包含 tag1、tag2 两个 key: `dubbo://xxx?tag1=value1&tag2=value2` + +**方法二:通过 `dubbo.env.keys` 或 `DUBBO_ENV_KEYS` 指定要加载的环境变量,Dubbo 会尝试从环境变量加载每个 key。** + +```properties +# JVM 参数 +-Ddubbo.env.keys = "DUBBO_TAG1, DUBBO_TAG2" + +# 环境变量 +DUBBO_ENV_KEYS = "DUBBO_TAG1, DUBBO_TAG2" +``` + +最终生成的 URL 会包含 DUBBO_TAG1、DUBBO_TAG2 两个 key: `dubbo://xxx?DUBBO_TAG1=value1&DUBBO_TAG2=value2` +{{% /alert %}} + + 接下来,我们开始为几个应用分别增加标签规则,将刚刚部署的实例从普通流量实例隔离出来。 #### 操作步骤 diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/traffic-management/mock.md b/content/zh-cn/overview/mannual/java-sdk/tasks/traffic-management/mock.md new file mode 100644 index 000000000000..f788b9ec8eda --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/traffic-management/mock.md @@ -0,0 +1,72 @@ +--- +aliases: + - /zh/overview/tasks/traffic-management/mock/ + - /zh-cn/overview/tasks/traffic-management/mock/ +description: "" +linkTitle: 服务降级 +title: 在大促之前对弱依赖调用进行服务降级 +type: docs +weight: 8 +--- + + + +由于微服务系统的分布式特性,一个服务往往需要依赖非常多的外部服务来实现某一项功能,因此,一个服务的稳定性不但取决于其自身,同时还取决于所有外部依赖的稳定性。我们可以根据这些依赖的重要程度将它们划分为强依赖和弱依赖:强依赖是指那些无论如何都要保证稳定性的服务,如果它们不可用则当前服务也就不可用;弱依赖项指当它们不可用之后当前服务仍能正常工作的依赖项,弱依赖不可用只是影响功能的部分完整性。 + +服务降级的核心目标就是针对这些弱依赖项。在弱依赖不可用或调用失败时,通过返回降级结果尽可能的维持功能完整性;另外,我们有时也会主动的屏蔽一些非关键弱依赖项的调用,比如在大促流量洪峰之前,通过预先设置一些有效的降级策略来短路部分依赖调用,来有效的提升流量高峰时期系统的整体效率和稳定性。 + +## 开始之前 + +* [部署 Shop 商城项目](../#部署商场系统) +* 部署并打开 [Dubbo Admin](../.././../reference/admin/architecture/) + +## 任务详情 + +正常情况下,商品详情页会展示来自顾客的商品评论信息。 + +![mock1.png](/imgs/v3/tasks/mock/mock1.png) + +评论信息的缺失在很多时候并不会影响用户浏览和购买商品,因此,我们定义评论信息属于商品详情页面的弱依赖。接下来,我们就模拟在大促前夕常用的一个策略,通过服务降级提前关闭商品详情页对于评论服务的调用(返回一些本地预先准备好的历史评论数据),来降低集群整体负载水位并提高响应速度。 + +![mock0.png](/imgs/v3/tasks/mock/mock0.png) + +### 通过降级规则短路 Comment 评论服务调用 + +评论数据由 Comment 应用的 `org.apache.dubbo.samples.CommentService` 服务提供,接下来我们就为 `CommentService` 配置降级规则。 + +#### 操作步骤 +1. 打开 Dubbo Admin 控制台 +2. 在左侧导航栏选择【流量管控】>【服务降级】 +3. 点击 "创建",输入服务 `org.apache.dubbo.samples.CommentService` 和降级规则。 + +![Admin 服务降级规则配置截图](/imgs/v3/tasks/mock/mock_admin.png) + +等待降级规则推送完成之后,刷新商品详情页面,发现商品评论信息已经变为我们预先设置的 "Mock Comment",因为商品详情页的 Comment 服务调用已经在本地短路,并没有真正的发送到后端服务提供者机器上。 + +![mock2.png](/imgs/v3/tasks/mock/mock2.png) + +再次刷新页面 + +#### 规则详解 + +**规则 key** :`org.apache.dubbo.samples.CommentService` + +**规则体** + +```yaml +configVersion: v3.0 +enabled: true +configs: + - side: consumer + parameters: + mock: force:return Mock Comment +``` + +## 清理 +为了不影响其他任务效果,通过 Admin 删除或者禁用刚刚配置的降级规则。 + +## 其他事项 + +服务降级功能也可以用于开发测试环境,由于微服务分布式的特点,不同的服务或应用之间都有相互依赖关系,因此,一个服务或应用很难不依赖其他服务而独立部署工作。但测试环境下并不是所有服务都是随时就绪的状态,这对于微服务强调的服务独立演进是一个很大的障碍,通过服务降级这个功能,我们可以模拟或短路应用对其他服务的依赖,从而可以让应用按照自己预期的行为 Mock 外部服务调用的返回结果。具体可参见 [Dubbo Admin 服务 Mock](../.././../reference/admin/mock/) 特性的使用方式。 + +Dubbo 的降级规则用来设置发生降级时的行为和返回值,而对于何时应该执行限流降级动作,即限流降级时机的判断并没有过多涉猎,这一点 Dubbo 通过集成更专业的限流降级产品如 Sentinel 进行了补全,可以配合 Dubbo 降级规则一起使用,具体可参见 [限流降级](/zh-cn/overview/core-features/traffic/circuit-breaking/) 文档。 diff --git a/content/zh-cn/overview/tasks/traffic-management/region.md b/content/zh-cn/overview/mannual/java-sdk/tasks/traffic-management/region.md similarity index 98% rename from content/zh-cn/overview/tasks/traffic-management/region.md rename to content/zh-cn/overview/mannual/java-sdk/tasks/traffic-management/region.md index d8151cd62ee2..b6939326d490 100644 --- a/content/zh-cn/overview/tasks/traffic-management/region.md +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/traffic-management/region.md @@ -1,6 +1,7 @@ --- aliases: - /zh/overview/tasks/traffic-management/region/ + - /zh-cn/overview/tasks/traffic-management/region/ description: 在 Dubbo-Admin 动态配置同机房/区域优先 linkTitle: 同区域优先 title: 同机房/区域优先 diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/traffic-management/retry.md b/content/zh-cn/overview/mannual/java-sdk/tasks/traffic-management/retry.md new file mode 100644 index 000000000000..263f481a6004 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/traffic-management/retry.md @@ -0,0 +1,75 @@ +--- +aliases: + - /zh/overview/tasks/traffic-management/retry/ + - /zh-cn/overview/tasks/traffic-management/retry/ +description: "" +linkTitle: 服务重试 +title: 通过重试提高服务调用成功率 +type: docs +weight: 2 +--- + + + +在服务初次调用失败后,通过重试能有效的提升总体调用成功率。但也要注意重试可能带来的响应时间增长,系统负载升高等,另外,重试一般适用于只读服务,或者具有幂等性保证的写服务。 + +## 开始之前 +* [部署 Shop 商城项目](../#部署商场系统) +* 部署并打开 [Dubbo Admin](../.././../reference/admin/architecture/) + +## 任务详情 + +成功登录商城项目后,商城会默认在首页展示当前登录用户的详细信息。 + +![retry1.png](/imgs/v3/tasks/retry/retry1.png) + +但有些时候,提供用户详情的 Dubbo 服务也会由于网络不稳定等各种原因变的不稳定,比如我们提供用户详情的 User 服务就很大概率会调用失败,导致用户无法看到账户的详细信息。 + +![retry2.png](/imgs/v3/tasks/retry/retry2.png) + +用户账户详情查询失败后的系统界面如下: + +![retry2.png](/imgs/v3/tasks/retry/retry4.png) + +商城为了获得带来更好的使用体验,用户信息的加载过程是异步的,因此用户信息加载失败并不会影响对整个商城页面的正常访问,但如果能始终展示完整的用户信息总能给使用者留下更好的印象。 +### 增加重试提高成功率 + +考虑到访问用户详情的过程是异步的(隐藏在页面加载背后),只要最终数据能加载出来,适当的增加等待时间并不是大的问题。因此,我们可以考虑通过对每次用户访问增加重试次数的方式,提高服务详情服务的整体访问成功率。 + +![retry3.png](/imgs/v3/tasks/retry/retry3.png) + +#### 操作步骤 +1. 打开 Dubbo Admin 控制台 +2. 在左侧导航栏选择【服务治理】>【动态配置】 +3. 点击 "创建",输入服务 `org.apache.dubbo.samples.UserService` 和失败重试次数如 `4` 即可。 + +![Admin 重试次数设置截图](/imgs/v3/tasks/retry/retry_admin.png) + +保存后,尝试多次刷新页面,发现用户详情数据总是能正常显示,虽然有时由于重试的缘故加载时间会明显变长。 + +#### 规则详解 + +**规则 key** :`org.apache.dubbo.samples.UserService` + +**规则体** + +```yaml +configVersion: v3.0 +enabled: true +configs: + - side: consumer + parameters: + retries: 5 +``` + +从 `UserService` 服务消费者视角(即 Frontend 应用)增加了调用失败后的重试次数。 + +```yaml +parameters: + retries: 5 +``` + +`side: consumer` 配置会将规则发送到服务消费方实例,所有 `UserService` 服务实例会基于新的 timeout 值进行重新发布,并通过注册中心通知给所有消费方。 + +## 清理 +为了不影响其他任务效果,通过 Admin 删除或者禁用刚刚配置的重试规则。 diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/traffic-management/route.md b/content/zh-cn/overview/mannual/java-sdk/tasks/traffic-management/route.md new file mode 100644 index 000000000000..6f9074cad131 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/traffic-management/route.md @@ -0,0 +1,56 @@ +--- +description: Spring Boot +linkTitle: 基于条件的流量路由 +title: 基于条件的流量路由 +type: docs +weight: 5 +--- + +路由是 Dubbo 中的核心流量管控机制, 我们可以基于它实现金丝雀发布、按比例流量转发、同区域优先、全链路灰度等流量策略。Dubbo 中路由(Router)机制的设计与基本原理,内置的几种路由规则 + + +## 常用流量管控场景 +Dubbo 内置的流量策略非常的灵活,但同时也有一定的理解与使用成本,因此,我们根据总结了一些常用的使用场景,并给出了配置方法: + +| **场景** | **效果** | **作用对象** | **说明** | +| --- | --- | --- | --- | +| 超时时间 | | | | +| 访问日志 | | | | +| 调用重试 | | | | +| + | | | | +| | | | | +| | | | | +| | | | | + + +接下来,我们就以一个条件路由为例,来看一下如何使用 Dubbo 流量管控机制。 +## 一个条件路由示例 +需求非常的直观明了。 + +- 匹配这个条件的流量,转发到这一批机器 +- 匹配另一个条件的流量,转发到另一批机器 + +![画一张流量匹配和转发的图]() + +这在 Dubbo 中就是用 条件路由 来实现的,关于其详细工作原理我们在介绍中有详细讲解。 +在以上示例中,xxx 代表;yyy 代表 + +我们需要把规则下发到运行中的dubbo sdk,在 dubbo 体系中这是如下如下工作的。 + +![路由规则的分发与生效原理图]() + +一个 zk/nacos、下发一条规则,dubbo实例接收到规则推送,rpc调用过程中应用规则筛选,选出地址子集调用 + +{{% alert title="注意" color="info" %}} +传统 Nacos/Zookeeper 的微服务部署方案中,Dubbo 的路由规则配置中心存储并转发到 Dubbo SDK,而在 Kubernetes Service 或服务网格场景下,路由规则的存储与推送机制会有一些变化,具体请参考 [Kubernetes 最佳实践]()。 +{{% /alert %}} + +这时,如果我们对 xxx 服务发送一个请求, + +有一点非常 + +## 更多内容 +- 配置了路由规则不生效?[Dubbo 路由规则排查方法]() +- 当前的路由规则不够灵活,无法达到效果?来看看 [脚本路由]() 吧 +- 您还可以通过 [扩展 Dubbo 的路由实现]() 定制自己的流量策略 diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/traffic-management/timeout.md b/content/zh-cn/overview/mannual/java-sdk/tasks/traffic-management/timeout.md new file mode 100644 index 000000000000..eb11f1c5428f --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/traffic-management/timeout.md @@ -0,0 +1,72 @@ +--- +aliases: + - /zh/overview/tasks/traffic-management/timeout/ + - /zh-cn/overview/tasks/traffic-management/timeout/ +description: 在 Dubbo-Admin 动态调整服务超时时间 +linkTitle: 调整超时时间 +title: 动态调整服务超时时间 +type: docs +weight: 2 +--- + +Dubbo 提供动态调整服务超时时间的能力,在无需重启应用的情况下调整服务的超时时间,这对于临时解决一些服务上下游依赖不稳定而导致的调用失败问题非常有效。 + +## 开始之前 +* [部署 Shop 商城项目](../#部署商场系统) +* 部署并打开 [Dubbo Admin](../.././../reference/admin/architecture/) + +## 任务详情 + +商城项目通过 `org.apache.dubbo.samples.UserService` 提供用户信息管理服务,访问 `http://localhost:8080/` 打开商城并输入任意账号密码,点击 `Login` 即可以正常登录到系统。 + +![timeout1.png](/imgs/v3/tasks/timeout/timeout1.png) + +有些场景下,User 服务的运行速度会变慢,比如存储用户数据的数据库负载过高导致查询变慢,这时就会出现 `UserService` 访问超时的情况,导致登录失败。 + +![timeout2.png](/imgs/v3/tasks/timeout/timeout2.png) + +在示例系统中,可通过下图 `Timeout Login` 模拟突发的 `UserService` 访问超时异常 + +![timeout4.png](/imgs/v3/tasks/timeout/timeout4.png) + +### 通过规则动态调整超时时间 + +为了解决突发的登录超时问题,我们只需要适当增加 `UserService` 服务调用的等待时间即可。 + +![timeout3.png](/imgs/v3/tasks/timeout/timeout3.png) + +#### 操作步骤 +1. 打开 Dubbo Admin 控制台 +2. 在左侧导航栏选择【服务治理】>【动态配置】 +3. 点击 "创建",输入服务 `org.apache.dubbo.samples.UserService` 和新的超时时间如 `2000` 即可。 + +![Admin 超时时间设置截图](/imgs/v3/tasks/timeout/timeout_admin.png) + +保存后,再次点击 `Timeout Login`,此时在经过短暂的等待后系统可以正常登录。 + +#### 规则详解 + +**规则 key** :`org.apache.dubbo.samples.UserService` + +**规则体** + +```yaml +configVersion: v3.0 +enabled: true +configs: + - side: provider + parameters: + timeout: 2000 +``` + +从 `UserService` 服务提供者视角,将超时时间总体调整为 2s。 + +```yaml +parameters: + timeout: 2000 +``` + +`side: provider` 配置会将规则发送到服务提供方实例,所有 `UserService` 服务实例会基于新的 timeout 值进行重新发布,并通过注册中心通知给所有消费方。 + +## 清理 +为了不影响其他任务效果,通过 Admin 删除或者禁用刚刚配置的超时规则。 diff --git a/content/zh-cn/overview/tasks/traffic-management/weight.md b/content/zh-cn/overview/mannual/java-sdk/tasks/traffic-management/weight.md similarity index 98% rename from content/zh-cn/overview/tasks/traffic-management/weight.md rename to content/zh-cn/overview/mannual/java-sdk/tasks/traffic-management/weight.md index f347019ef35e..095fb25d7852 100644 --- a/content/zh-cn/overview/tasks/traffic-management/weight.md +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/traffic-management/weight.md @@ -1,6 +1,7 @@ --- aliases: - /zh/overview/tasks/traffic-management/weight/ + - /zh-cn/overview/tasks/traffic-management/weight/ description: "" linkTitle: 权重比例 title: 基于权重值的比例流量转发 @@ -90,4 +91,4 @@ parameters: 为了不影响其他任务效果,通过 Admin 删除或者禁用刚刚配置的权重规则。 ## 其他事项 -`weight=0` \ No newline at end of file +`weight=0` diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/trasaction/_index.md b/content/zh-cn/overview/mannual/java-sdk/tasks/trasaction/_index.md new file mode 100755 index 000000000000..1a2f320d9e6c --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/trasaction/_index.md @@ -0,0 +1,9 @@ +--- +description: 分布式事务 +hide: true +linkTitle: 分布式事务 +no_list: true +title: 分布式事务 +type: docs +weight: 7 +--- diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/trasaction/distributed-transaction.md b/content/zh-cn/overview/mannual/java-sdk/tasks/trasaction/distributed-transaction.md new file mode 100644 index 000000000000..33dd863f54ba --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/trasaction/distributed-transaction.md @@ -0,0 +1,159 @@ +--- +aliases: + - /zh/docs3-v2/java-sdk/advanced-features-and-usage/service/distributed-transaction/ + - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/service/distributed-transaction/ + - /zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/distributed-transaction/ +description: "使用 Seata 解决 Dubbo 服务数据一致性问题,支持分布式事务。" +linkTitle: 使用Seata让Dubbo支持分布式事务 +title: 使用 Seata 支持分布式事务 +type: docs +weight: 42 +--- +本示例演示如何使用 Apache Seata 实现 Dubbo 分布式事务功能,保证数据一致性。 + +Apache Seata 是一款开源的分布式事务解决方案,致力于在微服务架构下提供高性能和简单易用的分布式事务服务。 +在Dubbo中集成Seata实现分布式事务非常方便,只需简单几步即可完成,本文将通过一个示例带你快速体验,示例总体架构图如下: + +![seata-flow](/imgs/docs3-v2/java-sdk/seata/flow.png) + +开始前,请先完成以下内容: + +1. 下载示例源码 + ```shell + git clone --depth=1 https://github.com/apache/dubbo-samples.git + ``` + + 进入示例源码目录: + ```shell + cd dubbo-samples/2-advanced/dubbo-samples-seata + ``` + +2. 下载最新版的[seata-server二进制包](https://seata.apache.org/zh-cn/unversioned/download/seata-server)至本地。 + +## 步骤 1:建立数据库并初始化相关测试数据 +- 本文将使用MySQL 5.7 (更多支持的数据库可在文末查看附录)。 +进入dubbo-samples-seata的script目录,找到dubbo_biz.sql和undo_log.sql两个数据库脚本文件,内容如下: + +undo_log.sql是Seata AT 模式需要 `UNDO_LOG` 表 +```sql +-- for AT mode you must to init this sql for you business database. the seata server not need it. +CREATE TABLE IF NOT EXISTS `undo_log` +( + `branch_id` BIGINT NOT NULL COMMENT 'branch transaction id', + `xid` VARCHAR(128) NOT NULL COMMENT 'global transaction id', + `context` VARCHAR(128) NOT NULL COMMENT 'undo_log context,such as serialization', + `rollback_info` LONGBLOB NOT NULL COMMENT 'rollback info', + `log_status` INT(11) NOT NULL COMMENT '0:normal status,1:defense status', + `log_created` DATETIME(6) NOT NULL COMMENT 'create datetime', + `log_modified` DATETIME(6) NOT NULL COMMENT 'modify datetime', + UNIQUE KEY `ux_undo_log` (`xid`, `branch_id`) + ) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8mb4 COMMENT ='AT transaction mode undo table'; +ALTER TABLE `undo_log` ADD INDEX `ix_log_created` (`log_created`); + +``` +dubbo_biz.sql是示例业务表以及初始化数据 + +```sql +DROP TABLE IF EXISTS `stock_tbl`; +CREATE TABLE `stock_tbl` +( + `id` int(11) NOT NULL AUTO_INCREMENT, + `commodity_code` varchar(255) DEFAULT NULL, + `count` int(11) DEFAULT 0, + PRIMARY KEY (`id`), + UNIQUE KEY (`commodity_code`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + + +DROP TABLE IF EXISTS `order_tbl`; +CREATE TABLE `order_tbl` +( + `id` int(11) NOT NULL AUTO_INCREMENT, + `user_id` varchar(255) DEFAULT NULL, + `commodity_code` varchar(255) DEFAULT NULL, + `count` int(11) DEFAULT 0, + `money` int(11) DEFAULT 0, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + + +DROP TABLE IF EXISTS `account_tbl`; +CREATE TABLE `account_tbl` +( + `id` int(11) NOT NULL AUTO_INCREMENT, + `user_id` varchar(255) DEFAULT NULL, + `money` int(11) DEFAULT 0, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +---INITIALIZE THE ACCOUNT TABLE +INSERT INTO account_tbl(`user_id`,`money`) VALUES('ACC_001','1000'); +---INITIALIZE THE STOCK TABLE +INSERT INTO stock_tbl(`commodity_code`,`count`) VALUES('STOCK_001','100'); + +``` +### 请依次执行以下操作: +* 1.1 创建seata数据库(实际业务场景中会使用不同的数据库,本文为了方便演示仅创建一个数据库,所有的表都在该数据库中创建) +* 1.2 执行undo_log.sql表中的脚本完成AT模式所需的undo_log表创建 +* 1.3 执行dubbo_biz.sql表中的脚本完成示例业务表创建以及测试数据的初始化 + +## 步骤 2:更新spring-boot应用配置中的数据库连接信息 + +请将以下3个子模块的数据库连接信息更新为你的信息,其他配置无需更改,至此,客户端的配置已经完毕。 + +* dubbo-samples-seata-account +* dubbo-samples-seata-order +* dubbo-samples-seata-stock +```yaml +url: jdbc:mysql://127.0.0.1:3306/seata?serverTimezone=Asia/Shanghai&useSSL=false&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useOldAliasMetadataBehavior=true +username: root +password: 123456 +``` + +## 步骤 3:启动Seata-Server +- 本文使用的是Seata-Server V2.0.0版本。 + +请将下载的Seata-Server二进制包解压,并进入bin目录,然后执行以下命令即可启动Seata-Server。 + +如果你是Mac OS 或者Linux操作系统,请执行: +``` +./seata-server.sh +``` +或者你是Windows操作系统,请执行: +``` +./seata-server.bat +``` + +## 步骤 4:启动示例 + +一切准备就绪,开始启动示例 + +### 请依次启动以下子项目: +* 4.1 Account Service +* 4.2 Order Service +* 4.3 Stock Service +* 4.4 Business Service + +## 步骤 5:查看分布式事务执行结果 +通过访问以下链接,可以测试分布式事务成功提交流程: + +http://127.0.0.1:9999/test/commit?userId=ACC_001&commodityCode=STOCK_001&orderCount=1 + +**分布式事务成功提交时,业务表的数据将正常更新,请注意观察数据库表中的数据。** + +通过访问以下链接,可以测试分布式事务失败回滚流程: + +http://127.0.0.1:9999/test/rollback?userId=ACC_001&commodityCode=STOCK_001&orderCount=1 + +**分布式事务失败回滚时,业务表的数据将没有任何改变,请注意观察数据库表中的数据。** + +## 附录 +* 支持的事务模式:Seata目前支持AT、TCC、SAGA、XA等模式,详情请访问[Seata官网](https://seata.apache.org/zh-cn/docs/user/mode/at)进行了解 +* 支持的配置中心:Seata支持丰富的配置中心,如zookeeper、nacos、consul、apollo、etcd、file(本文使用此配置中心,无需第三方依赖,方便快速演示),详情请访问[Seata配置中心](https://seata.apache.org/zh-cn/docs/user/configuration/)进行了解 +* 支持的注册中心:Seata支持丰富的注册中心,如eureka、sofa、redis、zookeeper、nacos、consul、etcd、file(本文使用此注册中心,无需第三方依赖,方便快速演示),详情请访问[Seata注册中心](https://seata.apache.org/zh-cn/docs/user/registry/)进行了解 +* 支持的部署方式:直接部署、Docker、K8S、Helm等部署方式,详情请访问[Seata部署方式](https://seata.apache.org/zh-cn/docs/ops/deploy-guide-beginner)进行了解 +* 支持的API:Seata的API分为两大类:High-Level API 和 Low-Level API,详情请访问[Seata API](https://seata.apache.org/zh-cn/docs/user/api)进行了解 +* 支持的数据库:Seata支持MySQL、Oracle、PostgreSQL、TiDB、MariaDB等数据库,不同的事务模式会有差别,详情请访问[Seata支持的数据库](https://seata.apache.org/zh-cn/docs/user/datasource)进行了解 +* 支持ORM框架:Seata 虽然是保证数据一致性的组件,但对于 ORM 框架并没有特殊的要求,像主流的Mybatis,Mybatis-Plus,Spring Data JPA, Hibernate等都支持。这是因为ORM框架位于JDBC结构的上层,而 Seata 的 AT,XA 事务模式是对 JDBC 标准接口操作的拦截和增强。详情请访问[Seata支持的ORM框架](https://seata.apache.org/zh-cn/docs/user/ormframework)进行了解 +* 支持的微服务框架:Seata目前支持Dubbo、gRPC、hsf、http、motan、sofa等框架,同时seata提供了丰富的拓展机制,理论上可以支持任何微服务框架。详情请访问[Seata支持的微服务框架](https://seata.apache.org/zh-cn/docs/user/microservice)进行了解 +* SQL限制:Seata 事务目前支持 INSERT、UPDATE、DELETE 三类 DML 语法的部分功能,这些类型都是已经经过Seata开源社区的验证。SQL 的支持范围还在不断扩大,建议在本文限制的范围内使用。详情请访问[Seata SQL限制](https://seata.apache.org/zh-cn/docs/user/sqlreference/sql-restrictions)进行了解 diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/troubleshoot/_index.md b/content/zh-cn/overview/mannual/java-sdk/tasks/troubleshoot/_index.md new file mode 100755 index 000000000000..96c7baa73055 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/troubleshoot/_index.md @@ -0,0 +1,10 @@ +--- +aliases: + - /zh/overview/tasks/troubleshoot/ + - /zh-cn/overview/tasks/troubleshoot/ +description: 对常见的 Dubbo 异常场景进行排查的思路 +linkTitle: 故障排查 +title: 故障排查 +type: docs +weight: 100 +--- diff --git a/content/zh-cn/overview/tasks/troubleshoot/no-provider.md b/content/zh-cn/overview/mannual/java-sdk/tasks/troubleshoot/no-provider.md similarity index 99% rename from content/zh-cn/overview/tasks/troubleshoot/no-provider.md rename to content/zh-cn/overview/mannual/java-sdk/tasks/troubleshoot/no-provider.md index 7de089a84456..50b70e0da9d7 100644 --- a/content/zh-cn/overview/tasks/troubleshoot/no-provider.md +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/troubleshoot/no-provider.md @@ -1,6 +1,7 @@ --- aliases: - /zh/overview/tasks/troubleshoot/no-provider/ + - /zh-cn/overview/tasks/troubleshoot/no-provider/ description: 在 Dubbo 抛出地址找不到异常的时候的排查思路 linkTitle: 地址找不到异常 title: 地址找不到异常 diff --git a/content/zh-cn/overview/mannual/java-sdk/tasks/troubleshoot/profiler.md b/content/zh-cn/overview/mannual/java-sdk/tasks/troubleshoot/profiler.md new file mode 100644 index 000000000000..0c4c0a213e2f --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/troubleshoot/profiler.md @@ -0,0 +1,190 @@ +--- +aliases: + - /zh/docs3-v2/java-sdk/advanced-features-and-usage/performance/profiler/ + - /zh-cn/docs3-v2/java-sdk/advanced-features-and-usage/performance/profiler/ +description: Dubbo 请求耗时采样 +linkTitle: 请求耗时采样 +title: 请求耗时采样 +type: docs +weight: 1 +--- + + +性能采样功能可以对 Dubbo 处理链路上的各处耗时进行检测,在出现超时的时候 `( usageTime / timeout > profilerWarnPercent * 100 )` 通过日志记录调用的耗时。 + +此功能分为 `simple profiler` 和 `detail profiler` 两个模式,其中 `simple profiler` 模式默认开启,`detail profiler` 模式默认关闭。 +`detail profiler` 相较 `simple profiler` 模式多采集了每个 filter 的处理耗时、协议上的具体耗时等。 +在 `simple profiler` 模式下如果发现 Dubbo 框架内部存在耗时长的情况,可以开启 `detail profiler` 模式,以便更好地排查问题。 + +## 使用场景 + +需要对 Dubbo 请求的精确耗时进行采集分析的场景,如服务不明原因的超时等 + +## 使用方式 + +`simple profiler` 默认自动开启,对于请求处理时间超过超时时间 3/4 的,都会通过日志打印出慢调用信息。如果需要开启 `detail profiler` 模式或者修改超时告警比例,可以参考[性能采样命令](/zh-cn/overview/mannual/java-sdk/reference-manual/qos/profiler/)文档。 + +### 日志说明 + +日志中各字段的含义如下: + +``` +[Dubbo-Consumer] execute service 接口#方法 cost 实际耗时, this invocation almost (maybe already) timeout. Timeout: 超时时间 +invocation context: +请求上下文 +thread info: +Start time: 开始请求时间(nano 时间) ++-[ Offset: 当前节点开始时间; Usage: 当前节点使用总耗时, 当前节点耗时比例 ] 当前节点描述 + +-[ Offset: 当前节点开始时间; Usage: 当前节点使用总耗时, 当前节点耗时比例 ] 当前节点描述 +``` + +对于请求耗时这里以两个例子进行介绍: + +``` +methodA() { + do something (1) + methodB (2) + do something (3) +} + +methodB() { + do something (4) + methodC (5) + do something (6) +} + +methodC() { + do something (7) +} + ++-[ Offset: 0 ms; Usage: (1) + (2) + (3) ms] execute methodA + +-[ Offset: (1) ms; Usage: (4) + (5) + (6) = (2) ms ] execute methodB + +-[ Offset: (1) + (4) ms; Usage: (7) = (5) ms ] execute methodC + +(1) (2) (3) ... 均为时间占位符 +``` + +``` +methodA() { + do something (1) + methodB (2) + methodE (3) + do something (4) +} + +methodB() { + do something (5) + methodC (6) + methodD (7) + do something (8) +} + +methodC() { + do something (9) +} + +methodD() { + do something (10) +} + +methodE() { + do something (11) +} + ++-[ Offset: 0 ms; Usage: (1) + (2) + (3) + (4) ms] execute methodA + +-[ Offset: (1) ms; Usage: (5) + (6) + (7) + (8) = (2) ms ] execute methodB + +-[ Offset: (1) + (5) ms; Usage: (9) = (6) ms ] execute methodC + +-[ Offset: (1) + (5) + (6) ms; Usage: (10) = (7) ms ] execute methodD + +-[ Offset: (1) + (2) ms; Usage: (11) = (3) ms ] execute methodE + +(1) (2) (3) ... 均为时间占位符 +``` + +### simple profiler + +Consumer 侧: +``` +[19/07/22 07:08:35:035 CST] main WARN proxy.InvokerInvocationHandler: [DUBBO] [Dubbo-Consumer] execute service org.apache.dubbo.samples.api.GreetingsService#sayHi cost 1003.015746 ms, this invocation almost (maybe already) timeout. Timeout: 1000ms +invocation context: +path=org.apache.dubbo.samples.api.GreetingsService; +remote.application=first-dubbo-consumer; +interface=org.apache.dubbo.samples.api.GreetingsService; +version=0.0.0; +timeout=1000; +thread info: +Start time: 285821581299853 ++-[ Offset: 0.000000ms; Usage: 1003.015746ms, 100% ] Receive request. Client invoke begin. ServiceKey: org.apache.dubbo.samples.api.GreetingsService MethodName:sayHi + +-[ Offset: 7.987015ms; Usage: 994.207928ms, 99% ] Invoker invoke. Target Address: xx.xx.xx.xx:20880, dubbo version: 3.0.10-SNAPSHOT, current host: xx.xx.xx.xx +``` + +Provider 侧: +``` +[19/07/22 07:08:35:035 CST] DubboServerHandler-30.227.64.173:20880-thread-2 WARN filter.ProfilerServerFilter: [DUBBO] [Dubbo-Provider] execute service org.apache.dubbo.samples.api.GreetingsService:0.0.0#sayHi cost 808.494672 ms, this invocation almost (maybe already) timeout. Timeout: 1000ms +client: xx.xx.xx.xx:51604 +invocation context: +input=281; +path=org.apache.dubbo.samples.api.GreetingsService; +remote.application=first-dubbo-consumer; +dubbo=2.0.2; +interface=org.apache.dubbo.samples.api.GreetingsService; +version=0.0.0; +timeout=1000; +thread info: +Start time: 285821754461125 ++-[ Offset: 0.000000ms; Usage: 808.494672ms, 100% ] Receive request. Server invoke begin. + +-[ Offset: 1.030912ms; Usage: 804.236342ms, 99% ] Receive request. Server biz impl invoke begin., dubbo version: 3.0.10-SNAPSHOT, current host: xx.xx.xx.xx +``` + +### detail profiler + +Consumer 侧: +``` +[19/07/22 07:10:59:059 CST] main WARN proxy.InvokerInvocationHandler: [DUBBO] [Dubbo-Consumer] execute service org.apache.dubbo.samples.api.GreetingsService#sayHi cost 990.828336 ms, this invocation almost (maybe already) timeout. Timeout: 1000ms +invocation context: +path=org.apache.dubbo.samples.api.GreetingsService; +remote.application=first-dubbo-consumer; +interface=org.apache.dubbo.samples.api.GreetingsService; +version=0.0.0; +timeout=1000; +thread info: +Start time: 285965458479241 ++-[ Offset: 0.000000ms; Usage: 990.828336ms, 100% ] Receive request. Client invoke begin. ServiceKey: org.apache.dubbo.samples.api.GreetingsService MethodName:sayHi + +-[ Offset: 0.852044ms; Usage: 989.899439ms, 99% ] Filter org.apache.dubbo.rpc.cluster.filter.support.ConsumerContextFilter invoke. + +-[ Offset: 1.814858ms; Usage: 988.924876ms, 99% ] Filter org.apache.dubbo.rpc.protocol.dubbo.filter.FutureFilter invoke. + +-[ Offset: 1.853211ms; Usage: 988.877928ms, 99% ] Filter org.apache.dubbo.monitor.support.MonitorClusterFilter invoke. + +-[ Offset: 1.873243ms; Usage: 988.661708ms, 99% ] Filter org.apache.dubbo.rpc.cluster.router.RouterSnapshotFilter invoke. + +-[ Offset: 2.159140ms; Usage: 0.504939ms, 0% ] Router route. + +-[ Offset: 8.125823ms; Usage: 981.748366ms, 99% ] Cluster org.apache.dubbo.rpc.cluster.support.FailoverClusterInvoker invoke. + +-[ Offset: 8.258359ms; Usage: 981.612033ms, 99% ] Invoker invoke. Target Address: xx.xx.xx.xx:20880, dubbo version: 3.0.10-SNAPSHOT, current host: xx.xx.xx.xx +``` + +Provider 侧: +``` +[19/07/22 07:10:59:059 CST] DubboServerHandler-30.227.64.173:20880-thread-2 WARN filter.ProfilerServerFilter: [DUBBO] [Dubbo-Provider] execute service org.apache.dubbo.samples.api.GreetingsService:0.0.0#sayHi cost 811.017347 ms, this invocation almost (maybe already) timeout. Timeout: 1000ms +client: xx.xx.xx.xx:52019 +invocation context: +input=281; +path=org.apache.dubbo.samples.api.GreetingsService; +remote.application=first-dubbo-consumer; +dubbo=2.0.2; +interface=org.apache.dubbo.samples.api.GreetingsService; +version=0.0.0; +timeout=1000; +thread info: +Start time: 285965612316294 ++-[ Offset: 0.000000ms; Usage: 811.017347ms, 100% ] Receive request. Server invoke begin. + +-[ Offset: 1.096880ms; Usage: 809.916668ms, 99% ] Filter org.apache.dubbo.rpc.filter.EchoFilter invoke. + +-[ Offset: 1.133478ms; Usage: 809.866204ms, 99% ] Filter org.apache.dubbo.rpc.filter.ClassLoaderFilter invoke. + +-[ Offset: 1.157563ms; Usage: 809.838572ms, 99% ] Filter org.apache.dubbo.rpc.filter.GenericFilter invoke. + +-[ Offset: 1.202075ms; Usage: 809.736843ms, 99% ] Filter org.apache.dubbo.rpc.filter.ContextFilter invoke. + +-[ Offset: 1.433193ms; Usage: 809.504401ms, 99% ] Filter org.apache.dubbo.auth.filter.ProviderAuthFilter invoke. + +-[ Offset: 1.470760ms; Usage: 809.464291ms, 99% ] Filter org.apache.dubbo.rpc.filter.ExceptionFilter invoke. + +-[ Offset: 1.489103ms; Usage: 809.440183ms, 99% ] Filter org.apache.dubbo.monitor.support.MonitorFilter invoke. + +-[ Offset: 1.515757ms; Usage: 809.381893ms, 99% ] Filter org.apache.dubbo.rpc.filter.TimeoutFilter invoke. + +-[ Offset: 1.526632ms; Usage: 809.366553ms, 99% ] Filter org.apache.dubbo.rpc.protocol.dubbo.filter.TraceFilter invoke. + +-[ Offset: 1.536964ms; Usage: 809.335907ms, 99% ] Filter org.apache.dubbo.rpc.filter.ClassLoaderCallbackFilter invoke. + +-[ Offset: 1.558545ms; Usage: 804.276436ms, 99% ] Receive request. Server biz impl invoke begin., dubbo version: 3.0.10-SNAPSHOT, current host: xx.xx.xx.xx +``` +{{% alert title="注意" color="warning" %}} +由于日志框架不匹配导致的日志为空可以参考[日志框架适配及运行时管理](../../others/logger-management/)动态修改日志输出框架。 +{{% /alert %}} diff --git a/content/zh-cn/overview/tasks/troubleshoot/request-failed.md b/content/zh-cn/overview/mannual/java-sdk/tasks/troubleshoot/request-failed.md similarity index 99% rename from content/zh-cn/overview/tasks/troubleshoot/request-failed.md rename to content/zh-cn/overview/mannual/java-sdk/tasks/troubleshoot/request-failed.md index a091f10bdc95..f5d3322f0514 100644 --- a/content/zh-cn/overview/tasks/troubleshoot/request-failed.md +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/troubleshoot/request-failed.md @@ -1,6 +1,7 @@ --- aliases: - /zh/overview/tasks/troubleshoot/request-failed/ + - /zh-cn/overview/tasks/troubleshoot/request-failed/ description: 在 Dubbo 请求成功率低时的排查思路 linkTitle: 请求成功率低 title: 请求成功率低 diff --git a/content/zh-cn/overview/tasks/troubleshoot/start-failed.md b/content/zh-cn/overview/mannual/java-sdk/tasks/troubleshoot/start-failed.md similarity index 99% rename from content/zh-cn/overview/tasks/troubleshoot/start-failed.md rename to content/zh-cn/overview/mannual/java-sdk/tasks/troubleshoot/start-failed.md index 654cde39a199..b89baf6503da 100644 --- a/content/zh-cn/overview/tasks/troubleshoot/start-failed.md +++ b/content/zh-cn/overview/mannual/java-sdk/tasks/troubleshoot/start-failed.md @@ -1,6 +1,7 @@ --- aliases: - /zh/overview/tasks/troubleshoot/start-failed/ + - /zh-cn/overview/tasks/troubleshoot/start-failed/ description: 在 Dubbo 应用启动失败时的排查思路 linkTitle: 应用启动失败 title: 应用启动失败 diff --git a/content/zh-cn/overview/mannual/java-sdk/upgrades-and-compatibility/3.2-to-3.3-compatibility-guide.md b/content/zh-cn/overview/mannual/java-sdk/upgrades-and-compatibility/3.2-to-3.3-compatibility-guide.md deleted file mode 100644 index d1ade3498319..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/upgrades-and-compatibility/3.2-to-3.3-compatibility-guide.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/upgrades-and-compatibility/3.2-to-3.3-compatibility-guide/ - - /zh-cn/docs3-v2/java-sdk/upgrades-and-compatibility/3.2-to-3.3-compatibility-guide/ -description: Dubbo 3.3 升级与兼容性指南 -linkTitle: 3.2 升级至 3.3 -title: 3.2 升级至 3.3 -type: docs -weight: 4 - ---- - - - - - - -## 功能修改点 - -### 1. 移除了dubbo-native-plugin - -在 3.3 版本中,移除了 dubbo-native-plugin。并且dubbo-native-plugin相关的功能都将迁移至dubbo-maven-plugin。 - -为什么要做这个迁移和调整? - -1. 为了提升用户的使用体验,后续dubbo有关maven的插件能力都将统一使用dubbo-maven-plugin来提供。方便Dubbo用户使用和接入。而不需要一个特性对应一个插件,导致用户需要依赖多个plugin。 -2. 更加有利于后续Dubbo提供maven plugin能力时的维护和特性增强。 - diff --git a/content/zh-cn/overview/mannual/java-sdk/upgrades-and-compatibility/_index.md b/content/zh-cn/overview/mannual/java-sdk/upgrades-and-compatibility/_index.md deleted file mode 100755 index 5525f42f163c..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/upgrades-and-compatibility/_index.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/upgrades-and-compatibility/ - - /zh-cn/docs3-v2/java-sdk/upgrades-and-compatibility/ -description: 升级和兼容性 -linkTitle: 升级和兼容性 -title: 升级和兼容性 -type: docs -weight: 5 ---- diff --git a/content/zh-cn/overview/mannual/java-sdk/upgrades-and-compatibility/migration-triple.md b/content/zh-cn/overview/mannual/java-sdk/upgrades-and-compatibility/migration-triple.md deleted file mode 100644 index da20bd6ecdd1..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/upgrades-and-compatibility/migration-triple.md +++ /dev/null @@ -1,350 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/upgrades-and-compatibility/migration-triple/ - - /zh-cn/docs3-v2/java-sdk/upgrades-and-compatibility/migration-triple/ -description: Triple 协议迁移指南 -linkTitle: Dubbo 协议迁移至 Triple 协议 -title: Dubbo 协议迁移至 Triple 协议 -type: docs -weight: 7 ---- - - - - - - -## Triple 协议介绍 - -根据 Triple 设计的目标,`Triple` 协议有以下优势: - -- 具备跨语言交互的能力,传统的多语言多 SDK 模式和 Mesh 化跨语言模式都需要一种更通用易扩展的数据传输协议。 -- 提供更完善的请求模型,除了支持传统的 Request/Response 模型(Unary 单向通信),还支持 Stream(流式通信) 和 Bidirectional(双向通信)。 -- 易扩展、穿透性高,包括但不限于 Tracing / Monitoring 等支持,也应该能被各层设备识别,网关设施等可以识别数据报文,对 Service Mesh 部署友好,降低用户理解难度。 -- 完全兼容 grpc,客户端/服务端可以与原生grpc客户端打通。 -- 可以复用现有 grpc 生态下的组件, 满足云原生场景下的跨语言、跨环境、跨平台的互通需求。 - -当前使用其他协议的 Dubbo 用户,框架提供了兼容现有序列化方式的迁移能力,在不影响线上已有业务的前提下,迁移协议的成本几乎为零。 - -需要新增对接 Grpc 服务的 Dubbo 用户,可以直接使用 Triple 协议来实现打通,不需要单独引入 grpc client 来完成,不仅能保留已有的 Dubbo 易用性,也能降低程序的复杂度和开发运维成本,不需要额外进行适配和开发即可接入现有生态。 - -对于需要网关接入的 Dubbo 用户,Triple 协议提供了更加原生的方式,让网关开发或者使用开源的 grpc 网关组件更加简单。网关可以选择不解析 payload ,在性能上也有很大提高。在使用 Dubbo 协议时,语言相关的序列化方式是网关的一个很大痛点,而传统的 HTTP 转 Dubbo 的方式对于跨语言序列化几乎是无能为力的。同时,由于 Triple 的协议元数据都存储在请求头中,网关可以轻松的实现定制需求,如路由和限流等功能。 - -> `Triple` 协议的格式和原理请参阅 [RPC 通信协议](/zh-cn/docs/concepts/rpc-protocol/) - -## Dubbo2 协议迁移流程 - -Dubbo2 的用户使用 dubbo 协议 + 自定义序列化,如 hessian2 完成远程调用。 - -而 Grpc 的默认仅支持 Protobuf 序列化,对于 Java 语言中的多参数以及方法重载也无法支持。 - -Dubbo3的之初就有一条目标是完美兼容 Dubbo2,所以为了 Dubbo2 能够平滑升级, Dubbo 框架侧做了很多工作来保证升级的无感,目前默认的序列化和 Dubbo2 保持一致为`hessian2`。 - -所以,如果决定要升级到 Dubbo3 的 `Triple` 协议,只需要修改配置中的协议名称为 `tri` (注意: 不是triple)即可。 - -接下来我们我们以一个使用 Dubbo2 协议的[工程](https://github.com/apache/dubbo-samples/tree/master/3-extensions/protocol/dubbo-samples-triple/src/main/java/org/apache/dubbo/sample/tri/migration) 来举例,如何一步一步安全的升级。 - -1. 仅使用 `dubbo` 协议启动 `provider` 和 `consumer`,并完成调用。 -2. 使用 `dubbo` 和 `tri` 协议 启动`provider`,以 `dubbo` 协议启动 `consumer`,并完成调用。 -3. 仅使用 `tri` 协议 启动 `provider`和 `consumer`,并完成调用。 - -### 定义服务 - -1. 定义接口 -```java -public interface IWrapperGreeter { - - //... - - /** - * 这是一个普通接口,没有使用 pb 序列化 - */ - String sayHello(String request); - -} -``` - -2. 实现类如下 -```java -public class IGreeter2Impl implements IWrapperGreeter { - - @Override - public String sayHello(String request) { - return "hello," + request; - } -} -``` - -### 仅使用 triple 协议 - -当所有的 consuemr 都升级至支持 `Triple` 协议的版本后,provider 可切换至仅使用 `Triple` 协议启动 - -结构如图所示: -![strust](/imgs/v3/migration/tri/migrate-only-tri-strust.png) - -[Provider](https://github.com/apache/dubbo-samples/blob/master/3-extensions/protocol/dubbo-samples-triple/src/main/java/org/apache/dubbo/sample/tri/migration/ApiMigrationTriProvider.java) -和 [Consumer](https://github.com/apache/dubbo-samples/blob/master/3-extensions/protocol/dubbo-samples-triple/src/main/java/org/apache/dubbo/sample/tri/migration/ApiMigrationTriConsumer.java) 完成调用,输出如下: - -![result](/imgs/v3/migration/tri/dubbo3-tri-migration-tri-tri-result.png) - -### 仅使用 dubbo 协议 - -为保证兼容性,我们先将部分 provider 升级到 `dubbo3` 版本并使用 `dubbo` 协议。 - -使用 `dubbo` 协议启动一个 [`Provider`](https://github.com/apache/dubbo-samples/blob/master/3-extensions/protocol/dubbo-samples-triple/src/main/java/org/apache/dubbo/sample/tri/migration/ApiMigrationDubboProvider.java) 和 [`Consumer`](https://github.com/apache/dubbo-samples/blob/master/3-extensions/protocol/dubbo-samples-triple/src/main/java/org/apache/dubbo/sample/tri/migration/ApiMigrationDubboConsumer.java) ,完成调用,输出如下: -![result](/imgs/v3/migration/tri/dubbo3-tri-migration-dubbo-dubbo-result.png) - -### 同时使用两协议 - -对于线上服务的升级,不可能一蹴而就同时完成 provider 和 consumer 升级, 需要按步操作,保证业务稳定。 -第二步, provider 提供双协议的方式同时支持 dubbo + tri 两种协议的客户端。 - -结构如图所示: -![strust](/imgs/v3/migration/tri/migrate-dubbo-tri-strust.png) - -> 按照推荐升级步骤,provider 已经支持了tri协议,所以 dubbo3的 consumer 可以直接使用 tri 协议 - -使用`dubbo`协议和`triple`协议启动[`Provider`](https://github.com/apache/dubbo-samples/blob/master/3-extensions/protocol/dubbo-samples-triple/src/main/java/org/apache/dubbo/sample/tri/migration/ApiMigrationBothProvider.java)和[`Consumer`](https://github.com/apache/dubbo-samples/blob/master/3-extensions/protocol/dubbo-samples-triple/src/main/java/org/apache/dubbo/sample/tri/migration/ApiMigrationBothConsumer.java),完成调用,输出如下: - -![result](/imgs/v3/migration/tri/dubbo3-tri-migration-both-dubbo-tri-result.png) - - -### 实现原理 - -通过上面介绍的升级过程,我们可以很简单的通过修改协议类型来完成升级。框架是怎么帮我们做到这些的呢? - -通过对 `Triple` 协议的介绍,我们知道Dubbo3的 `Triple` 的数据类型是 `protobuf` 对象,那为什么非 `protobuf` 的 java 对象也可以被正常传输呢。 - -这里 Dubbo3 使用了一个巧妙的设计,首先判断参数类型是否为 `protobuf` 对象,如果不是。用一个 `protobuf` 对象将 `request` 和 `response` 进行 wrapper,这样就屏蔽了其他各种序列化带来的复杂度。在 `wrapper` 对象内部声明序列化类型,来支持序列化的扩展。 - -wrapper 的`protobuf`的 IDL如下: -```proto -syntax = "proto3"; - -package org.apache.dubbo.triple; - -message TripleRequestWrapper { - // hessian4 - // json - string serializeType = 1; - repeated bytes args = 2; - repeated string argTypes = 3; -} - -message TripleResponseWrapper { - string serializeType = 1; - bytes data = 2; - string type = 3; -} -``` - -对于请求,使用`TripleRequestWrapper`进行包装,对于响应使用`TripleResponseWrapper`进行包装。 - -> 对于请求参数,可以看到 args 被`repeated`修饰,这是因为需要支持 java 方法的多个参数。当然,序列化只能是一种。序列化的实现沿用 Dubbo2 实现的 spi - - -## 多语言用户 - -使用 `protobuf` 建议新服务均使用该方式,对于 Dubbo3 和 Triple 来说,主推的是使用 `protobuf` 序列化,并且使用 `proto` 定义的 `IDL` 来生成相关接口定义。以 `IDL` 做为多语言中的通用接口约定,加上 `Triple` 与 `Grpc` 的天然互通性,可以轻松地实现跨语言交互,例如 Go 语言等。 - -将编写好的 `.proto` 文件使用 `dubbo-compiler` 插件进行编译并编写实现类,完成方法调用: - -![result](/imgs/v3/migration/tri/dubbo3-tri-migration-tri-tri-result.png) - -从上面升级的例子我们可以知道,`Triple` 协议使用 `protbuf` 对象序列化后进行传输,所以对于本身就是 `protobuf` 对象的方法来说,没有任何其他逻辑。 - -使用 `protobuf` 插件编译后接口如下: -```java -public interface PbGreeter { - - static final String JAVA_SERVICE_NAME = "org.apache.dubbo.sample.tri.PbGreeter"; - static final String SERVICE_NAME = "org.apache.dubbo.sample.tri.PbGreeter"; - - static final boolean inited = PbGreeterDubbo.init(); - - org.apache.dubbo.sample.tri.GreeterReply greet(org.apache.dubbo.sample.tri.GreeterRequest request); - - default CompletableFuture greetAsync(org.apache.dubbo.sample.tri.GreeterRequest request){ - return CompletableFuture.supplyAsync(() -> greet(request)); - } - - void greetServerStream(org.apache.dubbo.sample.tri.GreeterRequest request, org.apache.dubbo.common.stream.StreamObserver responseObserver); - - org.apache.dubbo.common.stream.StreamObserver greetStream(org.apache.dubbo.common.stream.StreamObserver responseObserver); -} -``` - -## Triple 新特性 Stream 流 -Stream 是 Dubbo3 新提供的一种调用类型,在以下场景时建议使用流的方式: - -- 接口需要发送大量数据,这些数据无法被放在一个 RPC 的请求或响应中,需要分批发送,但应用层如果按照传统的多次 RPC 方式无法解决顺序和性能的问题,如果需要保证有序,则只能串行发送 -- 流式场景,数据需要按照发送顺序处理, 数据本身是没有确定边界的 -- 推送类场景,多个消息在同一个调用的上下文中被发送和处理 - -Stream 分为以下三种: -- SERVER_STREAM(服务端流) -![SERVER_STREAM](/imgs/v3/migration/tri/migrate-server-stream.png) -- CLIENT_STREAM(客户端流) -![CLIENT_STREAM](/imgs/v3/migration/tri/migrate-client-stream.png) -- BIDIRECTIONAL_STREAM(双向流) -![BIDIRECTIONAL_STREAM](/imgs/v3/migration/tri/migrate-bi-stream.png) - -> 由于 `java` 语言的限制,BIDIRECTIONAL_STREAM 和 CLIENT_STREAM 的实现是一样的。 - -在 Dubbo3 中,流式接口以 `SteamObserver` 声明和使用,用户可以通过使用和实现这个接口来发送和处理流的数据、异常和结束。 - -> 对于 Dubbo2 用户来说,可能会对StreamObserver感到陌生,这是Dubbo3定义的一种流类型,Dubbo2 中并不存在 Stream 的类型,所以对于迁移场景没有任何影响。 - -流的语义保证 -- 提供消息边界,可以方便地对消息单独处理 -- 严格有序,发送端的顺序和接收端顺序一致 -- 全双工,发送不需要等待 -- 支持取消和超时 - -## 非 PB 序列化的流 -1. api -```java -public interface IWrapperGreeter { - - StreamObserver sayHelloStream(StreamObserver response); - - void sayHelloServerStream(String request, StreamObserver response); -} -``` - -> Stream 方法的方法入参和返回值是严格约定的,为防止写错而导致问题,Dubbo3 框架侧做了对参数的检查, 如果出错则会抛出异常。 -> 对于 `双向流(BIDIRECTIONAL_STREAM)`, 需要注意参数中的 `StreamObserver` 是响应流,返回参数中的 `StreamObserver` 为请求流。 - -2. 实现类 -```java -public class WrapGreeterImpl implements WrapGreeter { - - //... - - @Override - public StreamObserver sayHelloStream(StreamObserver response) { - return new StreamObserver() { - @Override - public void onNext(String data) { - System.out.println(data); - response.onNext("hello,"+data); - } - - @Override - public void onError(Throwable throwable) { - throwable.printStackTrace(); - } - - @Override - public void onCompleted() { - System.out.println("onCompleted"); - response.onCompleted(); - } - }; - } - - @Override - public void sayHelloServerStream(String request, StreamObserver response) { - for (int i = 0; i < 10; i++) { - response.onNext("hello," + request); - } - response.onCompleted(); - } -} -``` - -3. 调用方式 -```java -delegate.sayHelloServerStream("server stream", new StreamObserver() { - @Override - public void onNext(String data) { - System.out.println(data); - } - - @Override - public void onError(Throwable throwable) { - throwable.printStackTrace(); - } - - @Override - public void onCompleted() { - System.out.println("onCompleted"); - } -}); - - -StreamObserver request = delegate.sayHelloStream(new StreamObserver() { - @Override - public void onNext(String data) { - System.out.println(data); - } - - @Override - public void onError(Throwable throwable) { - throwable.printStackTrace(); - } - - @Override - public void onCompleted() { - System.out.println("onCompleted"); - } -}); -for (int i = 0; i < n; i++) { - request.onNext("stream request" + i); -} -request.onCompleted(); -``` - -## Protobuf 序列化的流 - -对于 `Protobuf` 序列化方式,推荐编写 `IDL` 使用 `compiler` 插件进行编译生成。生成的代码大致如下: -```java -public interface PbGreeter { - - static final String JAVA_SERVICE_NAME = "org.apache.dubbo.sample.tri.PbGreeter"; - static final String SERVICE_NAME = "org.apache.dubbo.sample.tri.PbGreeter"; - - static final boolean inited = PbGreeterDubbo.init(); - - //... - - void greetServerStream(org.apache.dubbo.sample.tri.GreeterRequest request, org.apache.dubbo.common.stream.StreamObserver responseObserver); - - org.apache.dubbo.common.stream.StreamObserver greetStream(org.apache.dubbo.common.stream.StreamObserver responseObserver); -} -``` - -## 流的实现原理 - -`Triple`协议的流模式是怎么支持的呢? - -- 从协议层来说,`Triple` 是建立在 `HTTP2` 基础上的,所以直接拥有所有 `HTTP2` 的能力,故拥有了分 `stream` 和全双工的能力。 - -- 框架层来说,`StreamObserver` 作为流的接口提供给用户,用于入参和出参提供流式处理。框架在收发 stream data 时进行相应的接口调用, 从而保证流的生命周期完整。 - -## Triple 与应用级注册发现 - -关于 Triple 协议的应用级服务注册和发现和其他语言是一致的,可以通过下列内容了解更多。 - -- [服务发现](/zh-cn/docs/concepts/service-discovery/) -- [应用级地址发现迁移指南](/zh-cn/docs/migration/migration-service-discovery/) - -## 与 GRPC 互通 - -通过对于协议的介绍,我们知道 `Triple` 协议是基于 `HTTP2` 并兼容 `GRPC`。为了保证和验证与`GRPC`互通能力,Dubbo3 也编写了各种从场景下的测试。详细的可以通过[这里](https://github.com/apache/dubbo-samples/blob/master/3-extensions/protocol/dubbo-samples-triple/README.MD) 了解更多。 - - -{{% alert title="未来: Everything on Stub" color="primary" %}} - -用过 `Grpc` 的同学应该对 `Stub` 都不陌生。 -Grpc 使用 `compiler` 将编写的 `proto` 文件编译为相关的 protobuf 对象和相关 rpc 接口。默认的会同时生成几种不同的 `stub` - -- blockingStub -- futureStub -- reactorStub -- ... - -`stub` 用一种统一的使用方式帮我们屏蔽了不同调用方式的细节。不过目前 `Dubbo3` 暂时只支持传统定义接口并进行调用的使用方式。 - -在不久的未来,`Triple` 也将实现各种常用的 `Stub`,让用户写一份`proto`文件,通过 `comipler` 可以在任意场景方便的使用,请拭目以待。 -{{% /alert %}} diff --git a/content/zh-cn/overview/mannual/java-sdk/upgrades-and-compatibility/protobuf&interface.md b/content/zh-cn/overview/mannual/java-sdk/upgrades-and-compatibility/protobuf&interface.md deleted file mode 100644 index 0cca5a72591a..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/upgrades-and-compatibility/protobuf&interface.md +++ /dev/null @@ -1,152 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/upgrades-and-compatibility/protobuf&interface/ - - /zh-cn/docs3-v2/java-sdk/upgrades-and-compatibility/protobuf&interface/ -description: Protobuf 与 Interface 差异对比指南 -linkTitle: Protobuf vs Interface -title: Protobuf 与 Interface -type: docs -weight: 6 ---- - - - - - -本文对比了Protobuf和Interface这2种IDL的差异,帮助Dubbo协议开发者了解Protobuf,为后续转到Triple协议和Grpc协议做铺垫。 - -## 1. 数据类型 - -### 1.1. 基本类型 - -| ptoto类型 | java类型 | -| ---- | ---- | -double | double -float | float -int32 | int -int64 | long -uint32 | int[注] -uint64 | long[注] -sint32 | int -sint64 | long -fixed32 | int[注] -fixed64 | long[注] -sfixed32 | int -sfixed64 | long -bool | boolean -string | String -bytes | ByteString - -{{% alert title="注意" color="primary" %}} -在Java中,无符号的32位和64位整数使用它们的有符号对数来表示,顶部位只存储在符号位中。 -{{% /alert %}} - -## 2. 复合类型 - -### 2.1. 枚举 - -* 原始pb代码 - -```java. -enum TrafficLightColor { - TRAFFIC_LIGHT_COLOR_INVALID = 0; - TRAFFIC_LIGHT_COLOR_UNSET = 1; - TRAFFIC_LIGHT_COLOR_GREEN = 2; - TRAFFIC_LIGHT_COLOR_YELLOW = 3; - TRAFFIC_LIGHT_COLOR_RED = 4; -} -``` - -* 生成的java代码 - -![image](/imgs/docs/advanced/protobufinterface/124234531-b96c2c80-db46-11eb-8155-a77dbe059f07.png) - -> 枚举是常量,因此采用大写 -### 2.2. 数组 - -* 原始pb代码 - -```java -message VipIDToRidReq { - repeated uint32 vipID = 1; -} -``` - -* 生成的java代码 - -![image](/imgs/docs/advanced/protobufinterface/124234564-c4bf5800-db46-11eb-94fc-a056af6089cb.png) - -> 底层实际上是1个ArrayList -### 2.3. 集合 - -PB不支持无序、不重复的集合,只能 ``借用数组实现``,需要 ``自行去重``。 - -### 2.4. 字典 - -* 原始pb代码 - -```java -message BatchOnlineRes { - map onlineMap = 1;//在线状态 -} -``` - -* 生成的java代码 - -![image](/imgs/docs/advanced/protobufinterface/124234654-e4568080-db46-11eb-9700-b30022ebee21.png) - -### 2.5. 嵌套 - -* 原始pb代码 - -```java -message BatchAnchorInfoRes { - map list = 1; //用户信息map列表 -} -/* -* 对应接口的功能: 批量或单个获取用户信息 -*/ -message AnchorInfo { - uint32 ownerUid = 1 [json_name="uid"]; //用户id - string nickName = 2 [json_name="nn"]; //用户昵称 - string smallAvatar = 3 [json_name="savt"]; //用户头像全路径-小 - string middleAvatar = 4 [json_name="mavt"]; //用户头像全路径-中 - string bigAvatar = 5 [json_name="bavt"]; //用户头像全路径-大 - string avatar = 6 [json_name="avt"]; //用户头像 -} -``` - -* 生成的java代码 - -![image](/imgs/docs/advanced/protobufinterface/124234723-f89a7d80-db46-11eb-82d0-a8aee5322098.png) - -## 3. 字段默认值 - -* 对于字符串,默认值为空字符串。 -* 对于字节,默认值为空字节。 -* 对于bools,默认值为false。 -* 对于数字类型,默认值为零。 -* 对于枚举,默认值为第一个定义的枚举值,它必须为0。 -* 对于消息字段,未设置字段。 它的确切值是语言相关的。 有关详细信息,请参阅生成的代码指南。 - -## 4. 整体结构 - -| Feature | Java Interface | Protobuf | 备注 | -| ---- | ---- | ---- | ---- | -| 方法重载 | √ | × | | -| 泛型/模板化 | √ | × | | -| 方法继承 | √ | × | | -| 嵌套定义 | √ | 部分支持 | PB仅支持message和enum嵌套 | -| import文件 | √ | √ | | -| 字段为null | √ | × | | -| 多个入参 | √ | × | PB仅支持单入参 | -| 0个入参 | √ | × | PB必须有入参 | -| 0个出参 | √ | × | PB必须有出参 | -| 入参/出参为抽象类 | √ | × | PB的入参/出参必须为具象类 | -| 入参/出参为接口 | √ | × | PB的入参/出参必须为具象类 | -| 入参/出参为基础类型 | √ | × | PB的入参/出参必须为结构体 | - -## 5. 社区资料 -* 社区主页地址:https://developers.google.cn/protocol-buffers/ -* 社区开源地址:https://github.com/google/protobuf -* 相关jar的maven:https://search.maven.org/search?q=com.google.protobuf diff --git a/content/zh-cn/overview/mannual/java-sdk/upgrades-and-compatibility/service-discovery/_index.md b/content/zh-cn/overview/mannual/java-sdk/upgrades-and-compatibility/service-discovery/_index.md deleted file mode 100755 index 0e8fa2bfab37..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/upgrades-and-compatibility/service-discovery/_index.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/upgrades-and-compatibility/service-discovery/ - - /zh-cn/docs3-v2/java-sdk/upgrades-and-compatibility/service-discovery/ -description: Dubbo 3 应用级服务发现指南 -linkTitle: 应用级服务发现 -title: 应用级服务发现 -type: docs -weight: 4 ---- diff --git a/content/zh-cn/overview/mannual/java-sdk/upgrades-and-compatibility/service-discovery/migration-service-discovery.md b/content/zh-cn/overview/mannual/java-sdk/upgrades-and-compatibility/service-discovery/migration-service-discovery.md deleted file mode 100644 index a4415014226b..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/upgrades-and-compatibility/service-discovery/migration-service-discovery.md +++ /dev/null @@ -1,168 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/upgrades-and-compatibility/service-discovery/migration-service-discovery/ - - /zh-cn/docs3-v2/java-sdk/upgrades-and-compatibility/service-discovery/migration-service-discovery/ -description: 本文档专门针对使用 2.x 版本的老用户,详细阐述了升级到 3.x 后的默认地址注册与发现行为、如何平滑的迁移到新版本的地址模型。 -linkTitle: 接口级服务发现迁移至应用级服务发现指南 -title: 接口级服务发现迁移至应用级服务发现指南 -type: docs -weight: 10 ---- - - - - - - -总体上来说,在地址注册与发现环节,`3.x` 是完全兼容 `2.x` 版本的,这意味着,用户可以选择将集群内任意数量的应用或机器升级到 `3.x`,同时在这个过程中保持与 `2.x` 版本的互操作性。 - -> 如关心迁移背后工作原理,请参考 [迁移规则详情与工作原理](../service-discovery-rule) - -## 1 快速升级步骤 - -简单的修改 pom.xml 到最新版本就可以完成升级,如果要迁移到应用级地址,只需要调整开关控制 3.x 版本的默认行为。 - -1. 升级 Provider 应用到最新 3.x 版本依赖,配置双注册开关`dubbo.application.register-mode=all`(建议通过全局配置中心设置,默认已自动开启),完成应用发布。 -2. 升级 Consumer 应用到最新 3.x 版本依赖,配置双订阅开关`dubbo.application.service-discovery.migration=APPLICATION_FIRST`(建议通过全局配置中心设置,默认已自动开启),完成应用发布。 -3. 在确认 Provider 的上有 Consumer 全部完成应用级地址迁移后,Provider 切到应用级地址单注册。完成升级 - - - -以下是关于迁移流程的详细描述。 - -## 2 Provider 端升级过程详解 - -在不改变任何 Dubbo 配置的情况下,可以将一个应用或实例升级到 3.x 版本,升级后的 Dubbo 实例会默保保证与 2.x 版本的兼容性,即会正常注册 2.x 格式的地址到注册中心,因此升级后的实例仍会对整个集群仍保持可见状态。 - - - -同时新的地址发现模型(注册应用级别的地址)也将会自动注册。 - -![//imgs/v3/migration/provider-registration.png](/imgs/v3/migration/provider-registration.png) - -通过 -D 参数,可以指定 provider 启动时的注册行为 - -```text --Ddubbo.application.register-mode=all -# 可选值 interface、instance、all,默认是 all,即接口级地址、应用级地址都注册 -``` - - - -另外,可以在配置中心修改全局默认行为,来控制所有 3.x 实例注册行为。其中,全局性开关的优先级低于 -D 参数。 - - - -为了保证平滑迁移,即升级到 3.x 的实例能同时被 2.x 与 3.x 的消费者实例发现,3.x 实例需要开启双注册;当所有上游的消费端都迁移到 3.x 的地址模型后,提供端就可以切换到 instance 模式(只注册应用级地址)。对于如何升级消费端到 3.x 请参见下一小节。 - -### 2.1 双注册带来的资源消耗 - -双注册不可避免的会带来额外的注册中心存储压力,但考虑到应用级地址发现模型的数据量在存储方面的极大优势,即使对于一些超大规模集群的用户而言,新增的数据量也并不会带来存储问题。总体来说,对于一个普通集群而言,数据增长可控制在之前数据总量的 1/100 ~ 1/1000 - -以一个中等规模的集群实例来说: 2000 实例、50个应用(500 个 Dubbo 接口,平均每个应用 10 个接口)。 - -​ 假设每个接口级 URL 地址平均大小为 5kb,每个应用级 URL 平均大小为 0.5kb - -​ 老的接口级地址量:2000 * 500 * 5kb ≈ 4.8G - -​ 新的应用级地址量:2000 * 50 * 0.5kb ≈ 48M - -​ 双注册后仅仅增加了 48M 的数据量。 - - - -## 3 Consumer 端升级过程 - -对于 2.x 的消费者实例,它们看到的自然都是 2.x 版本的提供者地址列表; - -对于 3.x 的消费者,它具备同时发现 2.x 与 3.x 提供者地址列表的能力。在默认情况下,如果集群中存在可以消费的 3.x 的地址,将自动消费 3.x 的地址,如果不存在新地址则自动消费 2.x 的地址。Dubbo3 提供了开关来控制这个行为: - -```text -dubbo.application.service-discovery.migration=APPLICATION_FIRST -# 可选值 -# FORCE_INTERFACE,只消费接口级地址,如无地址则报错,单订阅 2.x 地址 -# APPLICATION_FIRST,智能决策接口级/应用级地址,双订阅 -# FORCE_APPLICATION,只消费应用级地址,如无地址则报错,单订阅 3.x 地址 -``` - -`dubbo.application.service-discovery.migration ` 支持通过 `-D` 以及 `全局配置中心` 两种方式进行配置。 - - - -![//imgs/v3/migration/consumer-subscription.png](/imgs/v3/migration/consumer-subscription.png) - - -接下来,我们就具体看一下,如何通过双订阅模式(APPLICATION_FIRST)让升级到 3.x 的消费端迁移到应用级别的地址。在具体展开之前,先明确一条消费端的选址行为:**对于双订阅的场景,消费端虽然可同时持有 2.x 地址与 3.x 地址,但选址过程中两份地址是完全隔离的:要么用 2.x 地址,要么用 3.x 地址,不存在两份地址混合调用的情况,这个决策过程是在收到第一次地址通知后就完成了的。** - - - -下面,我们看一个`APPLICATION_FIRST`策略的具体操作过程。 - -首先,提前在全局配置中心 Nacos 配置一条配置项(所有消费端都将默认执行这个选址策略): - -![//imgs/v3/migration/nacos-migration-item.png](/imgs/v3/migration/nacos-migration-item.png) - - - -紧接着,升级消费端到 3.x 版本并启动,这时消费端读取到`APPLICATION_FIRST`配置后,执行双订阅逻辑(订阅 2.x 接口级地址与 3.x 应用级地址) - - - -至此,升级操作就完成了,剩下的就是框架内部的执行了。在调用发生前,框架在消费端会有一个“选址过程”,注意这里的选址和之前 2.x 版本是有区别的,选址过程包含了两层筛选: - -* 先进行地址列表(ClusterInvoker)筛选(接口级地址 or 应用级地址) -* 再进行实际的 provider 地址(Invoker)筛选。 - -![//imgs/v3/migration/migration-cluster-item.png](/imgs/v3/migration/migration-cluster-invoker.png) - -ClusterInvoker 筛选的依据,可以通过 MigrationAddressComparator SPI 自行定义,目前官方提供了一个简单的地址数量比对策略,即当 `应用级地址数量 == 接口级地址数量` 满足时则进行迁移。 - -> 其实 FORCE_INTERFACE、APPLICATION_FIRST、FORCE_APPLICATION 控制的都是这里的 ClusterInvoker 类型的筛选策略 - - - -### 3.1 双订阅带来的资源消耗 - -双订阅不可避免的会增加消费端的内存消耗,但由于应用级地址发现在地址总量方面的优势,这个过程通常是可接受的,我们从两个方面进行分析: - -1. 双订阅带来的地址推送数据量增长。这点我们在 ”双注册资源消耗“ 一节中做过介绍,应用级服务发现带来的注册中心数据量增长非常有限。 -2. 双订阅带来的消费端内存增长。要注意双订阅只存在于启动瞬态,在ClusterInvoker选址决策之后其中一份地址就会被完全销毁;对单个服务来说,启动阶段双订阅带来的内存增长大概能控制在原内存量的 30% ~ 40%,随后就会下降到单订阅水平,如果切到应用级地址,能实现内存 50% 的下降。 - - - -### 3.2 消费端更细粒度的控制 - -除了全局的迁移策略之外,Dubbo 在消费端提供了更细粒度的迁移策略支持。控制单位可以是某一个消费者应用,它消费的服务A、服务B可以有各自独立的迁移策略,具体是用方式是在消费端配置迁移规则: - - -```yaml -key: demo-consumer -step: APPLICATION_FIRST -applications: - - name: demo-provider - step: FORCE_APPLICATION -services: - - serviceKey: org.apache.dubbo.config.api.DemoService:1.0.0 - step: FORCE_INTERFACE -``` - -使用这种方式能做到比较精细迁移控制,但是当下及后续的改造成本会比较高,除了一些特别场景,我们不太推荐启用这种配置方式。 -[迁移指南](../service-discovery-rule/)官方推荐使用的全局的开关式的迁移策略,让消费端实例在启动阶段自行决策使用哪份可用的地址列表。 - - - -## 4 迁移状态的收敛 - -为了同时兼容 2.x 版本,升级到 3.x 版本的应用在一段时间内要么处在双注册状态,要么处在双订阅状态。 - -解决这个问题,我们还是从 Provider 视角来看,当所有的 Provider 都切换到应用级地址注册之后,也就不存在双订阅的问题了。 - -### 4.1 不同的升级策略影响很大 - -毫无疑问越早越彻底的升级,就能尽快摆脱这个局面。设想,如果可以将组织内所有的应用都升级到 3.x 版本,则版本收敛就变的非常简单:升级过程中 Provider 始终保持双注册,当所有的应用都升级到 3.x 之后,就可以调整全局默认行为,让 Provider 都变成应用级地址单注册了,这个过程并不会给 Consumer 应用带来困扰,因为它们已经是可以识别应用级地址的 3.x 版本了。 - -如果没有办法做到应用的全量升级,甚至在相当长的时间内只能升级一部分应用,则不可避免的迁移状态要持续比较长的时间。 -在这种情况下,我们追求的只能是尽量保持已升级应用的上下游实现版本及功能收敛。推动某些 Provider 的上游消费者都升级到 Dubbo3,这样就可以解除这部分 Provider 的双注册,要做到这一点,可能需要一些辅助统计工具的支持。 - -1. 要能分析出应用间的依赖关系,比如一个 Provdier 应用被哪些消费端应用消费,这可以通过 Dubbo 提供的服务元数据上报能力来实现。 -2. 要能知道每个应用当前使用的 dubbo 版本,可以通过扫描或者主动上报手段。 diff --git a/content/zh-cn/overview/mannual/java-sdk/upgrades-and-compatibility/version/_index.md b/content/zh-cn/overview/mannual/java-sdk/upgrades-and-compatibility/version/_index.md deleted file mode 100755 index 3ffbadcdb91a..000000000000 --- a/content/zh-cn/overview/mannual/java-sdk/upgrades-and-compatibility/version/_index.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -aliases: - - /zh/docs3-v2/java-sdk/version/ - - /zh-cn/docs3-v2/java-sdk/version/ - - /zh-cn/overview/mannual/java-sdk/version/ -description: 查看历史版本文档 -linkTitle: 查看历史版本文档 -title: 查看历史版本文档 -type: docs -weight: 100 ---- - -{{< blocks/section color="white" height="auto">}} -
-
-
-
-
-

- Early 3.0 Version -

-

早期 3.0 版本文档

-
-
-
-
-
-
-

- 2.7.x Version -

-

2.7.x 版本文档

-
-
-
- -
-
-
- -{{< /blocks/section >}} \ No newline at end of file diff --git a/content/zh-cn/overview/mannual/java-sdk/versions.md b/content/zh-cn/overview/mannual/java-sdk/versions.md new file mode 100644 index 000000000000..e20d7459cba5 --- /dev/null +++ b/content/zh-cn/overview/mannual/java-sdk/versions.md @@ -0,0 +1,23 @@ +--- +aliases: + - /zh/docs3-v2/golang-sdk/refer/compatible_version/ + - /zh-cn/docs3-v2/golang-sdk/refer/compatible_version/ + - /zh-cn/overview/mannual/golang-sdk/preface/refer/compatible_version/ +description: 依赖适配版本号 +title: 版本信息 +type: docs +weight: 1 +--- +我们提供了不同版本的 Dubbo Java 实现文档,您可以在下方版本列表中选择不同的版本文档,查看每个版本的维护情况、组件版本、升级注意事项等。 + +## 版本说明 + +| Dubbo 分支 | 最新版本 | JDK | Spring Boot | 组件版本 | 详细说明 | +| --- | --- | --- | --- | --- | --- | --- | --- | +| 3.3.x (当前文档) | 3.3.0 | 8, 17, 21 | [2.x、3.x](/zh-cn/overview/mannual/java-sdk/reference-manual/config/spring/spring-boot/#dubbo-spring-boot-starter) | [详情](https://github.com/apache/dubbo/blob/dubbo-3.3.0/dubbo-dependencies-bom/pom.xml#L91) | - [版本变更记录](/zh-cn/overview/mannual/java-sdk/reference-manual/upgrades-and-compatibility/version/3.2-to-3.3-compatibility-guide/)

- **生产可用(推荐,长期维护)!** 最新Triple协议升级,内置Metrics、Tracing、GraalVM支持等 | +| [3.2.x](https://dubbo-202409.staged.apache.org/zh-cn/overview/mannual/java-sdk/) | 3.2.10 | 8, 17 | [2.x、3.x](/zh-cn/overview/mannual/java-sdk/reference-manual/config/spring/spring-boot/#dubbo-spring-boot-starter) | [详情](https://github.com/apache/dubbo/blob/dubbo-3.2.10/dubbo-dependencies-bom/pom.xml#L91) | - [版本变更记录](/zh-cn/overview/mannual/java-sdk/reference-manual/upgrades-and-compatibility/version/3.1-to-3.2-compatibility-guide/)

- 生产可用(长期维护)! | +| [3.1.x](https://dubbo-202409.staged.apache.org/zh-cn/overview/mannual/java-sdk/) | 3.1.11 | 8, 17 | [2.x、3.x](/zh-cn/overview/mannual/java-sdk/reference-manual/config/spring/spring-boot/#dubbo-spring-boot-starter) | [详情](https://github.com/apache/dubbo/blob/dubbo-3.1.11/dubbo-dependencies-bom/pom.xml#L91) | - [版本变更记录](/zh-cn/overview/mannual/java-sdk/reference-manual/upgrades-and-compatibility/version/3.0-to-3.1-compatibility-guide/)

- 仅修复安全漏洞! | +| [3.0.x](https://dubbo-202409.staged.apache.org/zh-cn/docs/) | 3.0.15 | 8 | [2.x](/zh-cn/overview/mannual/java-sdk/reference-manual/config/spring/spring-boot/#dubbo-spring-boot-starter) | [详情](https://github.com/apache/dubbo/blob/dubbo-3.0.15/dubbo-dependencies-bom/pom.xml#L91) | - [版本变更记录](/zh-cn/overview/mannual/java-sdk/reference-manual/upgrades-and-compatibility/version/2.x-to-3.x-compatibility-guide/)

- 停止维护! | +| [2.7.x](https://dubbo-202409.staged.apache.org/zh-cn/docsv2.7/) | 2.7.23 | 8 | [2.x](/zh-cn/overview/mannual/java-sdk/reference-manual/config/spring/spring-boot/#dubbo-spring-boot-starter) | [详情](https://raw.githubusercontent.com/apache/dubbo/dubbo-2.7.23/dubbo-dependencies-bom/pom.xml) | - [了解如何升级到Dubbo3](/zh-cn/overview/mannual/java-sdk/reference-manual/upgrades-and-compatibility/migration/)

- 停止维护! | +| 2.6.x | 2.6.20 | 6, 7 | - | _ | - [了解如何升级到Dubbo3](/zh-cn/overview/mannual/java-sdk/reference-manual/upgrades-and-compatibility/migration/)

- 停止维护! | +| 2.5.x | 2.5.10 | 6, 7 | - | - | - [了解如何升级到Dubbo3](/zh-cn/overview/mannual/java-sdk/reference-manual/upgrades-and-compatibility/migration/)

- 停止维护! | diff --git a/content/zh-cn/overview/mannual/nodejs-sdk/_index.md b/content/zh-cn/overview/mannual/nodejs-sdk/_index.md new file mode 100755 index 000000000000..294410b450f9 --- /dev/null +++ b/content/zh-cn/overview/mannual/nodejs-sdk/_index.md @@ -0,0 +1,7 @@ +--- +description: Node.js SDK 使用手册 +linkTitle: Node.js SDK +title: Node.js SDK 手册 +type: docs +weight: 3 +--- diff --git a/content/zh-cn/overview/mannual/nodejs-sdk/quick-start.md b/content/zh-cn/overview/mannual/nodejs-sdk/quick-start.md new file mode 100644 index 000000000000..d27fefb32237 --- /dev/null +++ b/content/zh-cn/overview/mannual/nodejs-sdk/quick-start.md @@ -0,0 +1,186 @@ +--- +aliases: + - /zh/overview/quickstart/nodejs/ + - /zh-cn/overview/quickstart/nodejs/ +description: 使用 Node.js 开发后端微服务 +linkTitle: 快速开始 +title: 快速开始 +type: docs +weight: 1 +--- + +基于 Dubbo 定义的 Triple 协议,你可以轻松编写浏览器、gRPC 兼容的 RPC 服务,并让这些服务同时运行在 HTTP/1 和 HTTP/2 上。Dubbo Node.js SDK 支持使用 IDL 或编程语言特有的方式定义服务,并提供一套轻量的 API 来发布或调用这些服务。 + +本示例演示了基于 Triple 协议的 RPC 通信模式,示例使用 Protocol Buffer 定义 RPC 服务,并演示了代码生成、服务发布和服务访问等过程。 + +## 前置条件 + +因为使用 Protocol Buffer 的原因,我们首先需要安装相关的代码生成工具,这包括 `@bufbuild/protoc-gen-es`、`@bufbuild/protobuf`、`@apachedubbo/protoc-gen-apache-dubbo-es`、`@apachedubbo/dubbo`。 + +```Shell +npm install @bufbuild/protoc-gen-es @bufbuild/protobuf @apachedubbo/protoc-gen-apache-dubbo-es @apachedubbo/dubbo +``` + +## 定义服务 + +现在,使用 Protocol Buffer (IDL) 来定义一个 Dubbo 服务。 + +创建目录,并生成文件 + +```Shell +mkdir -p proto && touch proto/example.proto +``` + +写入内容 + +```Protobuf +syntax = "proto3"; + +package apache.dubbo.demo.example.v1; + +message SayRequest { + string sentence = 1; +} + +message SayResponse { + string sentence = 1; +} + +service ExampleService { + rpc Say(SayRequest) returns (SayResponse) {} +} +``` + +这个文件声明了一个叫做 `ExampleService` 的服务,为这个服务定义了 `Say` 方法以及它的请求参数 `SayRequest` 和返回值 `SayResponse`。 + +## 生成代码 + +创建 gen 目录,做为生成文件放置的目标目录 + +``` +mkdir -p gen +``` + +运行以下命令,在 gen 目录下生成代码文件 + +```Shell +PATH=$PATH:$(pwd)/node_modules/.bin \ + protoc -I proto \ + --es_out gen \ + --es_opt target=ts \ + --apache-dubbo-es_out gen \ + --apache-dubbo-es_opt target=ts \ + example.proto +``` + +运行命令后,应该可以在目标目录中看到以下生成的文件: + +```Plain Text +├── gen +│ ├── example_dubbo.ts +│ └── example_pb.ts +├── proto +│ └── example.proto +``` + +## 实现服务 + +接下来我们就需要添加业务逻辑了,实现 ExampleService ,并将其注册到 DubboRouter 中。 + +创建 dubbo.ts 文件 + +```typescript +import { DubboRouter } from "@apachedubbo/dubbo"; +import { ExampleService } from "./gen/example_dubbo"; + +export default (router: DubboRouter) => + // registers apache.dubbo.demo.example.v1 + router.service(ExampleService, { + // implements rpc Say + async say(req) { + return { + sentence: `You said: ${req.sentence}`, + }; + }, + }, { serviceGroup: 'dubbo', serviceVersion: '1.0.0' }); +``` + +## 启动 Server + +Dubbo 服务可以嵌入到普通的 Node.js 服务器、Next.js、Express 或 Fastify 中。 +在这里我们将使用 Fastify,所以让我们安装 Fastify 以及我们为 Fastify 准备的插件。 + +```Shell +npm install fastify @apachedubbo/dubbo-fastify +``` + +创建 server.ts 文件,新建一个 Server,把上一步中实现的 `ExampleService` 注册给它。 +接下来就可以直接初始化和启动 Server 了,它将在指定的端口接收请求。 + +```typescript +import { fastify } from "fastify"; +import { fastifyDubboPlugin } from "@apachedubbo/dubbo-fastify"; +import routes from "./dubbo"; + +async function main() { + const server = fastify(); + await server.register(fastifyDubboPlugin, { + routes, + }); + server.get("/", (_, reply) => { + reply.type("text/plain"); + reply.send("Hello World!"); + }); + await server.listen({ host: "localhost", port: 8080 }); + console.log("server is listening at", server.addresses()); +} + +void main(); +``` + +最后,运行代码启动服务 + +```Shell +npx tsx server.ts +``` + +## 访问服务 + +最简单方式是使用 HTTP/1.1 POST 请求访问服务,参数则作以标准 JSON 格式作为 HTTP 负载传递。如下是使用 cURL 命令的访问示例: + +```Shell +curl \ + --header 'Content-Type: application/json' \ + --header 'TRI-Service-Version: 1.0.0' \ + --header 'TRI-Service-group: dubbo' \ + --data '{"sentence": "Hello World"}' \ + http://localhost:8080/apache.dubbo.demo.example.v1.ExampleService/Say +``` + +也可以使用标准的 Dubbo client 请求服务,我们首先需要从生成代码即 dubbo-node 包中获取服务代理,为它指定 server 地址并初始化,之后就可以发起起 RPC 调用了。 + +创建 client.ts 文件。 + +```typescript +import { createPromiseClient } from "@apachedubbo/dubbo"; +import { ExampleService } from "./gen/example_dubbo"; +import { createDubboTransport } from "@apachedubbo/dubbo-node"; + +const transport = createDubboTransport({ + baseUrl: "http://localhost:8080", + httpVersion: "1.1", +}); + +async function main() { + const client = createPromiseClient(ExampleService, transport, { serviceVersion: '1.0.0', serviceGroup: 'dubbo' }); + const res = await client.say({ sentence: "Hello World" }); + console.log(res); +} +void main(); +``` + +运行客户端 + +```Shell +npx tsx client.ts +``` diff --git a/content/zh-cn/overview/mannual/rust-sdk/_index.md b/content/zh-cn/overview/mannual/rust-sdk/_index.md index 70c2ad64c8cd..cc146fb0aa73 100755 --- a/content/zh-cn/overview/mannual/rust-sdk/_index.md +++ b/content/zh-cn/overview/mannual/rust-sdk/_index.md @@ -6,5 +6,5 @@ description: Rust SDK 使用手册 linkTitle: Rust SDK title: Rust SDK 手册 type: docs -weight: 4 +weight: 5 --- diff --git a/content/zh-cn/overview/mannual/rust-sdk/quick-start.md b/content/zh-cn/overview/mannual/rust-sdk/quick-start.md index 1d0c07369454..9fa9f61dd4a6 100644 --- a/content/zh-cn/overview/mannual/rust-sdk/quick-start.md +++ b/content/zh-cn/overview/mannual/rust-sdk/quick-start.md @@ -2,6 +2,8 @@ aliases: - /zh/docs3-v2/rust-sdk/quick-start/ - /zh-cn/docs3-v2/rust-sdk/quick-start/ + - /zh/overview/quickstart/rust/ + - /zh-cn/overview/quickstart/rust/ description: 使用 Rust 快速开发 Dubbo 服务。 linkTitle: 快速开始 title: 快速开始 @@ -219,4 +221,36 @@ $ ./target/debug/greeter-server ```sh $ ./target/debug/greeter-client Response: GreeterReply { message: "hello, dubbo-rust" } -``` \ No newline at end of file +``` + +## 7 更多示例 + +{{< blocks/section color="white" height="auto">}} +
+
+
+
+
+

+ Streaming 通信模式 +

+

使用 Dubbo Rust 实现 Streaming 通信模型。

+
+
+
+
+
+
+

+ 与 Dubbo Java 互通 +

+

实现与其他 Dubbo 多语言服务的互通

+
+
+
+
+
+
+ +{{< /blocks/section >}} diff --git a/content/zh-cn/overview/mannual/rust-sdk/service-discovery.md b/content/zh-cn/overview/mannual/rust-sdk/service-discovery.md index 1171d74d3b35..d22c33572b27 100644 --- a/content/zh-cn/overview/mannual/rust-sdk/service-discovery.md +++ b/content/zh-cn/overview/mannual/rust-sdk/service-discovery.md @@ -3,10 +3,6 @@ aliases: - /zh/docs3-v2/rust-sdk/service-discovery/ - /zh-cn/docs3-v2/rust-sdk/service-discovery/ description: 服务发现 -feature: - description: | - Dubbo Rust依赖第三方注册中心组件来协调服务发现过程,支持的注册中心: Nacos、Zookeeper。 - title: 服务发现 linkTitle: 服务发现 title: 服务发现 type: docs diff --git a/content/zh-cn/overview/mannual/web-sdk/_index.md b/content/zh-cn/overview/mannual/web-sdk/_index.md new file mode 100755 index 000000000000..0c16b02ac2d5 --- /dev/null +++ b/content/zh-cn/overview/mannual/web-sdk/_index.md @@ -0,0 +1,7 @@ +--- +description: Web SDK 使用手册 +linkTitle: Web SDK +title: Web SDK 手册 +type: docs +weight: 4 +--- diff --git a/content/zh-cn/overview/mannual/web-sdk/quick-start.md b/content/zh-cn/overview/mannual/web-sdk/quick-start.md new file mode 100644 index 000000000000..b3690167fabb --- /dev/null +++ b/content/zh-cn/overview/mannual/web-sdk/quick-start.md @@ -0,0 +1,267 @@ +--- +aliases: + - /zh/docs3-v2/rust-sdk/quick-start/ + - /zh-cn/docs3-v2/rust-sdk/quick-start/ +description: 使用 dubbo-js 开发运行在浏览器页面的微服务。 +linkTitle: Web浏览器访问Dubbo服务 +title: Web 浏览器访问 Dubbo 服务 +type: docs +weight: 1 +--- + +基于 Dubbo3 定义的 Triple 协议,你可以轻松编写浏览器、gRPC 兼容的 RPC 服务,并让这些服务同时运行在 HTTP/1 和 HTTP/2 上。[Dubbo TypeScript SDK](https://github.com/apache/dubbo-js/) 支持使用 IDL 或编程语言特有的方式定义服务,并提供一套轻量的 API 来发布或调用这些服务。 + +Dubbo-js 已于 9 月份发布支持 Dubbo3 协议的首个 alpha 版本,它的发布将有机会彻底改变微服务前后端的架构与通信模式,让你能直接在浏览器页面或web服务器中访问后端 Dubbo RPC 服务。 + +![dubbo-web.png](/imgs/v3/web/web-1.png) + +# 浏览器 Web 应用示例 + +本示例演示了如何使用 dubbo-js 开发运行在浏览器上的 web 应用程序,web 页面将调用 dubbo node.js 开发的后端服务并生成页面内容。本示例演示基于 IDL 和非 IDL 两种编码模式。 + +![dubbo-web.png](/imgs/v3/web/web-2.png) + +## IDL 模式 + +### 前置条件 + +首先,我们将使用 Vite 来生成我们的前端项目模板,它内置了我们稍后需要的所有功能支持。 + +```shell +npm create vite@latest -- dubbo-web-example --template react-ts +cd dubbo-web-example +npm install +``` + +因为使用 Protocol Buffer 的原因,我们首先需要安装相关的代码生成工具,这包括 `@bufbuild/protoc-gen-es`、`@bufbuild/protobuf`、`@apachedubbo/protoc-gen-apache-dubbo-es`、`@apachedubbo/dubbo`。 + +```shell +npm install @bufbuild/protoc-gen-es @bufbuild/protobuf @apachedubbo/protoc-gen-apache-dubbo-es @apachedubbo/dubbo +``` + +### 使用 Proto 定义服务 + +现在,使用 Protocol Buffer (IDL) 来定义一个 Dubbo 服务。 + +src 下创建 util/proto 目录,并生成文件 + +```shell +mkdir -p src/util/proto && touch src/util/proto/example.proto +``` + +写入内容 + +```protobuf +syntax = "proto3"; + +package apache.dubbo.demo.example.v1; + +message SayRequest { + string sentence = 1; +} + +message SayResponse { + string sentence = 1; +} + +service ExampleService { + rpc Say(SayRequest) returns (SayResponse) {} +} +``` + +这个文件声明了一个叫做 `ExampleService` 的服务,为这个服务定义了 `Say` 方法以及它的请求参数 `SayRequest` 和返回值 `SayResponse`。 + +### 生成代码 + +创建 gen 目录,作为生成文件放置的目标目录 + +```shell +mkdir -p src/util/gen +``` + +运行以下命令,利用 `protoc-gen-es`、`protoc-gen-apache-dubbo-es` 等插件在 gen 目录下生成代码文件 + +```shell +PATH=$PATH:$(pwd)/node_modules/.bin \ + protoc -I src/util/proto \ + --es_out src/util/gen \ + --es_opt target=ts \ + --apache-dubbo-es_out src/util/gen \ + --apache-dubbo-es_opt target=ts \ + example.proto +``` + +运行命令后,应该可以在目标目录中看到以下生成的文件: + +``` +├── src +│ ├── util +│ │ ├── gen +│ │ │ ├── example_dubbo.ts +│ │ │ └── example_pb.ts +│ │ └── proto +│ │ └── example.proto +``` + +### 创建 App + +需要先下载 `@apachedubbo/dubbo-web` + +```shell +npm install @apachedubbo/dubbo-web +``` + +现在我们可以从包中导入服务并设置一个客户端。在 App.tsx 中添加以下内容: + +```typescript +import { useState } from "react"; +import "./App.css"; + +import { createPromiseClient } from "@apachedubbo/dubbo"; +import { createDubboTransport } from "@apachedubbo/dubbo-web"; + +// Import service definition that you want to connect to. +import { ExampleService } from "./util/gen/example_dubbo"; + +// The transport defines what type of endpoint we're hitting. +// In our example we'll be communicating with a Dubbo endpoint. +const transport = createDubboTransport({ + baseUrl: "http://localhost:8080", +}); + +// Here we make the client itself, combining the service +// definition with the transport. +const client = createPromiseClient(ExampleService, transport, { serviceGroup: 'dubbo', serviceVersion: '1.0.0' }); + +function App() { + const [inputValue, setInputValue] = useState(""); + const [messages, setMessages] = useState< + { + fromMe: boolean; + message: string; + }[] + >([]); + return ( + <> +
    + {messages.map((msg, index) => ( +
  1. {`${msg.fromMe ? "ME:" : "Dubbo Server:"} ${msg.message}`}
  2. + ))} +
+
{ + e.preventDefault(); + // Clear inputValue since the user has submitted. + setInputValue(""); + // Store the inputValue in the chain of messages and + // mark this message as coming from "me" + setMessages((prev) => [ + ...prev, + { + fromMe: true, + message: inputValue, + }, + ]); + const response = await client.say({ + sentence: inputValue, + }); + setMessages((prev) => [ + ...prev, + { + fromMe: false, + message: response.sentence, + }, + ]); + }} + > + setInputValue(e.target.value)} /> + +
+ + ); +} + +export default App; +``` + +执行以下命令,即可得到样例页面 + +```shell +npm run dev +``` + +### 启动 Server + +接下来我们需要启动 Server,可以使用 Java、Go、Node.js 等 Dubbo 支持的任一语言开发 Server。这里我们采用 Dubbo 服务嵌入的 Node.js 服务器,具体可参考 [Node.js 开发 Dubbo 后端服务](https://github.com/apache/dubbo-js/tree/dubbo3/example/dubbo-node-example) 中的操作步骤。 + +不过需要注意,我们额外需要修改 Node.js 示例:引入 @fastify/cors 来解决前端请求的跨域问题 + +```shell +npm install @fastify/cors +``` + +需要在 server.ts 文件下修改 + +```typescript +... +import cors from "@fastify/cors"; + +... +async function main() { + const server = fastify(); + ... + await server.register(cors, { + origin: true, + }); + ... + await server.listen({ host: "localhost", port: 8080 }); + ... +} + +void main(); +``` + +最后,运行代码启动服务 + +```shell +npx tsx server.ts +``` + +## 无 IDL 模式 + +在接下来的版本中,我们将继续提供无 IDL 模式的通信支持,这样就可以更方便的访问无 IDL 的后端服务。在这里,我们先快速的看一下无 IDL 模式的使用方式。 + +同样需要先安装 `@apachedubbo/dubbo`、`@apachedubbo/dubbo-web` + +```shell +npm install @apachedubbo/dubbo @apachedubbo/dubbo-web +``` + +现在就可以一个启动一个客户端,并发起调用了。App.tsx 中的代码与 IDL 模式基本一致,区别点在于以下内容: + +```typescript +// ... +// set backend server to connect +const transport = createDubboTransport({ + baseUrl: "http://localhost:8080", +}); +// init client +const client = createPromiseClient(transport); + +function App() { + // ... + // call remote Dubbo service + const response = await client.call( + "apache.dubbo.demo.example.v1.ExampleService", + "say", + { + sentence: inputValue, + }); +} +``` + +执行以下命令,即可得到样例页面 + +```shell +npm run dev +``` diff --git a/content/zh-cn/overview/quickstart/_index.md b/content/zh-cn/overview/quickstart/_index.md deleted file mode 100755 index de26b9216f95..000000000000 --- a/content/zh-cn/overview/quickstart/_index.md +++ /dev/null @@ -1,69 +0,0 @@ ---- -aliases: - - /zh/overview/quickstart/ -description: Dubbo 入门 -linkTitle: 入门 -no_list: true -title: Dubbo 入门 -type: docs -weight: 2 ---- - - - -{{< blocks/section color="white" height="auto">}} -
-
-
-
-
-

- Java 微服务开发入门 -

-

通过以下教程快速上手 Dubbo Java 开发:

-

1 - 快速部署

-

2 - 基于 dubbo-spring-boot-starter 开发

-
-
-
- -
-
-
-

- Rust 微服务开发入门 -

-

快速开始 Rust 微服务开发。 -

-
-
-
-
-
-
-

- Nodejs 微服务开发入门 -

-

快速开始 Node.js 微服务开发。 -

-
-
-
-
-
-
- -{{< /blocks/section >}} diff --git a/content/zh-cn/overview/quickstart/go/_index.md b/content/zh-cn/overview/quickstart/go/_index.md deleted file mode 100755 index 1bf518a36b9f..000000000000 --- a/content/zh-cn/overview/quickstart/go/_index.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -aliases: - - /zh/overview/quickstart/go/ -description: Go 微服务开发入门 -linkTitle: Go -no_list: true -title: Go 微服务开发入门 -type: docs -weight: 2 ---- - - - -{{< blocks/section color="white" height="auto">}} -
-
-
-
-
-

- 安装 Dubbo-go 开发环境 -

-

了解和安装 dubbogo-cli 工具

-
-
-
-
-
-
-

- 完成一次 RPC 调用 -

-

快速上手启动一个基于 Dubbo-go 的微服务应用

-
-
-
-
-
-
-

- 完成一次自己定义接口的 RPC 调用 -

-

从零上手开发一个基于 Dubbo-go 的微服务应用

-
-
-
-
-
-
- -{{< /blocks/section >}} diff --git a/content/zh-cn/overview/quickstart/go/install.md b/content/zh-cn/overview/quickstart/go/install.md deleted file mode 100644 index 20f02cf505f4..000000000000 --- a/content/zh-cn/overview/quickstart/go/install.md +++ /dev/null @@ -1,49 +0,0 @@ ---- -aliases: - - /zh/overview/quickstart/go/install/ -description: 1 - 安装 Dubbo-go 开发环境 -title: 安装 Dubbo-go 开发环境 -type: docs -weight: 1 ---- - - -### 1. 安装Go语言环境 - -> go version >= go 1.15。建议使用最新版 go 1.22 - -[【Go 语言官网下载地址】](https://golang.google.cn/) - -安装成功后将 `$GOPATH/bin` 加入环境变量 - -### 2. 安装序列化工具protoc - -[【protoc 下载地址】](https://github.com/protocolbuffers/protobuf/releases) - -### 3. 安装 dubbogo-cli 以及相关插件 - -执行以下指令安装dubbogo-cli 至 `$GOPATH/bin` - -```bash -$ export GOPROXY="https://goproxy.cn" -$ go install github.com/dubbogo/dubbogo-cli@latest -$ dubbogo-cli -hello -``` - -安装依赖的工具插件 - -```bash -$ dubbogo-cli install all -``` - -确保上述安装的工具位于在系统环境变量内 - -```bash -$ protoc --version -libprotoc 3.14.0 -$ protoc-gen-go --version -protoc-gen-go v1.26.0 -$ protoc-gen-go-triple --version -protoc-gen-go-triple 1.0.8 -``` diff --git a/content/zh-cn/overview/quickstart/go/quickstart_triple.md b/content/zh-cn/overview/quickstart/go/quickstart_triple.md deleted file mode 100644 index fc108256ec95..000000000000 --- a/content/zh-cn/overview/quickstart/go/quickstart_triple.md +++ /dev/null @@ -1,124 +0,0 @@ ---- -aliases: - - /zh/overview/quickstart/go/quickstart_triple/ -description: 2 - 完成一次 RPC 调用 -title: 完成一次 RPC 调用 -type: docs -weight: 2 ---- - -## 1. 生成 Demo 项目 - -使用安装好的 dubbogo-cli 工具,创建 demo 工程。 - -```bash -$ mkdir quickstart -$ cd quickstart -$ dubbogo-cli newDemo . -$ tree . -. -├── api -│   ├── samples_api.pb.go -│   ├── samples_api.proto -│   └── samples_api_triple.pb.go -├── go-client -│   ├── cmd -│   │   └── client.go -│   └── conf -│   └── dubbogo.yaml -├── go-server -│   ├── cmd -│   │   └── server.go -│   └── conf -│   └── dubbogo.yaml -└── go.mod -``` - -可看到生成的项目中包含一个 client 项目和一个 server 项目,以及相关的配置文件。 - -### 1.1 查看接口描述文件 sample_api.proto - -```protobuf -syntax = "proto3"; -package api; - -option go_package = "./;api"; - -// The greeting service definition. -service Greeter { - // Sends a greeting - rpc SayHello (HelloRequest) returns (User) {} - // Sends a greeting via stream - rpc SayHelloStream (stream HelloRequest) returns (stream User) {} -} - -// The request message containing the user's name. -message HelloRequest { - string name = 1; -} - -// The response message containing the greetings -message User { - string name = 1; - string id = 2; - int32 age = 3; -} -``` - -demo项目中,默认生成了一个接口描述文件,接口服务名为 api.Greeter, 包含两个 RPC 方法,入参为 HelloRequest,返回值为 User,两个方法分别为普通 RPC 方法和 Streaming 类型 RPC 方法。 - -### 1.2 (*可选) 使用安装好的编译工具编译 pb 接口 - -```bash -$ cd api -$ protoc --go_out=. --go-triple_out=. ./samples_api.proto -``` - -参数意义:`--go_out=.` 使用上述安装的 `protoc-gen-go` 插件,生成文件到当前目录,`--go-triple_out=.` 使用上述安装的 `protoc-gen-go-triple` 插件,生成文件到当前目录。 - -执行该指令后,会生成两个文件,分别是 sample_api.pb (包含 proto 结构) 和 sample_api_triple.pb.go (包含 triple 协议接口)。 - -在 demo 工程中,预先生成好了这两个文件,修改 .proto 文件后重新执行命令生成,即可覆盖。 - -## 2. 开启一次RPC调用 - -项目根目录执行 - -```bash -$ go mod tidy -``` - -拉取到最新的框架依赖(其中 Go SDK 版本和 module 名以个人机器配置为准): - -```go -module helloworld - -go 1.21.1 - -require ( - dubbo.apache.org/dubbo-go/v3 v3.1.0 - github.com/dubbogo/gost v1.14.0 - github.com/dubbogo/grpc-go v1.42.10 - github.com/dubbogo/triple v1.2.2-rc3 - google.golang.org/protobuf v1.31.0 -) - -require ( - ... -) - -``` - -{{% alert title="输出结果" color="info" %}} -先后启动服务端和客户端: 开启两个终端,在 `go-server/cmd` 和 `go-client/cmd` 文件夹下分别执行 `go run .` , 可在客户端看到输出: - -```shell -client response result: name:"Hello laurence" id:"12345" age:21 -``` - -调用成功。 -{{% /alert %}} - -{{% alert title="更多" color="primary" %}} -细心的读者可以发现,以上例子编写的的服务端可以接受来自客户端的普通 RPC、流式 RPC 调用请求。目前只编写了普通调用的 Client,读者可以根据 samples 库中的例子来尝试编写流式客户端和服务端应用。 -{{% /alert %}} diff --git a/content/zh-cn/overview/quickstart/go/quickstart_triple_with_customize.md b/content/zh-cn/overview/quickstart/go/quickstart_triple_with_customize.md deleted file mode 100644 index e0dea332f874..000000000000 --- a/content/zh-cn/overview/quickstart/go/quickstart_triple_with_customize.md +++ /dev/null @@ -1,212 +0,0 @@ ---- -aliases: - - /zh/overview/quickstart/go/quickstart_triple_with_customize/ -description: 3 - 完成一次 RPC 调用自己定义接口的版本 -title: 完成一次自己定义接口的 RPC 调用 -type: docs -weight: 3 ---- - - - -## 1.概述 -我们本章来实现一个简单的小需求,实现一个分布式ID生成服务,通过该服务可以获取分布式ID -(假设的分布式ID,我们不探讨ID的生成方案和算法,这里直接使用uuid代替,只为演示自定义服务的创建) - -## 2. 服务端实现 -首先使用 dubbogo-cli 创建 IDC 服务 -```bash -dubbogo-cli newApp IDC -cd IDC -tree . - -. -├── Makefile -├── api -│   ├── api.pb.go -│   ├── api.proto -│   └── api_triple.pb.go -├── build -│   └── Dockerfile -├── chart -│   ├── app -│   │   ├── Chart.yaml -│   │   ├── templates -│   │   │   ├── _helpers.tpl -│   │   │   ├── deployment.yaml -│   │   │   ├── service.yaml -│   │   │   └── serviceaccount.yaml -│   │   └── values.yaml -│   └── nacos_env -│   ├── Chart.yaml -│   ├── templates -│   │   ├── _helpers.tpl -│   │   ├── deployment.yaml -│   │   └── service.yaml -│   └── values.yaml -├── cmd -│   └── app.go -├── conf -│   └── dubbogo.yaml -├── go.mod -├── go.sum -└── pkg - └── service - └── service.go - -``` - -我们编辑proto定义我们的接口 - -```protobuf -syntax = "proto3"; -package api; - -option go_package = "./;api"; - -service Generator { - rpc GetID (GenReq) returns (GenResp) {} -} - -message GenReq { - string appId = 1; -} - -message GenResp { - string id = 1; -} -``` - -生成代码 - -```bash -$ cd api -$ protoc --go_out=. --go-triple_out=. ./api.proto -``` - -我们来调整service -目录:pkg/service/service.go -修改后的代码如下 - -```go -type GeneratorServerImpl struct { - api.UnimplementedGeneratorServer -} - -func (s *GeneratorServerImpl) GetID(ctx context.Context, in *api.GenReq) (*api.GenResp, error) { - logger.Infof("Dubbo-go GeneratorProvider AppId = %s\n", in.AppId) - uuid, err := uuid.NewV4() - if err != nil { - logger.Infof("Dubbo-go GeneratorProvider get id err = %v\n", err) - return nil, err - } - return &api.GenResp{Id: uuid.String()}, nil -} - -func init() { - config.SetProviderService(&GeneratorServerImpl{}) -} -``` -同时,我们调整conf/dubbogo.yaml中的provider部分, -```yaml -dubbo: - registries: - nacos: - protocol: nacos - address: 127.0.0.1:8848 - protocols: - triple: - name: tri - port: 20000 - provider: - services: - GeneratorServerImpl: - interface: "" # read from stub -``` -我们需要拉起一个依赖的注册中心,nacos,如果你有现成的,本步骤可以忽略,我们使用docker来快速启动一个nacos, - -```bash -git clone https://github.com/nacos-group/nacos-docker.git -cd nacos-docker -docker-compose -f example/standalone-derby.yaml up -``` - -最后,我们启动服务端。 -```go -export DUBBO_GO_CONFIG_PATH=conf/dubbogo.yaml -go run cmd/app.go -``` -打开nacos的控制台,可以看到服务已经注册 -![img](/imgs/docs3-v2/golang-sdk/quickstart/nacos.jpg) - - -## 2. 客户端使用 -首先,我们可以共享我们的服务端的api给客户端,并生成相关的代码(这里可以根据实际项目需要,共享共享proto,每个consumer自行生成代码,或统一生成sdk后给依赖的服务引入) -客户端目录如下: -```bash -. -├── api -│   ├── api.pb.go -│   ├── api.proto -│   └── api_triple.pb.go -├── cmd -│   └── client.go -├── conf -│   └── dubbogo.yml -├── go.mod -├── go.sum - -``` -api目录同服务端的api目录 -client.go 代码如下 -```go - -var grpcGeneratorImpl = new(api.GeneratorClientImpl) - -func main() { - config.SetConsumerService(grpcGeneratorImpl) - if err := config.Load(); err != nil { - panic(err) - } - - logger.Info("start to test dubbo") - req := &api.GenReq{ - AppId: "laurence", - } - reply, err := grpcGeneratorImpl.GetID(context.Background(), req) - if err != nil { - logger.Error(err) - } - logger.Infof("get id result: %v\n", reply.Id) -} - -``` - -dubbogo.yml 如下 -```yaml -dubbo: - registries: - nacos: - protocol: nacos - address: 127.0.0.1:8848 - consumer: - references: - GeneratorClientImpl: - protocol: tri - interface: "" -``` - -运行client,获取id,如下: - -```bash -export DUBBO_GO_CONFIG_PATH=conf/dubbogo.yml -go run cmd/client.go -…… -…… -2022-12-30T20:59:19.971+0800 INFO cmd/client.go:44 start to test dubbo -2022-12-30T20:59:19.982+0800 INFO cmd/client.go:52 get id result: aafd9c73-4014-4d67-a67f-5d107105647b - -``` -## 3. 更多 - -可以发现注册中心我们是使用nacos,当然,我们也可以使用其他的注册中心,更多的使用方式,可以参考[注册中心](/zh-cn/overview/mannual/golang-sdk/tutorial/develop/registry/) diff --git a/content/zh-cn/overview/quickstart/java/_index.md b/content/zh-cn/overview/quickstart/java/_index.md deleted file mode 100755 index 64e5814c6646..000000000000 --- a/content/zh-cn/overview/quickstart/java/_index.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -aliases: - - /zh/overview/quickstart/java/ -description: Java 微服务开发入门 -linkTitle: Java -no_list: true -title: Java 微服务开发入门 -type: docs -weight: 1 ---- - - - -{{< blocks/section color="white" height="auto">}} -
-
-
-
-
-

- 快速部署 -

-

零基础快速部署一个微服务应用

-
-
-
-
-
-
-

- Dubbo x Spring Boot 开发 -

-

使用 dubbo-spring-boot-starter 开发微服务应用

-
-
-
-
-
-
- -{{< /blocks/section >}} diff --git a/content/zh-cn/overview/quickstart/java/brief.md b/content/zh-cn/overview/quickstart/java/brief.md deleted file mode 100644 index bf0098941995..000000000000 --- a/content/zh-cn/overview/quickstart/java/brief.md +++ /dev/null @@ -1,313 +0,0 @@ ---- -aliases: - - /zh/overview/quickstart/java/brief/ -description: 本文将基于 Dubbo Samples 示例演示如何快速搭建并部署一个微服务应用。 -linkTitle: 快速部署一个微服务应用 -title: 1 - 零基础快速部署一个微服务应用 -type: docs -weight: 1 ---- - -## 背景 - -![arch-service-discovery](/imgs/architecture.png) - -Dubbo 作为一款微服务框架,最重要的是向用户提供跨进程的 RPC 远程调用能力。如上图所示,Dubbo 的服务消费者(Consumer)通过一系列的工作将请求发送给服务提供者(Provider)。 - -为了实现这样一个目标,Dubbo 引入了注册中心(Registry)组件,通过注册中心,服务消费者可以感知到服务提供者的连接方式,从而将请求发送给正确的服务提供者。 - -## 目标 - -了解微服务调用的方式以及 Dubbo 的能力 - -## 难度 - -低 - -## 环境要求 - -- 系统:Windows、Linux、MacOS - -- JDK 8 及以上(推荐使用 JDK17) - -- Git - -- Docker (可选) - -## 动手实践 - -本章将通过几个简单的命令,一步一步教你如何部署并运行一个最简单的 Dubbo 用例。 - -### 1. 获取测试工程 - -在开始整个教程之前,我们需要先获取测试工程的代码。Dubbo 的所有测试用例代码都存储在 [apache/dubbo-samples](https://github.com/apache/dubbo-samples) 这个仓库中,以下这个命令可以帮你获取 Samples 仓库的所有代码。 - -```bash -git clone --depth=1 --branch master git@github.com:apache/dubbo-samples.git -``` - -### 2. 认识 Dubbo Samples 项目结构 - -在将 [apache/dubbo-samples](https://github.com/apache/dubbo-samples) 这个仓库 clone 到本地以后,本小节将就仓库的具体组织方式做说明。 - -``` -. -├── codestyle // 开发使用的 style 配置文件 - -├── 1-basic // 基础的入门用例 -├── 2-advanced // 高级用法 -├── 3-extensions // 扩展使用示例 -├── 4-governance // 服务治理用例 -├── 10-task // Dubbo 学习系列示例 - -├── 99-integration // 集成测试使用 -├── test // 集成测试使用 -└── tools // 三方组件快速启动工具 -``` - -如上表所示,[apache/dubbo-samples](https://github.com/apache/dubbo-samples) 主要由三个部分组成:代码风格文件、测试代码、集成测试。 - -1. 代码风格文件是开发 Dubbo 代码的时候可以使用,其中包括了 IntelliJ IDEA 的配置文件。 - -2. 测试代码即本教材所需要的核心内容。目前包括了 5 个部分的内容:面向初学者的 basic 入门用例、面向开发人员的 advanced 高级用法、面向中间件维护者的 extensions Dubbo 周边扩展使用示例、面向生产的 governance 服务治理用例以及 Dubbo 学习系列。本文将基于 basic 入门用例中最简单的 Dubbo API 使用方式进行讲解。 - -3. 集成测试是 Dubbo 的质量保证体系中重要的一环,Dubbo 的每个版本都会对所有的 samples 进行回归验证,保证 Dubbo 的所有变更都不会影响 samples 的使用。 - -### 3. 启动一个简易的注册中心 - -从这一小节开始,将正式通过三个命令部署一个微服务应用。 - -从 [背景](#背景) 一节中可知,运行起 Dubbo 应用的一个大前提是部署一个注册中心,为了让本教程更易于上手,我们提供了一个基于 Apache Zookeeper 注册中心的简易启动器,如果您需要在生产环境部署注册中心,请参考[生产环境初始化](/)一文部署高可用的注册中心。 - -```bash -Windows: -./mvnw.cmd clean compile exec:java -pl tools/embedded-zookeeper - -Linux / MacOS: -./mvnw clean compile exec:java -pl tools/embedded-zookeeper - -注:需要开一个独立的 terminal 运行,命令将会保持一直执行的状态。 - -Docker: -docker run --name some-zookeeper -p 2181:2181 --restart always -d zookeeper -``` - -在执行完上述命令以后,等待一会出现如下图所示的日志即代表注册中心启动完毕,可以继续执行后续任务。 - -![registry](/imgs/docs3-v2/java-sdk/quickstart/2023-01-19-15-55-23-image.png) - -### 4. 启动服务提供者 - -在启动了注册中心之后,下一步是启动一个对外提供服务的服务提供者。在 dubbo-samples 中也提供了对应的示例,可以通过以下命令快速拉起。 - -```bash -Windows: -./mvnw.cmd clean compile exec:java -pl 1-basic/dubbo-samples-api "-Dexec.mainClass=org.apache.dubbo.samples.provider.Application" - -Linux / MacOS: -./mvnw clean compile exec:java -pl 1-basic/dubbo-samples-api -Dexec.mainClass="org.apache.dubbo.samples.provider.Application" - -注:需要开一个独立的 terminal 运行,命令将会保持一直执行的状态。 -``` - -在执行完上述命令以后,等待一会出现如下图所示的日志(`DubboBootstrap awaiting`)即代表服务提供者启动完毕,标志着该服务提供者可以对外提供服务了。 - -![provider](/imgs/docs3-v2/java-sdk/quickstart/2023-01-19-15-56-09-image.png) - -```log -[19/01/23 03:55:49:049 CST] org.apache.dubbo.samples.provider.Application.main() INFO bootstrap.DubboBootstrap: [DUBBO] DubboBootstrap awaiting ..., dubbo version: 3.2.0-beta.3, current host: 169.254.44.42 -``` - -### 5. 启动服务消费者 - -最后一步是启动一个服务消费者来调用服务提供者,也即是 RPC 调用的核心,为服务消费者提供调用服务提供者的桥梁。 - -```bash -Windows: -./mvnw.cmd clean compile exec:java -pl 1-basic/dubbo-samples-api "-Dexec.mainClass=org.apache.dubbo.samples.client.Application" - -Linux / MacOS: -./mvnw clean compile exec:java -pl 1-basic/dubbo-samples-api -Dexec.mainClass="org.apache.dubbo.samples.client.Application" -``` - -在执行完上述命令以后,等待一会出现如下图所示的日志(`hi, dubbo`),打印出的数据就是服务提供者处理之后返回的,标志着一次服务调用的成功。 - -![consumer](/imgs/docs3-v2/java-sdk/quickstart/2023-01-19-16-30-14-image.png) - -```log -Receive result ======> hi, dubbo -``` - -## 延伸阅读 - -### 1. 消费端是怎么找到服务端的? - -在本用例中的步骤 3 启动了一个 Zookeeper 的注册中心,服务提供者会向注册中心中写入自己的地址,供服务消费者获取。 - -Dubbo 会在 Zookeeper 的 `/dubbo/interfaceName` 和 `/services/appName` 下写入服务提供者的连接信息。 - -如下所示是 Zookeeper 上的数据示例: - -``` -[zk: localhost:2181(CONNECTED) 5] ls /dubbo/org.apache.dubbo.samples.api.GreetingsService/providers -[dubbo%3A%2F%2F30.221.146.35%3A20880%2Forg.apache.dubbo.samples.api.GreetingsService%3Fanyhost%3Dtrue%26application%3Dfirst-dubbo-provider%26background%3Dfalse%26deprecated%3Dfalse%26dubbo%3D2.0.2%26dynamic%3Dtrue%26environment%3Dproduct%26generic%3Dfalse%26interface%3Dorg.apache.dubbo.samples.api.GreetingsService%26ipv6%3Dfd00%3A1%3A5%3A5200%3A3218%3A774a%3A4f67%3A2341%26methods%3DsayHi%26pid%3D85639%26release%3D3.1.4%26service-name-mapping%3Dtrue%26side%3Dprovider%26timestamp%3D1674960780647] - -[zk: localhost:2181(CONNECTED) 2] ls /services/first-dubbo-provider -[30.221.146.35:20880] -[zk: localhost:2181(CONNECTED) 3] get /services/first-dubbo-provider/30.221.146.35:20880 -{"name":"first-dubbo-provider","id":"30.221.146.35:20880","address":"30.221.146.35","port":20880,"sslPort":null,"payload":{"@class":"org.apache.dubbo.registry.zookeeper.ZookeeperInstance","id":"30.221.146.35:20880","name":"first-dubbo-provider","metadata":{"dubbo.endpoints":"[{\"port\":20880,\"protocol\":\"dubbo\"}]","dubbo.metadata-service.url-params":"{\"connections\":\"1\",\"version\":\"1.0.0\",\"dubbo\":\"2.0.2\",\"release\":\"3.1.4\",\"side\":\"provider\",\"ipv6\":\"fd00:1:5:5200:3218:774a:4f67:2341\",\"port\":\"20880\",\"protocol\":\"dubbo\"}","dubbo.metadata.revision":"871fbc9cb2730caea9b0d858852d5ede","dubbo.metadata.storage-type":"local","ipv6":"fd00:1:5:5200:3218:774a:4f67:2341","timestamp":"1674960780647"}},"registrationTimeUTC":1674960781893,"serviceType":"DYNAMIC","uriSpec":null} -``` - -更多关于 Dubbo 服务发现模型的细节,可以参考[服务发现](/zh-cn/overview/mannual/java-sdk/concepts-and-architecture/service-discovery/)一文。 - -### 2. 消费端是如何发起请求的? - -在 Dubbo 的调用模型中,起到连接服务消费者和服务提供者的桥梁是接口。 - -服务提供者通过对指定接口进行实现,服务消费者通过 Dubbo 去订阅这个接口。服务消费者调用接口的过程中 Dubbo 会将请求封装成网络请求,然后发送到服务提供者进行实际的调用。 - -在本用例中,定义了一个 `GreetingsService` 的接口,这个接口有一个名为 `sayHi` 的方法。 - -```java -// 1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/api/GreetingsService.java - -package org.apache.dubbo.samples.api; - -public interface GreetingsService { - - String sayHi(String name); - -} -``` - -服务消费者通过 Dubbo 的 API 可以获取这个 `GreetingsService` 接口的代理,然后就可以按照普通的接口调用方式进行调用。**得益于 Dubbo 的动态代理机制,这一切都像本地调用一样。** - -```java -// 1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/client/Application.java - -// 获取订阅到的 Stub -GreetingsService service = reference.get(); -// 像普通的 java 接口一样调用 -String message = service.sayHi("dubbo"); -``` - -### 3. 服务端可以部署多个吗? - -可以,本小节将演示如何启动一个服务端**集群**。 - -1)启动一个注册中心,可以参考动手实践中第 3 小节的[教程](#3-启动一个简易的注册中心) - -2)修改服务提供者返回的数据,让第一个启动的服务提供者返回 `hi, dubbo. I am provider 1.` - -修改 `1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/provider/GreetingsServiceImpl.java` 文件的第 25 行如下所示。 - -```java -// 1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/provider/GreetingsServiceImpl.java - -package org.apache.dubbo.samples.provider; - -import org.apache.dubbo.samples.api.GreetingsService; - -public class GreetingsServiceImpl implements GreetingsService { - @Override - public String sayHi(String name) { - return "hi, " + name + ". I am provider 1."; - } -} -``` - -3)启动第一个服务提供者,可以参考动手实践中第 4 小节的[教程](#4-启动服务提供者) - -4)修改服务提供者返回的数据,让第二个启动的服务提供者返回 `hi, dubbo. I am provider 2.` - -修改 `1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/provider/GreetingsServiceImpl.java` 文件的第 25 行如下所示。 - -```java -// 1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/provider/GreetingsServiceImpl.java - -package org.apache.dubbo.samples.provider; - -import org.apache.dubbo.samples.api.GreetingsService; - -public class GreetingsServiceImpl implements GreetingsService { - @Override - public String sayHi(String name) { - return "hi, " + name + ". I am provider 2."; - } -} -``` - -4)启动第二个服务提供者,可以参考动手实践中第 4 小节的[教程](#4-启动服务提供者) - -5)启动服务消费者,可以参考动手实践中第 5 小节的[教程](#5-启动服务消费者)。多次启动消费者可以看到返回的结果是不一样的。 - -在 dubbo-samples 中也提供了一个会定时发起调用的消费端应用`org.apache.dubbo.samples.client.AlwaysApplication`,可以通过以下命令启动。 - -```bash -Windows: -./mvnw.cmd clean compile exec:java -pl 1-basic/dubbo-samples-api "-Dexec.mainClass=org.apache.dubbo.samples.client.AlwaysApplication" - -Linux / MacOS: -./mvnw clean compile exec:java -pl 1-basic/dubbo-samples-api -Dexec.mainClass="org.apache.dubbo.samples.client.AlwaysApplication" -``` - -启动后可以看到类似以下的日志,消费端会随机调用到不同的服务提供者,返回的结果也是远端的服务提供者觉得其结果。 - -``` -Sun Jan 29 11:23:37 CST 2023 Receive result ======> hi, dubbo. I am provider 1. -Sun Jan 29 11:23:38 CST 2023 Receive result ======> hi, dubbo. I am provider 2. -Sun Jan 29 11:23:39 CST 2023 Receive result ======> hi, dubbo. I am provider 2. -Sun Jan 29 11:23:40 CST 2023 Receive result ======> hi, dubbo. I am provider 1. -Sun Jan 29 11:23:41 CST 2023 Receive result ======> hi, dubbo. I am provider 1. -``` - -### 4. 这个用例复杂吗? - -不,Dubbo 只需要简单的配置就可以实现稳定、高效的远程调用。 - -以下是一个服务提供者的简单示例,通过定义若干个配置就可以启动。 - -```java -// 1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/provider/Application.java - -// 定义所有的服务 -ServiceConfig service = new ServiceConfig<>(); -service.setInterface(GreetingsService.class); -service.setRef(new GreetingsServiceImpl()); - -// 启动 Dubbo -DubboBootstrap.getInstance() - .application("first-dubbo-provider") - .registry(new RegistryConfig(ZOOKEEPER_ADDRESS)) - .protocol(new ProtocolConfig("dubbo", -1)) - .service(service) - .start(); -``` - -以下是一个服务消费者的简单示例,通过定义若干个配置启动后就可以获取到对应的代理对象,之后用户完全不需要感知这个对象背后的复杂实现,**一切只需要和本地调用一样就行了**。 - -```java -// 1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/client/Application.java - -// 定义所有的订阅 -ReferenceConfig reference = new ReferenceConfig<>(); -reference.setInterface(GreetingsService.class); - -// 启动 Dubbo -DubboBootstrap.getInstance() - .application("first-dubbo-consumer") - .registry(new RegistryConfig(ZOOKEEPER_ADDRESS)) - .reference(reference) - .start(); - -// 获取订阅到的 Stub -GreetingsService service = reference.get(); -// 像普通的 java 接口一样调用 -String message = service.sayHi("dubbo"); -``` - -## 更多 - -本用例介绍了一个 RPC 远程调用的基础流程,通过启动注册中心、服务提供者、服务消费者三个节点来模拟一个微服务的部署架构。 - -下一个教程中,将就服务提供者和服务消费者分别都做了什么配置进行讲解,[从零告诉你如何搭建一个微服务应用](../api/)。 diff --git a/content/zh-cn/overview/quickstart/java/spring-boot.md b/content/zh-cn/overview/quickstart/java/spring-boot.md deleted file mode 100644 index 03aeb18796ce..000000000000 --- a/content/zh-cn/overview/quickstart/java/spring-boot.md +++ /dev/null @@ -1,571 +0,0 @@ ---- -aliases: - - /zh/overview/quickstart/java/spring-boot/ -description: 本文将基于 Dubbo Samples 示例演示如何通过 Dubbo x Spring Boot 快速开发微服务应用。 -linkTitle: Dubbo Spring Boot Starter 开发微服务应用 -title: 2 - Dubbo Spring Boot Starter 开发微服务应用 -type: docs -weight: 3 ---- - - - -## 目标 - -从零上手开发基于 Dubbo x Spring Boot 的微服务开发,了解 Dubbo x Spring Boot 配置方式。 - -## 难度 - -低 - -## 环境要求 - -- 系统:Windows、Linux、MacOS - -- JDK 8 及以上(推荐使用 JDK17) - -- Git - -- IntelliJ IDEA(可选) - -- Docker (可选) - -## 项目介绍 - -在本任务中,将分为 3 个子模块进行独立开发,模拟生产环境下的部署架构。 - -``` -. // apache/dubbo-samples/1-basic/dubbo-samples-spring-boot -├── dubbo-samples-spring-boot-interface // 共享 API 模块 -├── dubbo-samples-spring-boot-consumer // 消费端模块 -└── dubbo-samples-spring-boot-provider // 服务端模块 -``` - -如上所示,共有 3 个模块,其中 `interface` 模块被 `consumer` 和 `provider` 两个模块共同依赖,存储 RPC 通信使用的 API 接口。 - -``` -. // apache/dubbo-samples/1-basic/dubbo-samples-spring-boot -├── dubbo-samples-spring-boot-interface // 共享 API 模块 -│   ├── pom.xml -│   └── src -│   └── main -│   └── java -│   └── org -│   └── apache -│   └── dubbo -│   └── springboot -│   └── demo -│   └── DemoService.java // API 接口 -├── dubbo-samples-spring-boot-consumer // 消费端模块 -│   ├── pom.xml -│   └── src -│   ├── main -│   │   ├── java -│   │   │   └── org -│   │   │   └── apache -│   │   │   └── dubbo -│   │   │   └── springboot -│   │   │   └── demo -│   │   │   └── consumer -│   │   │   ├── ConsumerApplication.java // 消费端启动类 -│   │   │   └── Task.java // 消费端模拟调用任务 -│   │   └── resources -│   │   └── application.yml // Spring Boot 配置文件 -├── dubbo-samples-spring-boot-provider // 服务端模块 -│   ├── pom.xml -│   └── src -│   └── main -│   ├── java -│   │   └── org -│   │   └── apache -│   │   └── dubbo -│   │   └── springboot -│   │   └── demo -│   │   └── provider -│   │   ├── DemoServiceImpl.java // 服务端实现类 -│   │   └── ProviderApplication.java // 服务端启动类 -│   └── resources -│   └── application.yml // Spring Boot 配置文件 -└── pom.xml -``` - -如上为本教程接下来会使用到的项目的文件结构。 - -## 快速部署(基于 Samples 直接启动) - -本章将通过几个简单的命令,一步一步教你如何部署并运行一个基于 Dubbo x Spring Boot 的用例。 - -注:本章部署的代码细节可以在 [apache/dubbo-samples](https://github.com/apache/dubbo-samples) 这个仓库中 `1-basic/dubbo-samples-spring-boot` 中找到,在下一章中也将展开进行讲解。 - -### 1. 获取测试工程 - -在开始整个教程之前,我们需要先获取测试工程的代码。Dubbo 的所有测试用例代码都存储在 [apache/dubbo-samples](https://github.com/apache/dubbo-samples) 这个仓库中,以下这个命令可以帮你获取 Samples 仓库的所有代码。 - -```bash -git clone --depth=1 --branch master git@github.com:apache/dubbo-samples.git -``` - -### 2. 启动一个简易的注册中心 - -对于一个微服务化的应用来说,注册中心是不可或缺的一个组件。只有通过注册中心,消费端才可以成功发现服务端的地址信息,进而进行调用。 - -为了让本教程更易于上手,我们提供了一个基于 Apache Zookeeper 注册中心的简易启动器,如果您需要在生产环境部署注册中心,请参考[生产环境初始化](/)一文部署高可用的注册中心。 - -```bash -Windows: -./mvnw.cmd clean compile exec:java -pl tools/embedded-zookeeper - -Linux / MacOS: -./mvnw clean compile exec:java -pl tools/embedded-zookeeper - -Docker: -docker run --name some-zookeeper -p 2181:2181 --restart always -d zookeeper -``` - -### 3. 本地打包 API 模块 - -为了成功编译服务端、消费端模块,需要先在本地打包安装 `dubbo-samples-spring-boot-interface` 模块。 - -```bash -./mvnw clean install -pl 1-basic/dubbo-samples-spring-boot -./mvnw clean install -pl 1-basic/dubbo-samples-spring-boot/dubbo-samples-spring-boot-interface -``` - -### 4. 启动服务提供者 - -在启动了注册中心之后,下一步是启动一个对外提供服务的服务提供者。在 dubbo-samples 中也提供了对应的示例,可以通过以下命令快速拉起。 - -```bash -Windows: -./mvnw.cmd clean compile exec:java -pl 1-basic/dubbo-samples-spring-boot/dubbo-samples-spring-boot-provider -Dexec.mainClass="org.apache.dubbo.springboot.demo.provider.ProviderApplication" - -Linux / MacOS: -./mvnw clean compile exec:java -pl 1-basic/dubbo-samples-spring-boot/dubbo-samples-spring-boot-provider -Dexec.mainClass="org.apache.dubbo.springboot.demo.provider.ProviderApplication" - -注:需要开一个独立的 terminal 运行,命令将会保持一直执行的状态。 -``` - -在执行完上述命令以后,等待一会出现如下所示的日志(`Current Spring Boot Application is await`)即代表服务提供者启动完毕,标志着该服务提供者可以对外提供服务了。 - -```log -2023-02-08 17:13:00.357 INFO 80600 --- [lication.main()] o.a.d.c.d.DefaultApplicationDeployer : [DUBBO] Dubbo Application[1.1](dubbo-springboot-demo-provider) is ready., dubbo version: 3.2.0-beta.4, current host: 30.221.128.96 -2023-02-08 17:13:00.369 INFO 80600 --- [lication.main()] o.a.d.s.d.provider.ProviderApplication : Started ProviderApplication in 9.114 seconds (JVM running for 26.522) -2023-02-08 17:13:00.387 INFO 80600 --- [pool-1-thread-1] .b.c.e.AwaitingNonWebApplicationListener : [Dubbo] Current Spring Boot Application is await... -``` - -### 5. 启动服务消费者 - -最后一步是启动一个服务消费者来调用服务提供者,也即是 RPC 调用的核心,为服务消费者提供调用服务提供者的桥梁。 - -```bash -Windows: -./mvnw.cmd clean compile exec:java -pl 1-basic/dubbo-samples-spring-boot/dubbo-samples-spring-boot-consumer -Dexec.mainClass="org.apache.dubbo.springboot.demo.consumer.ConsumerApplication" - -Linux / MacOS: -./mvnw clean compile exec:java -pl 1-basic/dubbo-samples-spring-boot/dubbo-samples-spring-boot-consumer -Dexec.mainClass="org.apache.dubbo.springboot.demo.consumer.ConsumerApplication" -``` - -在执行完上述命令以后,等待一会出现如下所示的日志(`Hello world`),打印出的数据就是服务提供者处理之后返回的,标志着一次服务调用的成功。 - -```log -2023-02-08 17:14:33.045 INFO 80740 --- [lication.main()] o.a.d.s.d.consumer.ConsumerApplication : Started ConsumerApplication in 11.052 seconds (JVM running for 31.62) -Receive result ======> Hello world -2023-02-08 17:14:33.146 INFO 80740 --- [pool-1-thread-1] .b.c.e.AwaitingNonWebApplicationListener : [Dubbo] Current Spring Boot Application is await... -Wed Feb 08 17:14:34 CST 2023 Receive result ======> Hello world -Wed Feb 08 17:14:35 CST 2023 Receive result ======> Hello world -Wed Feb 08 17:14:36 CST 2023 Receive result ======> Hello world -Wed Feb 08 17:14:37 CST 2023 Receive result ======> Hello world -``` - -## 动手实践(从零代码开发版) - -本章将通过手把手的教程一步一步教你如何从零开发一个微服务应用。 - -### 1. 启动注册中心 - -对于一个微服务化的应用来说,注册中心是不可或缺的一个组件。只有通过注册中心,消费端才可以成功发现服务端的地址信息,进而进行调用。 - -为了让本教程更易于上手,我们提供了一个基于 Apache Zookeeper 注册中心的简易启动器,如果您需要在生产环境部署注册中心,请参考[生产环境初始化](/)一文部署高可用的注册中心。 - -```bash -Windows: -git clone --depth=1 --branch master git@github.com:apache/dubbo-samples.git -cd dubbo-samples -./mvnw.cmd clean compile exec:java -pl tools/embedded-zookeeper - -Linux / MacOS: -git clone --depth=1 --branch master git@github.com:apache/dubbo-samples.git -cd dubbo-samples -./mvnw clean compile exec:java -pl tools/embedded-zookeeper - -Docker: -docker run --name some-zookeeper -p 2181:2181 --restart always -d zookeeper -``` - -### 2. 初始化项目 - -从本小节开始,将基于 IntelliJ IDEA 进行工程的搭建以及测试。 - -![img](/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-17-25-27-image.png) - -如上图所示,可以建立一个基础的项目。 - -搭建了基础项目之后,我们还需要创建 `dubbo-spring-boot-demo-interface` 、`dubbo-spring-boot-demo-provider` 和 `dubbo-spring-boot-demo-consumer` 三个子模块。 - -![img](/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-17-27-17-image.png) - -![img](/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-17-26-57-image.png) - -![img](/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-17-27-45-image.png) - -![img](/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-17-28-26-image.png) - -创建了三个子模块之后,需要创建一下几个文件夹: - -1. 在 `dubbo-spring-boot-demo-consumer/src/main/java` 下创建 `org.apache.dubbo.springboot.demo.consumer` package - -2. 在 `dubbo-spring-boot-demo-interface/src/main/java` 下创建 `org.apache.dubbo.springboot.demo` package - -3. 在 `dubbo-spring-boot-demo-provider/src/main/java` 下创建 `org.apache.dubbo.springboot.demo.provider` package - -![img](/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-17-32-50-image.png) - -最终的文件夹参考如上图所示。 - -### 3. 添加 Maven 依赖 - -在初始化完项目以后,我们需要先添加 Dubbo 相关的 maven 依赖。 - -对于多模块项目,首先需要在父项目的 `pom.xml` 里面配置依赖信息。 - -![img](/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-17-53-18-image.png) - -编辑 `./pom.xml` 这个文件,添加下列配置。 - -```xml - org.apache.dubbo - dubbo-spring-boot-demo - 1.0-SNAPSHOT - pom - - - dubbo-spring-boot-demo-interface - dubbo-spring-boot-demo-provider - dubbo-spring-boot-demo-consumer - - - - 3.2.0-beta.4 - 2.7.8 - 17 - 17 - UTF-8 - - - - - - - org.springframework.boot - spring-boot-dependencies - ${spring-boot.version} - pom - import - - - - - org.apache.dubbo - dubbo-bom - ${dubbo.version} - pom - import - - - - org.apache.dubbo - dubbo-dependencies-zookeeper-curator5 - ${dubbo.version} - pom - - - - - - - - - - org.springframework.boot - spring-boot-maven-plugin - ${spring-boot.version} - - - - -``` - -然后在 `dubbo-spring-boot-consumer` 和 `dubbo-spring-boot-provider` 两个模块 `pom.xml` 中进行具体依赖的配置。 - -![img](/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-17-52-53-image.png) - -编辑 `./dubbo-spring-boot-consumer/pom.xml` 和 `./dubbo-spring-boot-provider/pom.xml` 这两文件,都添加下列配置。 - -```xml - - - org.apache.dubbo - dubbo-spring-boot-demo-interface - ${project.parent.version} - - - - - org.apache.dubbo - dubbo-spring-boot-starter - - - org.apache.dubbo - dubbo-dependencies-zookeeper-curator5 - pom - - - slf4j-reload4j - org.slf4j - - - - - - - org.springframework.boot - spring-boot-starter - - - -``` - -在这份配置中,定义了 dubbo 和 zookeeper(以及对应的连接器 curator)的依赖。 - -添加了上述的配置以后,可以通过 IDEA 的 `Maven - Reload All Maven Projects` 刷新依赖。 - -### 4. 定义服务接口 - -服务接口 Dubbo 中沟通消费端和服务端的桥梁。 - -![img](/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-17-57-29-image.png) - -在 `dubbo-spring-boot-demo-interface` 模块的 `org.apache.dubbo.samples.api` 下建立 `DemoService` 接口,定义如下: - -```java -package org.apache.dubbo.springboot.demo; - -public interface DemoService { - - String sayHello(String name); -} -``` - -在 `DemoService` 中,定义了 `sayHello` 这个方法。后续服务端发布的服务,消费端订阅的服务都是围绕着 `DemoService` 接口展开的。 - -### 5. 定义服务端的实现 - -定义了服务接口之后,可以在服务端这一侧定义对应的实现,这部分的实现相对于消费端来说是远端的实现,本地没有相关的信息。 - -![img](/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-17-59-46-image.png) - -在`dubbo-spring-boot-demo-provider` 模块的 `org.apache.dubbo.samples.provider` 下建立 `DemoServiceImpl` 类,定义如下: - -```java -package org.apache.dubbo.springboot.demo.provider; - -import org.apache.dubbo.config.annotation.DubboService; -import org.apache.dubbo.springboot.demo.DemoService; - -@DubboService -public class DemoServiceImpl implements DemoService { - - @Override - public String sayHello(String name) { - return "Hello " + name; - } -} -``` - -在 `DemoServiceImpl` 中,实现了 `DemoService` 接口,对于 `sayHello` 方法返回 `Hello name`。 - -注:在`DemoServiceImpl` 类中添加了 `@DubboService` 注解,通过这个配置可以基于 Spring Boot 去发布 Dubbo 服务。 - -### 6. 配置服务端 Yaml 配置文件 - -从本步骤开始至第 7 步,将会通过 Spring Boot 的方式配置 Dubbo 的一些基础信息。 - -首先,我们先创建服务端的配置文件。 - -![img](/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-18-00-24-image.png) - -在 `dubbo-spring-boot-demo-provider` 模块的 `resources` 资源文件夹下建立 `application.yml` 文件,定义如下: - -```yaml -dubbo: - application: - name: dubbo-springboot-demo-provider - protocol: - name: dubbo - port: -1 - registry: - address: zookeeper://${zookeeper.address:127.0.0.1}:2181 -``` - -在这个配置文件中,定义了 Dubbo 的应用名、Dubbo 协议信息、Dubbo 使用的注册中心地址。 - -### 7. 配置消费端 YAML 配置文件 - -同样的,我们需要创建消费端的配置文件。 - -![img](/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-18-01-03-image.png) - -在 `dubbo-spring-boot-demo-consumer` 模块的 `resources` 资源文件夹下建立 `application.yml` 文件,定义如下: - -```yaml -dubbo: - application: - name: dubbo-springboot-demo-consumer - protocol: - name: dubbo - port: -1 - registry: - address: zookeeper://${zookeeper.address:127.0.0.1}:2181 -``` - -在这个配置文件中,定义了 Dubbo 的应用名、Dubbo 协议信息、Dubbo 使用的注册中心地址。 - -### 8. 基于 Spring 配置服务端启动类 - -除了配置 Yaml 配置文件之外,我们还需要创建基于 Spring Boot 的启动类。 - -首先,我们先创建服务端的启动类。 - -![img](/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-18-01-38-image.png) - -在 `dubbo-spring-boot-demo-provider` 模块的 `org.apache.dubbo.springboot.demo.provider` 下建立 `Application` 类,定义如下: - -```java -package org.apache.dubbo.springboot.demo.provider; - -import org.apache.dubbo.config.spring.context.annotation.EnableDubbo; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -@SpringBootApplication -@EnableDubbo -public class ProviderApplication { - public static void main(String[] args) { - SpringApplication.run(ProviderApplication.class, args); - } -} -``` - -在这个启动类中,配置了一个 `ProviderApplication` 去读取我们前面第 6 步中定义的 `application.yml` 配置文件并启动应用。 - -### 9. 基于 Spring 配置消费端启动类 - -同样的,我们需要创建消费端的启动类。 - -![img](/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-18-02-11-image.png) - -在 `dubbo-spring-boot-demo-consumer` 模块的 `org.apache.dubbo.springboot.demo.consumer` 下建立 `Application` 类,定义如下: - -```java -package org.apache.dubbo.springboot.demo.consumer; - -import org.apache.dubbo.config.spring.context.annotation.EnableDubbo; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -@SpringBootApplication -@EnableDubbo -public class ConsumerApplication { - - public static void main(String[] args) { - SpringApplication.run(ConsumerApplication.class, args); - } -} -``` - -在这个启动类中,配置了一个 `ConsumerApplication` 去读取我们前面第 7 步中定义的 `application.yml` 配置文件并启动应用。 - -### 10. 配置消费端请求任务 - -除了配置消费端的启动类,我们在 Spring Boot 模式下还可以基于 `CommandLineRunner`去创建 - -![img](/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-18-02-33-image.png) - -在 `dubbo-spring-boot-demo-consumer` 模块的 `org.apache.dubbo.springboot.demo.consumer` 下建立 `Task` 类,定义如下: - -```java -package org.apache.dubbo.springboot.demo.consumer; - -import java.util.Date; - -import org.apache.dubbo.config.annotation.DubboReference; -import org.apache.dubbo.springboot.demo.DemoService; -import org.springframework.boot.CommandLineRunner; -import org.springframework.stereotype.Component; - -@Component -public class Task implements CommandLineRunner { - @DubboReference - private DemoService demoService; - - @Override - public void run(String... args) throws Exception { - String result = demoService.sayHello("world"); - System.out.println("Receive result ======> " + result); - - new Thread(()-> { - while (true) { - try { - Thread.sleep(1000); - System.out.println(new Date() + " Receive result ======> " + demoService.sayHello("world")); - } catch (InterruptedException e) { - e.printStackTrace(); - Thread.currentThread().interrupt(); - } - } - }).start(); - } -} -``` - -在 `Task` 类中,通过`@DubboReference` 从 Dubbo 获取了一个 RPC 订阅,这个 `demoService` 可以像本地调用一样直接调用。在 `run`方法中创建了一个线程进行调用。 - -### 11. 启动应用 - -截止第 10 步,代码就已经开发完成了,本小节将启动整个项目并进行验证。 - -![img](/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-18-03-59-image.png) - -首先是启动 `org.apache.dubbo.samples.provider.Application` ,等待一会出现如下图所示的日志(`Current Spring Boot Application is await`)即代表服务提供者启动完毕,标志着该服务提供者可以对外提供服务了。 - -```log -[Dubbo] Current Spring Boot Application is await... -``` - -然后是启动`org.apache.dubbo.samples.client.Application` ,等待一会出现如下图所示的日志(`Hello world` )即代表服务消费端启动完毕并调用到服务端成功获取结果。 - -![img](/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-18-05-02-image.png) - -```log -Receive result ======> Hello world -``` - -## 延伸阅读 - -### 1. Dubbo 的 Spring 配置介绍 - -Dubbo 的主要配置入口有 yaml 的配置内容、`@DubboReference` 和`@DubboService` 等,更多的细节可以参考 [Annotation 配置 | Apache Dubbo](/zh-cn/overview/mannual/java-sdk/reference-manual/config/annotation/) 一文。 - -## 更多 - -本教程介绍了如何基于 Dubbo x Spring Boot 开发一个微服务应用。在下一节中,将介绍[另外一种 Dubbo 的配置方式 —— Dubbo x Spring XML](../spring-xml/)。 diff --git a/content/zh-cn/overview/quickstart/nodejs/_index.md b/content/zh-cn/overview/quickstart/nodejs/_index.md deleted file mode 100755 index 2ae8a3da79f0..000000000000 --- a/content/zh-cn/overview/quickstart/nodejs/_index.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -_build: - render: link -description: Node.js 微服务开发入门 -icon: fas fa-external-link-alt -linkTitle: Node.js -manualLink: https://github.com/apache/dubbo-js -manualLinkTarget: _blank -title: Node.js 微服务开发入门 -type: docs -weight: 40 ---- diff --git a/content/zh-cn/overview/quickstart/rust/_index.md b/content/zh-cn/overview/quickstart/rust/_index.md deleted file mode 100755 index 27e8e6e9c7f1..000000000000 --- a/content/zh-cn/overview/quickstart/rust/_index.md +++ /dev/null @@ -1,253 +0,0 @@ ---- -aliases: - - /zh/overview/quickstart/rust/ -description: Rust 微服务开发入门 -hide: true -linkTitle: Rust -no_list: true -title: Rust 微服务开发入门 -type: docs -weight: 3 ---- - - - - -请在此查看完整 [示例](https://github.com/apache/dubbo-rust/tree/main/examples/greeter)。 - -## 1 前置条件 -- 安装 [Rust](https://rustup.rs/) 开发环境 -- 安装 [protoc](https://grpc.io/docs/protoc-installation/) 工具 - -## 2 使用 IDL 定义 Dubbo 服务 - -Greeter 服务定义如下,包含一个 Unary(request-response) 模型的 Dubbo 服务。 - -```protobuf -// ./proto/greeter.proto -syntax = "proto3"; - -option java_multiple_files = true; - -package org.apache.dubbo.sample.tri; - - -// The request message containing the user's name. -message GreeterRequest { - string name = 1; -} - -// The response message containing the greetings -message GreeterReply { - string message = 1; -} - -service Greeter{ - // unary - rpc greet(GreeterRequest) returns (GreeterReply); -} -``` - -## 3 添加 Dubbo-rust 及相关依赖到项目 -```toml -# ./Cargo.toml -[package] -name = "example-greeter" -version = "0.1.0" -edition = "2021" - -[[bin]] -name = "greeter-server" -path = "src/greeter/server.rs" - -[[bin]] -name = "greeter-client" -path = "src/greeter/client.rs" - -[dependencies] -http = "0.2" -http-body = "0.4.4" -futures-util = {version = "0.3", default-features = false} -tokio = { version = "1.0", features = [ "rt-multi-thread", "time", "fs", "macros", "net", "signal"] } -prost-derive = {version = "0.10", optional = true} -prost = "0.10.4" -async-trait = "0.1.56" -tokio-stream = "0.1" - -dubbo = "0.1.0" -dubbo-config = "0.1.0" - -[build-dependencies] -dubbo-build = "0.1.0" -``` - -## 4 配置 dubbo-build 编译 IDL - -在项目根目录创建 (not /src),创建 `build.rs` 文件并添加以下内容: - -```rust -// ./build.rs -fn main() { - dubbo_build::prost::configure() - .compile(&["proto/greeter.proto"], &["proto/"]) - .unwrap(); -} -``` -这样配置之后,编译项目就可以生成 Dubbo Stub 相关代码,路径一般在`./target/debug/build/example-greeter-/out/org.apache.dubbo.sample.tri.rs`。 - -## 5 编写 Dubbo 业务代码 - -### 5.1 编写 Dubbo Server - -```rust -// ./src/greeter/server.rs -use ... - -#[tokio::main] -async fn main() { - register_server(GreeterServerImpl { - name: "greeter".to_string(), - }); - - // Dubbo::new().start().await; - Dubbo::new() - .with_config({ - let r = RootConfig::new(); - match r.load() { - Ok(config) => config, - Err(_err) => panic!("err: {:?}", _err), // response was droped - } - }) - .start() - .await; -} - -#[allow(dead_code)] -#[derive(Default, Clone)] -struct GreeterServerImpl { - name: String, -} - -// #[async_trait] -#[async_trait] -impl Greeter for GreeterServerImpl { - async fn greet( - &self, - request: Request, - ) -> Result, dubbo::status::Status> { - println!("GreeterServer::greet {:?}", request.metadata); - - Ok(Response::new(GreeterReply { - message: "hello, dubbo-rust".to_string(), - })) - } -} -``` - -### 5.2 配置dubbo.yaml - -dubbo.yaml指示server端的配置,包括暴露的服务列表、协议配置、监听配置等。 - -```yaml -# ./dubbo.yaml -name: dubbo -service: - org.apache.dubbo.sample.tri.Greeter: - version: 1.0.0 - group: test - protocol: triple - registry: '' - serializer: json - protocol_configs: - triple: - ip: 0.0.0.0 - port: '8888' - name: triple -protocols: - triple: - ip: 0.0.0.0 - port: '8888' - name: triple -``` - -### 5.3 编写 Dubbo Client - -```rust -// ./src/greeter/client.rs -use ... - -#[tokio::main] -async fn main() { - let mut cli = GreeterClient::new().with_uri("http://127.0.0.1:8888".to_string()); - - println!("# unary call"); - let resp = cli - .greet(Request::new(GreeterRequest { - name: "message from client".to_string(), - })) - .await; - let resp = match resp { - Ok(resp) => resp, - Err(err) => return println!("{:?}", err), - }; - let (_parts, body) = resp.into_parts(); - println!("Response: {:?}", body); -} -``` - -## 6 运行并总结 - -1. 编译 - -执行`cargo build`来编译server和client。 - -2. 运行server - -执行`./target/debug/greeter-server`来运行server,如上文dubbo.yaml所配置,server会监听8888端口,并以triple协议提供RPC服务: - -```sh -$ ./target/debug/greeter-server -2022-09-28T23:33:28.104577Z INFO dubbo::framework: url: Some(Url { uri: "triple://0.0.0.0:8888/org.apache.dubbo.sample.tri.Greeter", protocol: "triple", location: "0.0.0.0:8888", ip: "0.0.0.0", port: "8888", service_key: ["org.apache.dubbo.sample.tri.Greeter"], params: {} }) -``` - -3. 运行client,验证调用是否成功 - -执行`./target/debug/greeter-client`来运行client,调用`triple://127.0.0.1:8888/org.apache.dubbo.sample.tri.Greeter`下的各种方法: - - -```sh -$ ./target/debug/greeter-client -Response: GreeterReply { message: "hello, dubbo-rust" } -``` - -## 7 更多示例 - -{{< blocks/section color="white" height="auto">}} -
-
-
-
-
-

- Streaming 通信模式 -

-

使用 Dubbo Rust 实现 Streaming 通信模型。

-
-
-
-
-
-
-

- 与 Dubbo Java 互通 -

-

实现与其他 Dubbo 多语言服务的互通

-
-
-
-
-
-
- -{{< /blocks/section >}} diff --git a/content/zh-cn/overview/reference/Metrics/standard_metrics.md b/content/zh-cn/overview/reference/Metrics/standard_metrics.md index 9c35f98c4054..4b93d3a4ab0e 100644 --- a/content/zh-cn/overview/reference/Metrics/standard_metrics.md +++ b/content/zh-cn/overview/reference/Metrics/standard_metrics.md @@ -1,4 +1,6 @@ --- +aliases: + - /zh-cn/overview/reference/Metrics/standard_metrics/ linkTitle: 标准监控指标 title: Dubbo 框架标准监控指标 type: docs diff --git a/content/zh-cn/overview/reference/_index.md b/content/zh-cn/overview/reference/_index.md index 86502e99e621..d2c7cc2af825 100755 --- a/content/zh-cn/overview/reference/_index.md +++ b/content/zh-cn/overview/reference/_index.md @@ -13,16 +13,6 @@ weight: 7
-
-
-
-

- Dubbo Admin -

-

Dubbo Admin 使用指南

-
-
-
diff --git a/content/zh-cn/overview/reference/admin/_index.md b/content/zh-cn/overview/reference/admin/_index.md deleted file mode 100644 index fa89e7bc1fe0..000000000000 --- a/content/zh-cn/overview/reference/admin/_index.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -description: "" -linkTitle: Admin -title: Admin 控制台操作手册 -type: docs -weight: 1 ---- diff --git a/content/zh-cn/overview/reference/admin/architecture.md b/content/zh-cn/overview/reference/admin/architecture.md deleted file mode 100644 index c38e0a083a2d..000000000000 --- a/content/zh-cn/overview/reference/admin/architecture.md +++ /dev/null @@ -1,293 +0,0 @@ ---- -description: "" -linkTitle: 架构与安装 -no_list: true -title: Admin 整体架构与安装步骤 -type: docs -weight: 1 -working_in_progress: true ---- - -回顾 [Dubbo 服务治理体系的总体架构](../../../what/overview/),Admin 是服务治理控制面中的一个核心组件,负责微服务集群的服务治理、可视化展示等。 - -## Admin 部署架构 - -![admin-core-components.png](/imgs/v3/reference/admin/admin-core-components.png) - -总体上来说,Admin 部署架构分为以下几个部分: -* Admin 主进程,包括服务发现元数据管理、可视化控制台、安全认证策略管控、其他定制化服务治理能力等组件。 -* 强依赖组件,包括 Mysql 数据库、注册/配置/元数据中心(可以是 Kubernetes、Nacos、Zookeeper 等) -* 可选依赖组件,包括 Prometheus、Grafana、Zipkin 等 - -## 安装 Admin - -### Dubboctl 安装 -#### Download -当前Dubboctl未正式发行,可按以下方式进行尝试。 -拉取Dubbo Admin并编译Dubboctl -```shell -git clone https://github.com/apache/dubbo-admin.git -cd dubbo-admin/cmd/dubboctl -go build -o dubboctl . -``` - -将 dubboctl 放入可执行路径 -```shell -ln -s dubbo-admin/cmd/dubboctl/dubboctl /usr/local/bin/dubboctl -``` -#### Install -安装过程会依次: - -1. 将用户自定义的配置profile以及set参数覆盖于默认profile,得到最终的profile -```yaml -# default profile -apiVersion: dubbo.apache.org/v1alpha1 -kind: DubboOperator -metadata: - namespace: dubbo-system -spec: - profile: default - namespace: dubbo-system - componentsMeta: - admin: - enabled: true - grafana: - enabled: true - repoURL: https://grafana.github.io/helm-charts - version: 6.52.4 - nacos: - enabled: true - zookeeper: - enabled: true - repoURL: https://charts.bitnami.com/bitnami - version: 11.1.6 - prometheus: - enabled: true - repoURL: https://prometheus-community.github.io/helm-charts - version: 20.0.2 - skywalking: - enabled: true - repoURL: https://apache.jfrog.io/artifactory/skywalking-helm - version: 4.3.0 - zipkin: - enabled: true - repoURL: https://openzipkin.github.io/zipkin - version: 0.3.0 -``` -建议使用自定义profile进行配置,在componentsMeta中开启或关闭组件,在components下配置各组件。其中components下各组件的配置值都是helm chart的values,各组件的具体配置请参考: -Grafana: https://github.com/grafana/helm-charts/blob/main/charts/grafana/README.md -Zookeeper: https://github.com/bitnami/charts/tree/main/bitnami/zookeeper/#installing-the-chart -Prometheus: https://github.com/prometheus-community/helm-charts/tree/main/charts -Skywalking: https://github.com/apache/skywalking-kubernetes/blob/master/chart/skywalking/README.md -Zipkin: https://github.com/openzipkin/zipkin-helm -```yaml -# customization profile -apiVersion: dubbo.apache.org/v1alpha1 -kind: DubboOperator -metadata: - namespace: dubbo-system -spec: - profile: default - namespace: dubbo-system - componentsMeta: - admin: - enabled: true - grafana: - enabled: true - version: 6.31.0 - prometheus: - enabled: false - components: - admin: - replicas: 3 - grafana: - testFramework: - enabled: false -``` -2. 根据profile拉取所需组件并生成manifest,目前Admin,Nacos已在本地,无需拉取;Grafana,Zookeeper,Prometheus,Skywalking,Zipkin将从官方chart库拉取,具体地址和版本可见上方default profile -3. 将manifest应用于k8s集群 -```shell -dubboctl manifest install # 使用默认 manifests 安装 - -# or - -dubboctl manifest generate | kubectl apply -f - -``` - -```shell -dubboctl install --set spec.components.admin.replicas=2 # 设置组件的配置 -``` - -```shell -dubboctl install --set spec.componentsMeta.admin.enabled=true, spec.componentsMeta.grafana.enabled=false -# 开启或关闭组件 -``` - -```shell -dubboctl install --set spec.componentsMeta.grafana.repoURL=https://grafana.github.io/helm-charts, spec.componentsMeta.grafana.version=6.31.0 -# 设置需远程拉取组件的仓库地址与版本 -``` - -检查安装效果 -```shell -kubectl get pod -n dubbo-system -``` - -#### 打开 Admin 控制台 -```shell -kubectl port-forward svc/dubbo-admin -n dubbo-system 38080:38080 -``` - -打开浏览器,访问: `http://127.0.0.1:38080/` - -### Helm 安装 - -获取图表 -``` -helm repo add https://charts.bitnami.com/bitnami -helm repo add https://prometheus-community.github.io/helm-charts -helm repo add https://grafana.github.io/helm-charts -helm repo add https://apache.jfrog.io/artifactory/skywalking-helm -helm repo add https://openzipkin.github.io/zipkin -``` -安装 zookeeper -```bash -helm install zookeeper bitnami/zookeeper -n dubbo-system -``` - -安装 prometheus -```bash -helm install prometheus prometheus-community/prometheus -n dubbo-system -``` - -安装 grafana -```bash -helm install grafana grafana/grafana -n dubbo-system -``` - -安装 skywalking -```bash -helm install skywalking skywalking/skywalking -n dubbo-system -``` - -安装 zipkin -``` -helm install zipkin openzipkin/zipkin -n dubbo-system -``` - -检查安装状态 -```shell -helm ls -n dubbo-system ;kubectl get pods -n dubbo-system --output wide -``` - -### VM 安装 -#### Download -下载 Dubbo Admin 发行版本 -```shell -curl -L https://dubbo.apache.org/installer.sh | VERSION=0.1.0 sh - -# Admin 要组织好发行版本 -``` - -将 dubboctl 放入可执行路径 -```shell -ln -s dubbo-admin-0.1.0/bin/dubbo-admin /usr/local/bin/dubbo-admin -``` -#### Run -```shell -dubbo-admin run -f override-configuration.yml -``` -## 配置手册 (Configuration) -配置用于控制 dubbo-admin 的行为 - - -```yaml -# Environment type. Available values are: "kubernetes" or "universal" -environment: universal # ENV: DUBBO_ENVIRONMENT -# Mode in which Dubbo CP is running. Available values are: "standalone", "global", "zone" -mode: standalone # ENV: DUBBO_MODE - -# Resource Store configuration -store: - # Type of Store used in the Control Plane. Available values are: "kubernetes", "postgres" or "memory" - type: memory # ENV: DUBBO_STORE_TYPE - - # Kubernetes Store configuration (used when store.type=kubernetes) - kubernetes: - # Namespace where Control Plane is installed to. - systemNamespace: dubbo-system # ENV: DUBBO_STORE_KUBERNETES_SYSTEM_NAMESPACE - - # Postgres Store configuration (used when store.type=postgres) - mysql: - # Host of the Postgres DB - host: 127.0.0.1 # ENV: DUBBO_STORE_POSTGRES_HOST - # Port of the Postgres DB - port: 15432 # ENV: DUBBO_STORE_POSTGRES_PORT - # User of the Postgres DB - user: dubbo # ENV: DUBBO_STORE_POSTGRES_USER - # Password of the Postgres DB - password: dubbo # ENV: DUBBO_STORE_POSTGRES_PASSWORD - # Database name of the Postgres DB - dbName: dubbo # ENV: DUBBO_STORE_POSTGRES_DB_NAME - # Connection Timeout to the DB in seconds - connectionTimeout: 5 # ENV: DUBBO_STORE_POSTGRES_CONNECTION_TIMEOUT - # Maximum number of open connections to the database - # `0` value means number of open connections is unlimited - maxOpenConnections: 50 # ENV: DUBBO_STORE_POSTGRES_MAX_OPEN_CONNECTIONS - # Maximum number of connections in the idle connection pool - # <0 value means no idle connections and 0 means default max idle connections - maxIdleConnections: 50 # ENV: DUBBO_STORE_POSTGRES_MAX_IDLE_CONNECTIONS - # TLS settings - tls: - # Mode of TLS connection. Available values are: "disable", "verifyNone", "verifyCa", "verifyFull" - mode: disable # ENV: DUBBO_STORE_POSTGRES_TLS_MODE - # Path to TLS Certificate of the client. Used in verifyCa and verifyFull modes - certPath: # ENV: DUBBO_STORE_POSTGRES_TLS_CERT_PATH - # Path to TLS Key of the client. Used in verifyCa and verifyFull modes - keyPath: # ENV: DUBBO_STORE_POSTGRES_TLS_KEY_PATH - # Path to the root certificate. Used in verifyCa and verifyFull modes. - caPath: # ENV: DUBBO_STORE_POSTGRES_TLS_ROOT_CERT_PATH - # MinReconnectInterval controls the duration to wait before trying to - # re-establish the database connection after connection loss. After each - # consecutive failure this interval is doubled, until MaxReconnectInterval - # is reached. Successfully completing the connection establishment procedure - # resets the interval back to MinReconnectInterval. - minReconnectInterval: "10s" # ENV: DUBBO_STORE_POSTGRES_MIN_RECONNECT_INTERVAL - # MaxReconnectInterval controls the maximum possible duration to wait before trying - # to re-establish the database connection after connection loss. - maxReconnectInterval: "60s" # ENV: DUBBO_STORE_POSTGRES_MAX_RECONNECT_INTERVAL -server: - port: 38080 -registry: - address: xxx -metadata-center: - address: xxx -config-center: - address: xxx -external-services: - prometheus: - # Prometheus service name is "metrics" and is in the "telemetry" namespace - # http://prometheus.:9090 - url: "http://metrics.telemetry:9090/" - tracing: - # Enabled by default. Kiali will anyway fallback to disabled if - # Jaeger is unreachable. - enabled: true - # Jaeger service name is "tracing" and is in the "telemetry" namespace. - # Make sure the URL you provide corresponds to the non-GRPC enabled endpoint - # if you set "use_grpc" to false. - in_cluster_url: 'http://tracing.telemetry:16685/jaeger' - use_grpc: true - # Public facing URL of Jaeger - url: 'http://my-jaeger-host/jaeger' - grafana: - enabled: true - # Grafana service name is "grafana" and is in the "telemetry" namespace. - in_cluster_url: 'http://grafana.telemetry:3000/' - # Public facing URL of Grafana - url: 'http://my-ingress-host/grafana' - -# 更多配置 -``` -#### 打开 Admin 控制台 - -打开浏览器,访问: `http://127.0.0.1:38080/` diff --git a/content/zh-cn/overview/reference/admin/documentation.md b/content/zh-cn/overview/reference/admin/documentation.md deleted file mode 100644 index b1234b31995a..000000000000 --- a/content/zh-cn/overview/reference/admin/documentation.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -description: "" -linkTitle: 文档管理 -no_list: true -toc_hide: true -title: Admin 文档管理功能介绍 -type: docs -weight: 6 -working_in_progress: true ---- - -// TBD - - diff --git a/content/zh-cn/overview/reference/admin/mock.md b/content/zh-cn/overview/reference/admin/mock.md deleted file mode 100644 index ed5d70a40027..000000000000 --- a/content/zh-cn/overview/reference/admin/mock.md +++ /dev/null @@ -1,173 +0,0 @@ ---- -description: "" -linkTitle: 服务Mock -no_list: true -title: Admin 服务 Mock 功能简介 -type: docs -weight: 4 -working_in_progress: true ---- - -Mock 功能是设计用来提升微服务研发与测试效率的,它可以短路 Consumer 侧发起的远程调用,提前返回预先设定好的 Mock 值,这样即使在没有 Provider 可用的情况下,消费端也能正常的推进开发、测试进程。除此之外,mock 也可用于快速模拟负责返回值的测试数据、模拟服务端异常等场景 - -需要注意的是,Mock 能力仅限用于测试环境,应避免将其用于生产环境。 - -# 设计背景 -在跨团队或是多应用开发时,在前期开发中往往会出现依赖的服务还未开发完成的情况,这样就会导致流程的阻塞,影响研发效率。基于这种情况,Dubbo Admin 提供了 mock 能力来解耦 Consumer 与 Provider 之间的依赖,以确保在 Provider 未就绪的情况下 Consumer 仍能正常开展测试,提高研发效率。 - -Dubbo 框架本身设计有服务降级(有时也称为 mock)能力,通过配置 `org.apache.dubbo.config.ReferenceConfig` 的 mock 字段(可设置为true或是对应接口的Mock实现)或动态配置规则,此时就可以启动服务降级能力。这种服务降级能力是为生产环境的限流降级准备的,虽然也可以用于本地开发测试场景,但灵活度并不高,基于提升开发效率的根本诉求,我们设计了基于 Admin 的服务降级能力。 - -Dubbo Admin 服务 mock 是一种更为轻量和便捷实现方式,主要用于开发测试阶段的,目标是提升微服务场景下的整体研发效率。需求详见:[Dubbo Admin Mock需求](https://github.com/apache/dubbo-admin/issues/757)。 - -## 架构设计 - -![admin-mock-architecture.png](/imgs/v3/reference/admin/console/mock-architecture.png) - -**实现 Mock 能力,Dubbo 框架与 Admin 侧要支持的能力** - -* Dubbo Admin - * 规则管理 - * 规则新增 - * 规则查询 - * 规则修改 - * 规则删除 - * 请求历史记录 - * Mock 请求数据查询 - * MockService Provider - * 根据规则生成 Mock 数据 - * 响应 Consumer Mock 请求 - * 保存请求和返回数据 -* Dubbo - * 根据 mock 开关配置,转发请求到 Admin 注册的 MockService - * 处理 mock 返回值并转换为匹配方法签名的强类型数据 - -**Mock 请求原理时序图** - -![admin-mock-workflow.png](/imgs/v3/reference/admin/console/mock-workflow.png) - -## 使用方式 - -1. 在 Consumer 应用中添加依赖 - - 开启 Mock 前,请确保在消费端应用中引入以下依赖: - - ```xml - - org.apache.dubbo.extensions - dubbo-mock-admin - ${version} - - ``` - - > 查看 [dubbo-mock-admin 的可用版本](/zh-cn/download/spi-extensions/) - -2. 配置 `-Denable.dubbo.admin.mock=true` 参数开启 Mock 并重启进程 -3. 打开 Admin 配置 Mock 规则 - - 用户可以通过在控制台上指定需要被 mock 的消费端IP、服务名和方法和具体的 mock 行为,实现对调用结果的 mock。 - - ![admin-mock](/imgs/v3/reference/admin/console/mock-rule-screenshot.png) - - 一些支持的规则类型与示例 - - ``` - 数字类型:123 - - 字符串:"hello, world!" - - 数组、列表:[1, 2, 3] - - 枚举:"ENUM_TYPE" - - Map、对象: - { - "prop1": "value1", - "prop2": ["a", "b", "c"] - } - - null: null - ``` - -4. 此时,消费端再次发起远程调用,就会得到预期 Mock 返回值。 - - > 注意事项 - > 1. Mock 仅限用于测试开发环境,因此为了确保核心依赖的稳定性,社区没有将 mock 组件打包在核心框架包中,用户可以自行决策是否将其作为应用的默认依赖在公司内推广 - > 2. 即使添加了 mock 二进制依赖,mock 功能也不会默认开启,需要设置 `-Denable.dubbo.admin.mock=true` 后才能开启。 - -## 实现原理 - -Consumer 调用发起的调用会被本地的 MockServiceFilter 拦截,如果 mock 开关开启,则 MockServiceFilter 将请求转发到 MockService (由 Dubbo Admin 发布的服务),MockService 根据请求的服务、方法等查询用户预先配置的 mock 规则,如果查询到则返回规则中的 mock 值,Consumer 收到 mock 值后调用成功返回。 - -### Mock 返回值如何定义? - -当前 Admin 支持录入 JSON 或者基本类型数据,如: - -* 返回数字值 (当方法签名返回值是数字类型) - -``` -123 -``` - -* 返回字符串 (当方法签名返回值是字符串类型) -``` -"hello, world!" -``` - -* 返回 JSON (当方法签名返回值是 Map 或对象类型) -``` -{ - "prop1": "value1", - "prop2": ["a", "b", "c"] -} -``` - -* 返回数组 (当方法签名返回值是数组或列表) -``` -[1, 2, 3] -``` - -### 消费端如何发起 MockService 调用? - -`dubbo-mock-admin` 将为消费端引入 MockServiceFilter 请求拦截器,如果用户打开 mock 开关,那么 Filter 会将请求转发到 Admin MockService 服务。 - -### Mock 值如何转换为原始类型值? - -MockService 支持返回标准 JSON 格式或者基本类型数据,消费端会基于 Dubbo 内置类型转换器将 JSON 等值转为原始对象类型。 - -### 未来优化点 -* 保存 Mock 开关到配置中心,用户可以通过 Admin 动态控制开关。 -* 开启 Mysql 数据库链接池 - -### 表结构设计 -Admin 依赖 Mysql 数据库存储用户配置的 mock 规则,具体的表结构设计如下。 - -#### Mock Rule - -```sql -CREATE TABLE `mock_rule` ( - `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', - `service_name` varchar(255) DEFAULT NULL COMMENT '服务名', - `method_name` varchar(255) DEFAULT NULL COMMENT '方法名', - `rule` text NULL DEFAULT COMMENT '规则', - `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='服务mock方法表'; -``` -#### Mock Log - -```sql -CREATE TABLE `mock_log` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键id', - `method_id` int(11) DEFAULT NULL COMMENT '规则id', - `request` text COMMENT '请求数据', - `response` text COMMENT '返回值', - `created_at` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `updated_at` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='mock请求记录表'; -``` - - - - diff --git a/content/zh-cn/overview/reference/erlang-sdk/_index.md b/content/zh-cn/overview/reference/erlang-sdk/_index.md new file mode 100755 index 000000000000..bbe745d36e1d --- /dev/null +++ b/content/zh-cn/overview/reference/erlang-sdk/_index.md @@ -0,0 +1,12 @@ +--- +aliases: + - /zh/docs3-v2/erlang-sdk/ + - /zh-cn/docs3-v2/erlang-sdk/ + - /zh-cn/overview/reference/erlang-sdk/ + - /zh-cn/overview/mannual/erlang-sdk/ +description: Erlang 支持 +linkTitle: Erlang SDK +title: Erlang SDK 手册 +type: docs +weight: 8 +--- diff --git a/content/zh-cn/overview/reference/erlang-sdk/quick-start.md b/content/zh-cn/overview/reference/erlang-sdk/quick-start.md new file mode 100644 index 000000000000..4ad051a37f0e --- /dev/null +++ b/content/zh-cn/overview/reference/erlang-sdk/quick-start.md @@ -0,0 +1,71 @@ +--- +aliases: + - /zh/docs3-v2/erlang-sdk/quick-start/ + - /zh-cn/docs3-v2/erlang-sdk/quick-start/ + - /zh-cn/overview/mannual/erlang-sdk/quick-start/ + - /zh-cn/overview/reference/erlang-sdk/quick-start/ +description: Erlang 快速开始 +linkTitle: 快速开始 +title: 快速开始 +type: docs +weight: 1 +--- + +建议先使用 java 定义接口 jar,并使用 [erlanalysis](https://github.com/apache/dubbo-erlang/tree/master/tools/erlanalysis) 工具解析java接口至Erlang lib + +## 导入依赖库 + +### 使用 Rebar 编译工具。 +Add dubblerl to rebar.config with your project +```erlang +{deps, [ + {dubboerl, {git, "https://github.com/apache/dubbo-erlang.git", {branch, "master"}}} +]}. +``` + +### 使用 erlang.mk 编译工具 +`待补充` + +## 导入接口库 +Suppose the interface lib you exported is called dubbo_service. +* If you didn't upload your lib to your git repository, It is recommended that you copy the `dubbo_service` lib +into the project's `apps` directory. +* If it is upload to your git repository, you can import like this: +```erlang +{deps, [ + {dubboerl, {git, "https://github.com/apache/dubbo-erlang.git", {branch, "master"}}}, + {dubbo_service,{git,"${INTERFACE_LIB_URL}",{branch,"master"}}} %% replace ${INTERFACE_LIB_URL} with your lib git repos url +]}. +``` + +## 消费者配置 +Please reference [Reference Config](../reference/) + +## Init dubbolib in your project +It is need you +```erlang +dubboerl:init(). +``` + +## 如何调用? + +### 同步调用 +```erlang +Request = #userInfoRequest{requestId = 123, username = "testname"}, +{ok,RequestRef,Response,RpcContent} = userOperator:queryUserInfo(Request,#{sync=> true}). +``` +If it occur error, is reponse `{error,Reason}`. + +### 异步调用 + +Default is Async call. +```erlang +Request = #userInfoRequest{requestId = 123, username = "testname"}, +{ok,RequestRef} = userOperator:queryUserInfo(Request). + +%% you can receive the message after. +handle_cast({msg_back,RequestRef,Response,RpcContent},State). +``` + +## 示例 +参考项目 [dubboerl_demo](https://github.com/apache/dubbo-erlang/tree/master/samples) diff --git a/content/zh-cn/overview/mannual/erlang-sdk/reference.md b/content/zh-cn/overview/reference/erlang-sdk/reference.md similarity index 83% rename from content/zh-cn/overview/mannual/erlang-sdk/reference.md rename to content/zh-cn/overview/reference/erlang-sdk/reference.md index 3f0415c093ce..230601811fcb 100644 --- a/content/zh-cn/overview/mannual/erlang-sdk/reference.md +++ b/content/zh-cn/overview/reference/erlang-sdk/reference.md @@ -2,6 +2,8 @@ aliases: - /zh/docs3-v2/erlang-sdk/reference/ - /zh-cn/docs3-v2/erlang-sdk/reference/ + - /zh-cn/overview/mannual/erlang-sdk/reference/ + - /zh-cn/overview/reference/erlang-sdk/reference/ description: 在 erlang 中配置消费者 linkTitle: 消费者配置 title: 消费者配置 diff --git a/content/zh-cn/overview/reference/erlang-sdk/serialization.md b/content/zh-cn/overview/reference/erlang-sdk/serialization.md new file mode 100644 index 000000000000..20fe7f4b4e41 --- /dev/null +++ b/content/zh-cn/overview/reference/erlang-sdk/serialization.md @@ -0,0 +1,36 @@ +--- +aliases: + - /zh/docs3-v2/erlang-sdk/serialization/ + - /zh-cn/docs3-v2/erlang-sdk/serialization/ + - /zh-cn/overview/mannual/erlang-sdk/serialization/ + - /zh-cn/overview/reference/erlang-sdk/serialization/ +description: 在 erlang 中配置序列化方式 +linkTitle: 序列化配置项 +title: 序列化配置项 +type: docs +weight: 4 +--- + + + + + + +当前该库只实现了 `dubbo://` 通讯协议。 + +序列化方式实现了 `hessian` 和 `json` 两种方式。 + +## 配置样例 + +序列化配置需要添加到 `sys.config` 文件 `dubboerl` 应用配置项里。 + +```erlang +{dubboerl,[ + %% other config ... + {protocol,hessian} +]} +``` + +| ConfigName | Type | DefaultValue | Remarks | +| --- | --- | --- | --- | +| protocol | atom() | hessian | hessian,json | diff --git a/content/zh-cn/overview/mannual/erlang-sdk/service.md b/content/zh-cn/overview/reference/erlang-sdk/service.md similarity index 90% rename from content/zh-cn/overview/mannual/erlang-sdk/service.md rename to content/zh-cn/overview/reference/erlang-sdk/service.md index b99c57c544ef..d0529ed2da3d 100644 --- a/content/zh-cn/overview/mannual/erlang-sdk/service.md +++ b/content/zh-cn/overview/reference/erlang-sdk/service.md @@ -2,6 +2,8 @@ aliases: - /zh/docs3-v2/erlang-sdk/service/ - /zh-cn/docs3-v2/erlang-sdk/service/ + - /zh-cn/overview/mannual/erlang-sdk/service/ + - /zh-cn/overview/reference/erlang-sdk/service/ description: 在 erlang 中配置服务提供者 linkTitle: 提供者配置 title: 提供者配置 diff --git a/content/zh-cn/overview/reference/integrations/grafana.md b/content/zh-cn/overview/reference/integrations/grafana.md index 05c294911d98..1a4f406c038c 100644 --- a/content/zh-cn/overview/reference/integrations/grafana.md +++ b/content/zh-cn/overview/reference/integrations/grafana.md @@ -24,7 +24,7 @@ Grafana 是一种开源的监控解决方案,可用于为 Dubbo 配置可视 你可以使用 Dubbo 社区提供的示例配置快速安装 Grafana,安装后的 Grafana 提供了社区默认指标面板视图。 ```bash -kubectl create -f https://raw.githubusercontent.com/apache/dubbo-admin/refactor-with-go/deploy/kubernetes/grafana.yaml +kubectl create -f https://raw.githubusercontent.com/apache/dubbo-kubernetes/master/deploy/kubernetes/grafana.yaml ``` 你可能需要端口映射获得访问地址 `$ kubectl port-forward service/grafana 3000:3000`,打开浏览器访问页面 `http://localhost:3000`。 diff --git a/content/zh-cn/overview/reference/integrations/higress.md b/content/zh-cn/overview/reference/integrations/higress.md new file mode 100644 index 000000000000..6704c9eac49e --- /dev/null +++ b/content/zh-cn/overview/reference/integrations/higress.md @@ -0,0 +1,48 @@ +--- +aliases: +- /zh/overview/reference/integrations/skywalking/ +description: "如何安装与配置 Higress,涵盖本地、docker、kubernetes 等环境。" +linkTitle: Higress +title: Higress +type: docs +weight: 6 +--- + +本文档讲解如何安装与配置 Higress,涵盖本地、docker、kubernetes 等环境。以下仅为快速示例安装指南,如想搭建生产可用集群请参考 Higress 官方文档。 + +## docker +使用 docker 启动 Higress,请首先确保您已经在本地机器正确 下载页面 安装 docker。 + +使用以下命令安装 Higress: + +```shell +curl -fsSL https://higress.io/standalone/get-higress.sh | bash -s -- -a -c nacos://192.168.0.1:8848 --nacos-username=nacos --nacos-password=nacos +``` + +请将 `192.168.0.1` 替换为 Nacos 服务器的 IP(如果 Nacos 部署在本机,请不要使用如 `localhost` 或 `127.0.0.1` 的 Loopback 地址)。按需调整 --nacos-username 和 --nacos-password 的取值,如果 Nacos 服务未开启认证功能,则可以移除这两个参数。 + +{{% alert title="注意" color="info" %}} +* 如果您还没有安装 nacos,请 [参考文档完成安装](../nacos/)。 +* 如果您使用 Zookeeper 做服务发现,请修改对应的集群地址为 zookeeper 集群地址。 +{{% /alert %}} + +在浏览器中输入 `http://127.0.0.1:8080` 进入 Higress 控制台。 + +## kubernetes + +通过以下命令安装 Higress: + +```shell +helm repo add higress.io https://higress.io/helm-charts +helm install higress -n higress-system higress.io/higress --create-namespace --render-subchart-notes --set global.local=true --set higress-console.o11y.enabled=false +``` + +通过以下端口映射命令,对本机访问开放端口: + +```shell +kubectl port-forward service/higress-gateway -n higress-system 80:80 443:443 8080:8080 +``` + +在浏览器中输入 `http://127.0.0.1:8080` 进入 Higress 控制台。 + + diff --git a/content/zh-cn/overview/reference/integrations/nacos.md b/content/zh-cn/overview/reference/integrations/nacos.md new file mode 100644 index 000000000000..2c8012f3c9e9 --- /dev/null +++ b/content/zh-cn/overview/reference/integrations/nacos.md @@ -0,0 +1,50 @@ +--- +aliases: +- /zh/overview/reference/integrations/skywalking/ +description: "如何安装与配置 Nacos,涵盖本地、docker、kubernetes等环境。" +linkTitle: Nacos +title: Nacos +type: docs +weight: 5 +--- + +本文档讲解如何安装与配置 Nacos,涵盖本地、docker、kubernetes 等环境。以下仅为快速示例安装指南,如想搭建生产可用集群请参考 Nacos 官方文档。 + +## 本地下载 + +Nacos 依赖 Java 环境 来运行,目前支持 Linux、MacOS、Windows 等环境。 + +您可以 下载最新稳定版本 Nacos,解压缩二进制包: + +```shell +unzip nacos-server-$version.zip +cd nacos/bin +#tar -xvf nacos-server-$version.tar.gz +``` + +#### 启动命令 +```shell +# Linux/Unix/Mac +sh startup.sh -m standalone + +# Ubuntu +bash startup.sh -m standalone + +# Windows +startup.cmd -m standalone +``` + +#### 验证 nacos 正常启动 + +通过浏览器访问以下链接打开控制台:http://127.0.0.1:8848/nacos/ + +## docker +使用 docker 启动 nacos,请首先确保您已经在本地机器正确 下载页面 安装 docker。 + +```shell +docker run --name nacos-quick -e MODE=standalone -p 8849:8848 -d nacos/nacos-server:2.3.1 +``` + +## kubernetes + +请参考 nacos-operator 了解如何部署 Nacos 到 Kubernetes 集群。 diff --git a/content/zh-cn/overview/reference/integrations/prometheus.md b/content/zh-cn/overview/reference/integrations/prometheus.md index e49d414e3828..89839a4de16d 100644 --- a/content/zh-cn/overview/reference/integrations/prometheus.md +++ b/content/zh-cn/overview/reference/integrations/prometheus.md @@ -13,7 +13,7 @@ weight: 1 你可以使用 Dubbo 社区提供的示例配置快速安装 Prometheus。 ```bash -kubectl create -f https://raw.githubusercontent.com/apache/dubbo-admin/refactor-with-go/deploy/kubernetes/prometheus.yaml +kubectl create -f https://raw.githubusercontent.com/apache/dubbo-kubernetes/master/deploy/kubernetes/prometheus.yaml ``` > 本安装仅适用于测试或体验使用,生产级别的安装请参考 Prometheus 官方安装文档。 diff --git a/content/zh-cn/overview/reference/integrations/skywalking.md b/content/zh-cn/overview/reference/integrations/skywalking.md index a9f295f147e7..55bb598b9853 100644 --- a/content/zh-cn/overview/reference/integrations/skywalking.md +++ b/content/zh-cn/overview/reference/integrations/skywalking.md @@ -13,6 +13,6 @@ weight: 3 你可以使用 Dubbo 社区提供的示例配置快速安装 Skywalking。 ```bash -kubectl create -f https://raw.githubusercontent.com/apache/dubbo-admin/refactor-with-go/deploy/kubernetes/skywalking.yaml +kubectl create -f https://raw.githubusercontent.com/apache/dubbo-kubernetes/master/deploy/kubernetes/skywalking.yaml ``` > 本安装仅适用于测试或体验使用,生产级别的安装请参考 Skywalking 官方安装文档。 diff --git a/content/zh-cn/overview/reference/integrations/zipkin.md b/content/zh-cn/overview/reference/integrations/zipkin.md index ddae7390ac22..27ee8fc17373 100644 --- a/content/zh-cn/overview/reference/integrations/zipkin.md +++ b/content/zh-cn/overview/reference/integrations/zipkin.md @@ -13,6 +13,6 @@ weight: 4 你可以使用 Dubbo 社区提供的示例配置快速安装 Zipkin。 ```bash -kubectl create -f https://raw.githubusercontent.com/apache/dubbo-admin/refactor-with-go/deploy/kubernetes/zipkin.yaml +kubectl create -f https://raw.githubusercontent.com/apache/dubbo-kubernetes/master/deploy/kubernetes/zipkin.yaml ``` > 本安装仅适用于测试或体验使用,生产级别的安装请参考 Zipkin 官方安装文档。 diff --git a/content/zh-cn/overview/reference/integrations/zookeeper.md b/content/zh-cn/overview/reference/integrations/zookeeper.md new file mode 100644 index 000000000000..dce003589532 --- /dev/null +++ b/content/zh-cn/overview/reference/integrations/zookeeper.md @@ -0,0 +1,92 @@ +--- +aliases: +- /zh/overview/reference/integrations/skywalking/ +description: "如何安装与配置 Zookeeper,涵盖本地、docker、kubernetes等环境。" +linkTitle: Zookeeper +title: Zookeeper +type: docs +weight: 6 +--- + +这篇文章讲解如何安装与配置 Zookeeper,涵盖本地、docker、kubernetes 等环境。以下仅为快速示例安装指南,如想搭建生产可用集群请参考 Zookeeper 官方文档。 + +## 本地下载 + +#### 下载Zookeeper +请到 Apache Zookeeper 下载页面 下载最新版本的 zookeeper 发行包。 + +解压下载的 zookeeper 包: + +```shell +tar -zxvf apache-zookeeper-3.8.3.tar.gz +cd apache-zookeeper-3.8.3 +``` + +#### 启动 Zookeeper + +在启动 zookeeper 之前,首先需要在根目录以下位置创建文件 `conf/zoo.cfg`: + +``` +tickTime=2000 +clientPort=2181 +admin.enableServer=false +``` + +以下是一些参数的详细解释: +* tickTime : Zookeeper 用到的基本时间设置,tickTime 为心跳检测间隔, 2*tickTime 是最大 session 超时时间等(单位是毫秒 ms)。 +* clientPort : 监听端口,客户端可通过这个端口方案 zookeeper server +* admin.enableServer:运维端口,默认为 8080,建议关闭防止和 Spring Web 应用程序冲突 + +接下来,可以以 standalone 模式启动 Zookeeper 了: + +```shell +bin/zkServer.sh start +``` + +#### 测试连接到 ZooKeeper + +运行以下命令,连接到刚刚启动的 zookeeper server: + +```shell +$ bin/zkCli.sh -server 127.0.0.1:2181 +``` + +连接成功后,可看到以下输出: + +```shell +Connecting to localhost:2181 +... +Welcome to ZooKeeper! +JLine support is enabled +[zkshell: 0] +``` + +执行以下命令查看根节点内容: + +```shell +[zkshell: 8] ls / +[zookeeper] +``` + +## docker + +使用 docker 启动 zookeeper,请首先确保您已经在本地机器正确 下载页面 安装 docker。 + +运行以下命令启动 zookeeper server: + +```shell +docker run --name some-zookeeper -p 2181:2181 -e JVMFLAGS="-Dzookeeper.admin.enableServer=false" --restart always -d zookeeper:3.8.3 +``` + +如果你要指定 `/conf` 配置文件,可通过 mount 本地文件到 docker 容器: +```shell +$ docker run --name some-zookeeper --restart always -e JVMFLAGS="-Dzookeeper.admin.enableServer=false" -d -v $(pwd)/zoo.cfg:/conf/zoo.cfg +``` + +## kubernetes + +您可以使用 Dubbo 社区提供的示例配置快速安装 Zookeeper 到 Kubernetes 集群。 + +```shell +kubectl apply -f https://raw.githubusercontent.com/apache/dubbo-kubernetes/master/deploy/kubernetes/zookeeper.yaml +``` \ No newline at end of file diff --git a/content/zh-cn/overview/reference/pixiu/_index.md b/content/zh-cn/overview/reference/pixiu/_index.md new file mode 100755 index 000000000000..b7c369e7720e --- /dev/null +++ b/content/zh-cn/overview/reference/pixiu/_index.md @@ -0,0 +1,12 @@ +--- +aliases: + - /zh/docs3-v2/dubbo-go-pixiu/ + - /zh-cn/docs3-v2/dubbo-go-pixiu/ + - /zh-cn/overview/mannual/dubbo-go-pixiu/ + - /zh-cn/overview/reference/pixiu/ +description: Dubbo Go Pixiu 简介 +linkTitle: Pixiu gateway +title: Dubbo Go Pixiu 简介 +type: docs +weight: 15 +--- diff --git a/content/zh-cn/overview/reference/pixiu/dev/_index.md b/content/zh-cn/overview/reference/pixiu/dev/_index.md new file mode 100755 index 000000000000..df862b67ff1b --- /dev/null +++ b/content/zh-cn/overview/reference/pixiu/dev/_index.md @@ -0,0 +1,10 @@ +--- +aliases: + - /zh-cn/overview/mannual/dubbo-go-pixiu/dev/ + - /zh-cn/overview/reference/pixiu/dev/ +description: 开发者指南 +linkTitle: 开发者指南 +title: 开发者指南 +type: docs +weight: 30 +--- diff --git a/content/zh-cn/overview/mannual/dubbo-go-pixiu/dev/dubbo-pilot.md b/content/zh-cn/overview/reference/pixiu/dev/dubbo-pilot.md similarity index 97% rename from content/zh-cn/overview/mannual/dubbo-go-pixiu/dev/dubbo-pilot.md rename to content/zh-cn/overview/reference/pixiu/dev/dubbo-pilot.md index d58402f5ea4d..8ad56b648b83 100644 --- a/content/zh-cn/overview/mannual/dubbo-go-pixiu/dev/dubbo-pilot.md +++ b/content/zh-cn/overview/reference/pixiu/dev/dubbo-pilot.md @@ -2,6 +2,8 @@ aliases: - /zh/docs3-v2/dubbo-go-pixiu/dev/dubbo-pilot/ - /zh-cn/docs3-v2/dubbo-go-pixiu/dev/dubbo-pilot/ + - /zh-cn/overview/reference/pixiu/dev/dubbo-pilot/ + - /zh-cn/overview/mannual/dubbo-go-pixiu/dev/dubbo-pilot/ description: dubbo-pilot Control Plane 部署 linkTitle: dubbo-pilot Control Plane 部署 title: dubbo-pilot Control Plane 部署 @@ -198,4 +200,4 @@ Forwarding from 127.0.0.1:8015 -> 8015 Forwarding from [::1]:8015 -> 8015 ``` -6. 可以进行远程调试 \ No newline at end of file +6. 可以进行远程调试 diff --git a/content/zh-cn/overview/mannual/dubbo-go-pixiu/dev/filter-extension.md b/content/zh-cn/overview/reference/pixiu/dev/filter-extension.md similarity index 96% rename from content/zh-cn/overview/mannual/dubbo-go-pixiu/dev/filter-extension.md rename to content/zh-cn/overview/reference/pixiu/dev/filter-extension.md index f6f857d5f16c..a7c4066c632f 100644 --- a/content/zh-cn/overview/mannual/dubbo-go-pixiu/dev/filter-extension.md +++ b/content/zh-cn/overview/reference/pixiu/dev/filter-extension.md @@ -2,6 +2,8 @@ aliases: - /zh/docs3-v2/dubbo-go-pixiu/dev/filter-extension/ - /zh-cn/docs3-v2/dubbo-go-pixiu/dev/filter-extension/ + - /zh-cn/overview/reference/pixiu/dev/filter-extension/ + - /zh-cn/overview/mannual/dubbo-go-pixiu/dev/filter-extension/ description: Pixiu Filter体系介绍 linkTitle: Pixiu Filter体系介绍 title: Pixiu Filter体系介绍 @@ -138,4 +140,4 @@ c’est la vie% ``` 2022-02-19T20:20:11.900+0800 INFO demo/demo.go:62 request body: eiv al tse’c 2022-02-19T20:20:11.900+0800 INFO demo/demo.go:71 : eiv al tse’c -``` \ No newline at end of file +``` diff --git a/content/zh-cn/overview/mannual/dubbo-go-pixiu/dev/trie.md b/content/zh-cn/overview/reference/pixiu/dev/trie.md similarity index 99% rename from content/zh-cn/overview/mannual/dubbo-go-pixiu/dev/trie.md rename to content/zh-cn/overview/reference/pixiu/dev/trie.md index fa76be362cca..3c9293505144 100644 --- a/content/zh-cn/overview/mannual/dubbo-go-pixiu/dev/trie.md +++ b/content/zh-cn/overview/reference/pixiu/dev/trie.md @@ -2,6 +2,8 @@ aliases: - /zh/docs3-v2/dubbo-go-pixiu/dev/trie/ - /zh-cn/docs3-v2/dubbo-go-pixiu/dev/trie/ + - /zh-cn/overview/reference/pixiu/dev/trie/ + - /zh-cn/overview/mannual/dubbo-go-pixiu/dev/trie/ description: Trie 前缀树介绍 linkTitle: Trie 前缀树介绍 title: Trie 前缀树介绍 @@ -142,4 +144,4 @@ path: '/api/v1/test-dubbo/user/name/:name' 1. 切换写引用到另一个树 1. 恢复追 log 线程 -pr:
[https://github.com/apache/dubbo-go-pixiu/pull/262](https://github.com/apache/dubbo-go-pixiu/pull/262)
pkg/common/router/trie/trie.go:26 \ No newline at end of file +pr:
[https://github.com/apache/dubbo-go-pixiu/pull/262](https://github.com/apache/dubbo-go-pixiu/pull/262)
pkg/common/router/trie/trie.go:26 diff --git a/content/zh-cn/overview/reference/pixiu/overview/_index.md b/content/zh-cn/overview/reference/pixiu/overview/_index.md new file mode 100755 index 000000000000..6815f4c36b9e --- /dev/null +++ b/content/zh-cn/overview/reference/pixiu/overview/_index.md @@ -0,0 +1,12 @@ +--- +aliases: + - /zh/docs3-v2/dubbo-go-pixiu/overview/ + - /zh-cn/docs3-v2/dubbo-go-pixiu/overview/ + - /zh-cn/overview/reference/pixiu/overview/ + - /zh-cn/overview/mannual/dubbo-go-pixiu/overview/ +description: 入门概述 +linkTitle: 入门概述 +title: 入门概述 +type: docs +weight: 10 +--- diff --git a/content/zh-cn/overview/mannual/dubbo-go-pixiu/overview/faq.md b/content/zh-cn/overview/reference/pixiu/overview/faq.md similarity index 81% rename from content/zh-cn/overview/mannual/dubbo-go-pixiu/overview/faq.md rename to content/zh-cn/overview/reference/pixiu/overview/faq.md index fccd3c0142ad..22da713f34a0 100755 --- a/content/zh-cn/overview/mannual/dubbo-go-pixiu/overview/faq.md +++ b/content/zh-cn/overview/reference/pixiu/overview/faq.md @@ -2,6 +2,8 @@ aliases: - /zh/docs3-v2/dubbo-go-pixiu/overview/faq/ - /zh-cn/docs3-v2/dubbo-go-pixiu/overview/faq/ + - /zh-cn/overview/reference/pixiu/overview/faq/ + - /zh-cn/overview/mannual/dubbo-go-pixiu/overview/faq/ description: Pixiu 常见问题 linkTitle: Pixiu 常见问题 title: Pixiu 常见问题 @@ -25,4 +27,4 @@ weight: 3 **Pixiu 目前支持高可用吗?** **A:** - 目前 Pixiu 仅支持单实例部署,可以和 Nginx 组成无状态多实例集群。 \ No newline at end of file + 目前 Pixiu 仅支持单实例部署,可以和 Nginx 组成无状态多实例集群。 diff --git a/content/zh-cn/overview/mannual/dubbo-go-pixiu/overview/terminology.md b/content/zh-cn/overview/reference/pixiu/overview/terminology.md similarity index 86% rename from content/zh-cn/overview/mannual/dubbo-go-pixiu/overview/terminology.md rename to content/zh-cn/overview/reference/pixiu/overview/terminology.md index 20b040a906ca..ca4fdbbf3bfd 100755 --- a/content/zh-cn/overview/mannual/dubbo-go-pixiu/overview/terminology.md +++ b/content/zh-cn/overview/reference/pixiu/overview/terminology.md @@ -2,6 +2,8 @@ aliases: - /zh/docs3-v2/dubbo-go-pixiu/overview/terminology/ - /zh-cn/docs3-v2/dubbo-go-pixiu/overview/terminology/ + - /zh-cn/overview/reference/pixiu/overview/terminology/ + - /zh-cn/overview/mannual/dubbo-go-pixiu/overview/terminology/ description: Pixiu 术语 linkTitle: Pixiu 术语 title: Pixiu 术语 @@ -39,4 +41,4 @@ Cluter 代表相同服务的集群,Endpoint 则代表服务集群中的单一 ### Adapter 适配器 -Adapter 则代表 Pixiu 和外界进行元数据获取的能力。能够根据服务中的服务元数据,进行路由和集群信息的动态获取。目前 Pixiu 支持两宽 Adapter,分别是从 Dubbo 集群和 Springcloud 集群获取信息。 \ No newline at end of file +Adapter 则代表 Pixiu 和外界进行元数据获取的能力。能够根据服务中的服务元数据,进行路由和集群信息的动态获取。目前 Pixiu 支持两宽 Adapter,分别是从 Dubbo 集群和 Springcloud 集群获取信息。 diff --git a/content/zh-cn/overview/mannual/dubbo-go-pixiu/overview/what-is-pixiu.md b/content/zh-cn/overview/reference/pixiu/overview/what-is-pixiu.md similarity index 95% rename from content/zh-cn/overview/mannual/dubbo-go-pixiu/overview/what-is-pixiu.md rename to content/zh-cn/overview/reference/pixiu/overview/what-is-pixiu.md index 3c9de721b0dd..2cb6d8e13fbd 100755 --- a/content/zh-cn/overview/mannual/dubbo-go-pixiu/overview/what-is-pixiu.md +++ b/content/zh-cn/overview/reference/pixiu/overview/what-is-pixiu.md @@ -2,6 +2,8 @@ aliases: - /zh/docs3-v2/dubbo-go-pixiu/overview/what-is-pixiu/ - /zh-cn/docs3-v2/dubbo-go-pixiu/overview/what-is-pixiu/ + - /zh-cn/overview/reference/pixiu/overview/what-is-pixiu/ + - /zh-cn/overview/mannual/dubbo-go-pixiu/overview/what-is-pixiu/ description: Pixiu 是一款开源的 Dubbo 生态的 API 网关和 接入 dubbo 集群的语言解决方案。作为 API 网关形态。 linkTitle: Pixiu 是什么 title: Pixiu 是什么 diff --git a/content/zh-cn/overview/reference/pixiu/user/_index.md b/content/zh-cn/overview/reference/pixiu/user/_index.md new file mode 100755 index 000000000000..1b21e015232c --- /dev/null +++ b/content/zh-cn/overview/reference/pixiu/user/_index.md @@ -0,0 +1,12 @@ +--- +aliases: + - /zh/docs3-v2/dubbo-go-pixiu/user/ + - /zh-cn/docs3-v2/dubbo-go-pixiu/user/ + - /zh-cn/overview/reference/pixiu/user/ + - /zh-cn/overview/mannual/dubbo-go-pixiu/user/ +description: 用户文档 +linkTitle: 用户文档 +title: 用户文档 +type: docs +weight: 20 +--- diff --git a/content/zh-cn/overview/reference/pixiu/user/adapter/_index.md b/content/zh-cn/overview/reference/pixiu/user/adapter/_index.md new file mode 100755 index 000000000000..c66262d179c9 --- /dev/null +++ b/content/zh-cn/overview/reference/pixiu/user/adapter/_index.md @@ -0,0 +1,12 @@ +--- +aliases: + - /zh/docs3-v2/dubbo-go-pixiu/user/adapter/ + - /zh-cn/docs3-v2/dubbo-go-pixiu/user/adapter/ + - /zh-cn/overview/reference/pixiu/user/adapter/ + - /zh-cn/overview/mannual/dubbo-go-pixiu/user/adapter/ +description: Adapter 介绍 +linkTitle: Adapter 介绍 +title: Adapter 介绍 +type: docs +weight: 60 +--- diff --git a/content/zh-cn/overview/reference/pixiu/user/adapter/dubbo.md b/content/zh-cn/overview/reference/pixiu/user/adapter/dubbo.md new file mode 100644 index 000000000000..56d634d99ea1 --- /dev/null +++ b/content/zh-cn/overview/reference/pixiu/user/adapter/dubbo.md @@ -0,0 +1,12 @@ +--- +aliases: + - /zh/docs3-v2/dubbo-go-pixiu/user/adapter/dubbo/ + - /zh-cn/docs3-v2/dubbo-go-pixiu/user/adapter/dubbo/ + - /zh-cn/overview/reference/pixiu/user/adapter/dubbo/ + - /zh-cn/overview/mannual/dubbo-go-pixiu/user/adapter/dubbo/ +description: Dubbo 集群中心 Adapter +linkTitle: Dubbo 集群中心 Adapter +title: Dubbo 集群中心 Adapter +type: docs +weight: 10 +--- diff --git a/content/zh-cn/overview/reference/pixiu/user/adapter/springcloud.md b/content/zh-cn/overview/reference/pixiu/user/adapter/springcloud.md new file mode 100644 index 000000000000..01339a53be88 --- /dev/null +++ b/content/zh-cn/overview/reference/pixiu/user/adapter/springcloud.md @@ -0,0 +1,12 @@ +--- +aliases: + - /zh/docs3-v2/dubbo-go-pixiu/user/adapter/springcloud/ + - /zh-cn/docs3-v2/dubbo-go-pixiu/user/adapter/springcloud/ + - /zh-cn/overview/reference/pixiu/user/adapter/springcloud/ + - /zh-cn/overview/mannual/dubbo-go-pixiu/user/adapter/springcloud/ +description: Spring Cloud 集群中心 Adapter +linkTitle: Spring Cloud 集群中心 Adapter +title: Spring Cloud 集群中心 Adapter +type: docs +weight: 20 +--- diff --git a/content/zh-cn/overview/reference/pixiu/user/appendix/_index.md b/content/zh-cn/overview/reference/pixiu/user/appendix/_index.md new file mode 100755 index 000000000000..879e2baf0d11 --- /dev/null +++ b/content/zh-cn/overview/reference/pixiu/user/appendix/_index.md @@ -0,0 +1,12 @@ +--- +aliases: + - /zh/docs3-v2/dubbo-go-pixiu/user/appendix/ + - /zh-cn/docs3-v2/dubbo-go-pixiu/user/appendix/ + - /zh-cn/overview/reference/pixiu/user/appendix/ + - /zh-cn/overview/mannual/dubbo-go-pixiu/user/appendix/ +description: 附录 +linkTitle: 附录 +title: 附录 +type: docs +weight: 90 +--- diff --git a/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/appendix/http-to-dubbo-default-stragety.md b/content/zh-cn/overview/reference/pixiu/user/appendix/http-to-dubbo-default-stragety.md similarity index 98% rename from content/zh-cn/overview/mannual/dubbo-go-pixiu/user/appendix/http-to-dubbo-default-stragety.md rename to content/zh-cn/overview/reference/pixiu/user/appendix/http-to-dubbo-default-stragety.md index 1c4e499619b4..e5c287f9f4df 100644 --- a/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/appendix/http-to-dubbo-default-stragety.md +++ b/content/zh-cn/overview/reference/pixiu/user/appendix/http-to-dubbo-default-stragety.md @@ -2,6 +2,8 @@ aliases: - /zh/docs3-v2/dubbo-go-pixiu/user/appendix/http-to-dubbo-default-stragety/ - /zh-cn/docs3-v2/dubbo-go-pixiu/user/appendix/http-to-dubbo-default-stragety/ + - /zh-cn/overview/reference/pixiu/user/appendix/http-to-dubbo-default-stragety/ + - /zh-cn/overview/mannual/dubbo-go-pixiu/user/appendix/http-to-dubbo-default-stragety/ description: HTTP to Dubbo 默认转换协议 linkTitle: HTTP to Dubbo 默认转换协议 title: HTTP to Dubbo 默认转换协议 @@ -322,4 +324,4 @@ Triple协议将请求参数放在Body中,在triple中,如果服务中的方 | --------- | ---- | ---------------------------- | | 400 | 3 | argument type info not found | -### \ No newline at end of file +### diff --git a/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/configurations.md b/content/zh-cn/overview/reference/pixiu/user/configurations.md similarity index 97% rename from content/zh-cn/overview/mannual/dubbo-go-pixiu/user/configurations.md rename to content/zh-cn/overview/reference/pixiu/user/configurations.md index b1996999e9fc..3511e79939ca 100755 --- a/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/configurations.md +++ b/content/zh-cn/overview/reference/pixiu/user/configurations.md @@ -2,6 +2,8 @@ aliases: - /zh/docs3-v2/dubbo-go-pixiu/user/configurations/ - /zh-cn/docs3-v2/dubbo-go-pixiu/user/configurations/ + - /zh-cn/overview/reference/pixiu/user/configurations/ + - /zh-cn/overview/mannual/dubbo-go-pixiu/user/configurations/ description: 启动和配置 linkTitle: 启动和配置 title: 启动和配置 @@ -155,4 +157,4 @@ route 可以用于对请求进行路由分发,以下面配置为例。具体 Adapter 代表 Pixiu 和外界元数据中心交互的能力。目前有两款,分别是 `dgp.adapter.dubboregistrycenter` 和 `dgp.adapter.springcloud`,分别代表从 Dubbo 集群注册中心和 Spring Cloud 集群注册中心获取服务实例信息,构建 Pixiu 转发 Http 请求路由规则的。 -更多的 Adapter 可以查看 [Adapter文档](../adapter/dubbo/)。 \ No newline at end of file +更多的 Adapter 可以查看 [Adapter文档](../adapter/dubbo/)。 diff --git a/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/deployment.md b/content/zh-cn/overview/reference/pixiu/user/deployment.md similarity index 93% rename from content/zh-cn/overview/mannual/dubbo-go-pixiu/user/deployment.md rename to content/zh-cn/overview/reference/pixiu/user/deployment.md index 86095a98ad8c..63bd461fa135 100644 --- a/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/deployment.md +++ b/content/zh-cn/overview/reference/pixiu/user/deployment.md @@ -2,6 +2,8 @@ aliases: - /zh/docs3-v2/dubbo-go-pixiu/user/deployment/ - /zh-cn/docs3-v2/dubbo-go-pixiu/user/deployment/ + - /zh-cn/overview/reference/pixiu/user/deployment/ + - /zh-cn/overview/mannual/dubbo-go-pixiu/user/deployment/ description: 部署操作 linkTitle: 部署操作 title: 部署操作 @@ -85,4 +87,4 @@ docker run -itd --name dubbo-go-pixiu -p 8883:8883 \ 在当前目录下`make run` 可根据你当前的配置直接启动pixiu服务 -[运行示例参考](../quickstart/) \ No newline at end of file +[运行示例参考](../quickstart/) diff --git a/content/zh-cn/overview/reference/pixiu/user/httpfilter/_index.md b/content/zh-cn/overview/reference/pixiu/user/httpfilter/_index.md new file mode 100755 index 000000000000..78dbdb9e5dc5 --- /dev/null +++ b/content/zh-cn/overview/reference/pixiu/user/httpfilter/_index.md @@ -0,0 +1,12 @@ +--- +aliases: + - /zh/docs3-v2/dubbo-go-pixiu/user/httpfilter/ + - /zh-cn/docs3-v2/dubbo-go-pixiu/user/httpfilter/ + - /zh-cn/overview/reference/pixiu/user/httpfilter/ + - /zh-cn/overview/mannual/dubbo-go-pixiu/user/httpfilter/ +description: Http Filter 介绍 +linkTitle: Http Filter 介绍 +title: Http Filter 介绍 +type: docs +weight: 60 +--- diff --git a/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/httpfilter/dubbo.md b/content/zh-cn/overview/reference/pixiu/user/httpfilter/dubbo.md similarity index 100% rename from content/zh-cn/overview/mannual/dubbo-go-pixiu/user/httpfilter/dubbo.md rename to content/zh-cn/overview/reference/pixiu/user/httpfilter/dubbo.md diff --git a/content/zh-cn/overview/reference/pixiu/user/httpfilter/hystrix.md b/content/zh-cn/overview/reference/pixiu/user/httpfilter/hystrix.md new file mode 100644 index 000000000000..d848ed81f9c4 --- /dev/null +++ b/content/zh-cn/overview/reference/pixiu/user/httpfilter/hystrix.md @@ -0,0 +1,19 @@ +--- +aliases: + - /zh/docs3-v2/dubbo-go-pixiu/user/httpfilter/hystrix/ + - /zh-cn/docs3-v2/dubbo-go-pixiu/user/httpfilter/hystrix/ + - /zh-cn/overview/reference/pixiu/user/httpfilter/hystrix/ + - /zh-cn/overview/mannual/dubbo-go-pixiu/user/httpfilter/hystrix/ +description: 断路器介绍 +linkTitle: 断路器介绍 +title: 断路器介绍 +type: docs +weight: 30 +--- + + + + + + +欢迎认领补充此文档。 diff --git a/content/zh-cn/overview/reference/pixiu/user/httpfilter/ratelimit.md b/content/zh-cn/overview/reference/pixiu/user/httpfilter/ratelimit.md new file mode 100644 index 000000000000..892c72457141 --- /dev/null +++ b/content/zh-cn/overview/reference/pixiu/user/httpfilter/ratelimit.md @@ -0,0 +1,19 @@ +--- +aliases: + - /zh/docs3-v2/dubbo-go-pixiu/user/httpfilter/ratelimit/ + - /zh-cn/docs3-v2/dubbo-go-pixiu/user/httpfilter/ratelimit/ + - /zh-cn/overview/reference/pixiu/user/httpfilter/ratelimit/ + - /zh-cn/overview/mannual/dubbo-go-pixiu/user/httpfilter/ratelimit/ +description: RateLimiter 介绍 +linkTitle: RateLimiter 介绍 +title: RateLimiter 介绍 +type: docs +weight: 20 +--- + + + + + + +欢迎认领补充此文档。 diff --git a/content/zh-cn/overview/reference/pixiu/user/listener/_index.md b/content/zh-cn/overview/reference/pixiu/user/listener/_index.md new file mode 100755 index 000000000000..43ebd115e266 --- /dev/null +++ b/content/zh-cn/overview/reference/pixiu/user/listener/_index.md @@ -0,0 +1,12 @@ +--- +aliases: + - /zh/docs3-v2/dubbo-go-pixiu/user/listener/ + - /zh-cn/docs3-v2/dubbo-go-pixiu/user/listener/ + - /zh-cn/overview/reference/pixiu/user/listener/ + - /zh-cn/overview/mannual/dubbo-go-pixiu/user/listener/ +description: Listener 介绍 +linkTitle: Listener 介绍 +title: Listener 介绍 +type: docs +weight: 40 +--- diff --git a/content/zh-cn/overview/reference/pixiu/user/listener/http.md b/content/zh-cn/overview/reference/pixiu/user/listener/http.md new file mode 100644 index 000000000000..8b4b6c1f9dec --- /dev/null +++ b/content/zh-cn/overview/reference/pixiu/user/listener/http.md @@ -0,0 +1,53 @@ +--- +aliases: + - /zh/docs3-v2/dubbo-go-pixiu/user/listener/http/ + - /zh-cn/docs3-v2/dubbo-go-pixiu/user/listener/http/ + - /zh-cn/overview/reference/pixiu/user/listener/http/ + - /zh-cn/overview/mannual/dubbo-go-pixiu/user/listener/http/ +description: Http Listener 介绍 +linkTitle: Http Listener 介绍 +title: Http Listener 介绍 +type: docs +weight: 10 +--- + + + + + + +Http Listener 是专门负载接收 HTTP 请求的 Listener,它可以设置 HTTP 监听的地址和端口。它可以通过如下配置进行引入。 + +``` +static_resources: + listeners: + - name: "net/http" + protocol_type: "HTTP" # 表明是引入 HTTP Listener + address: + socket_address: + address: "0.0.0.0" # 地址 + port: 8883 # 端口 +``` + +Http Listener 的具体实现可以参考 `pkg/listener/http`。 + +有关 HTTP Listener 的案例,可以参考: +- HTTP to Dubbo 请求的转换,[案例](/zh-cn/overview/mannual/dubbo-go-pixiu/user/samples/http_to_dubbo/) +- HTTP 请求代理,[案例](/zh-cn/overview/mannual/dubbo-go-pixiu/user/samples/http_proxy/) + +目前也支持 HTTPS 协议。可以将 `protocol_type` 修改为 `HTTPS`。并且添加 `domains` 和 `certs_dir` 来指定域名和 cert 文件目录。 + +``` + listeners: + - name: "net/http" + protocol_type: "HTTPS" + address: + socket_address: + domains: + - "sample.domain.com" + - "sample.domain-1.com" + - "sample.domain-2.com" + certs_dir: $PROJECT_DIR/cert +``` + +具体案例可以查看 [案例](/zh-cn/overview/mannual/dubbo-go-pixiu/user/samples/https/) diff --git a/content/zh-cn/overview/reference/pixiu/user/listener/http2.md b/content/zh-cn/overview/reference/pixiu/user/listener/http2.md new file mode 100644 index 000000000000..24ed858fbbde --- /dev/null +++ b/content/zh-cn/overview/reference/pixiu/user/listener/http2.md @@ -0,0 +1,19 @@ +--- +aliases: + - /zh/docs3-v2/dubbo-go-pixiu/user/listener/http2/ + - /zh-cn/docs3-v2/dubbo-go-pixiu/user/listener/http2/ + - /zh-cn/overview/reference/pixiu/user/listener/http2/ + - /zh-cn/overview/mannual/dubbo-go-pixiu/user/listener/http2/ +description: Http2 Listener 介绍 +linkTitle: Http2 Listener 介绍 +title: Http2 Listener 介绍 +type: docs +weight: 20 +--- + + + + + + +欢迎认领补充此文档。 diff --git a/content/zh-cn/overview/reference/pixiu/user/listener/tcp.md b/content/zh-cn/overview/reference/pixiu/user/listener/tcp.md new file mode 100644 index 000000000000..fafe5f2d607b --- /dev/null +++ b/content/zh-cn/overview/reference/pixiu/user/listener/tcp.md @@ -0,0 +1,19 @@ +--- +aliases: + - /zh/docs3-v2/dubbo-go-pixiu/user/listener/tcp/ + - /zh-cn/docs3-v2/dubbo-go-pixiu/user/listener/tcp/ + - /zh-cn/overview/reference/pixiu/user/listener/tcp/ + - /zh-cn/overview/mannual/dubbo-go-pixiu/user/listener/tcp/ +description: TCP Listener 介绍 +linkTitle: TCP Listener 介绍 +title: TCP Listener 介绍 +type: docs +weight: 30 +--- + + + + + + +欢迎认领补充此文档。 diff --git a/content/zh-cn/overview/reference/pixiu/user/listener/triple.md b/content/zh-cn/overview/reference/pixiu/user/listener/triple.md new file mode 100644 index 000000000000..5d50b9d5dacb --- /dev/null +++ b/content/zh-cn/overview/reference/pixiu/user/listener/triple.md @@ -0,0 +1,19 @@ +--- +aliases: + - /zh/docs3-v2/dubbo-go-pixiu/user/listener/triple/ + - /zh-cn/docs3-v2/dubbo-go-pixiu/user/listener/triple/ + - /zh-cn/overview/reference/pixiu/user/listener/triple/ + - /zh-cn/overview/mannual/dubbo-go-pixiu/user/listener/triple/ +description: Triple Listener 介绍 +linkTitle: Triple Listener 介绍 +title: Triple Listener 介绍 +type: docs +weight: 40 +--- + + + + + + +欢迎认领补充此文档。 diff --git a/content/zh-cn/overview/reference/pixiu/user/networkfilter/_index.md b/content/zh-cn/overview/reference/pixiu/user/networkfilter/_index.md new file mode 100755 index 000000000000..76d329902d2b --- /dev/null +++ b/content/zh-cn/overview/reference/pixiu/user/networkfilter/_index.md @@ -0,0 +1,12 @@ +--- +aliases: + - /zh/docs3-v2/dubbo-go-pixiu/user/networkfilter/ + - /zh-cn/docs3-v2/dubbo-go-pixiu/user/networkfilter/ + - /zh-cn/overview/reference/pixiu/user/networkfilter/ + - /zh-cn/overview/mannual/dubbo-go-pixiu/user/networkfilter/ +description: Network Filter 介绍 +linkTitle: Network Filter 介绍 +title: Network Filter 介绍 +type: docs +weight: 50 +--- diff --git a/content/zh-cn/overview/reference/pixiu/user/networkfilter/dubbo.md b/content/zh-cn/overview/reference/pixiu/user/networkfilter/dubbo.md new file mode 100644 index 000000000000..74f000bdf9c4 --- /dev/null +++ b/content/zh-cn/overview/reference/pixiu/user/networkfilter/dubbo.md @@ -0,0 +1,19 @@ +--- +aliases: + - /zh/docs3-v2/dubbo-go-pixiu/user/networkfilter/dubbo/ + - /zh-cn/docs3-v2/dubbo-go-pixiu/user/networkfilter/dubbo/ + - /zh-cn/overview/reference/pixiu/user/networkfilter/dubbo/ + - /zh-cn/overview/mannual/dubbo-go-pixiu/user/networkfilter/dubbo/ +description: Dubbo NetWorkFilter 介绍 +linkTitle: Dubbo NetWorkFilter 介绍 +title: Dubbo NetWorkFilter 介绍 +type: docs +weight: 30 +--- + + + + + + +欢迎认领补充此文档。 diff --git a/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/networkfilter/grpc.md b/content/zh-cn/overview/reference/pixiu/user/networkfilter/grpc.md similarity index 100% rename from content/zh-cn/overview/mannual/dubbo-go-pixiu/user/networkfilter/grpc.md rename to content/zh-cn/overview/reference/pixiu/user/networkfilter/grpc.md diff --git a/content/zh-cn/overview/reference/pixiu/user/networkfilter/http.md b/content/zh-cn/overview/reference/pixiu/user/networkfilter/http.md new file mode 100644 index 000000000000..5a03965f9a71 --- /dev/null +++ b/content/zh-cn/overview/reference/pixiu/user/networkfilter/http.md @@ -0,0 +1,19 @@ +--- +aliases: + - /zh/docs3-v2/dubbo-go-pixiu/user/networkfilter/http/ + - /zh-cn/docs3-v2/dubbo-go-pixiu/user/networkfilter/http/ + - /zh-cn/overview/reference/pixiu/user/networkfilter/http/ + - /zh-cn/overview/mannual/dubbo-go-pixiu/user/networkfilter/http/ +description: Http NetWorkFilter 介绍 +linkTitle: Http NetWorkFilter 介绍 +title: Http NetWorkFilter 介绍 +type: docs +weight: 10 +--- + + + + + + +Http NetWorkFilter 用来处理 HTTP 请求,它能接收来自 HTTP Listener 传递的 HTTP 请求,然后将其交给自身维护的 HTTP Filter 链进行处理,最后将响应返回给调用方。 diff --git a/content/zh-cn/overview/reference/pixiu/user/quality/_index.md b/content/zh-cn/overview/reference/pixiu/user/quality/_index.md new file mode 100755 index 000000000000..b296bad52f99 --- /dev/null +++ b/content/zh-cn/overview/reference/pixiu/user/quality/_index.md @@ -0,0 +1,12 @@ +--- +aliases: + - /zh/docs3-v2/dubbo-go-pixiu/user/quality/ + - /zh-cn/docs3-v2/dubbo-go-pixiu/user/quality/ + - /zh-cn/overview/reference/pixiu/user/quality/ + - /zh-cn/overview/mannual/dubbo-go-pixiu/user/quality/ +description: 质量指标 +linkTitle: 质量指标 +title: 质量指标 +type: docs +weight: 80 +--- diff --git a/content/zh-cn/overview/reference/pixiu/user/quality/performance.md b/content/zh-cn/overview/reference/pixiu/user/quality/performance.md new file mode 100755 index 000000000000..13633e789fb1 --- /dev/null +++ b/content/zh-cn/overview/reference/pixiu/user/quality/performance.md @@ -0,0 +1,19 @@ +--- +aliases: + - /zh/docs3-v2/dubbo-go-pixiu/user/quality/performance/ + - /zh-cn/docs3-v2/dubbo-go-pixiu/user/quality/performance/ + - /zh-cn/overview/reference/pixiu/user/quality/stability/ + - /zh-cn/overview/mannual/dubbo-go-pixiu/user/quality/stability/ +description: 性能 +linkTitle: 性能 +title: 性能 +type: docs +weight: 10 +--- + + + + + + +欢迎认领补充此文档。 diff --git a/content/zh-cn/overview/reference/pixiu/user/quality/stability.md b/content/zh-cn/overview/reference/pixiu/user/quality/stability.md new file mode 100644 index 000000000000..0da92f432ee0 --- /dev/null +++ b/content/zh-cn/overview/reference/pixiu/user/quality/stability.md @@ -0,0 +1,19 @@ +--- +aliases: + - /zh/docs3-v2/dubbo-go-pixiu/user/quality/stability/ + - /zh-cn/docs3-v2/dubbo-go-pixiu/user/quality/stability/ + - /zh-cn/overview/reference/pixiu/user/quality/stability/ + - /zh-cn/overview/mannual/dubbo-go-pixiu/user/quality/stability/ +description: 稳定性 +linkTitle: 稳定性 +title: 稳定性 +type: docs +weight: 10 +--- + + + + + + +欢迎认领补充此文档。 diff --git a/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/quickstart.md b/content/zh-cn/overview/reference/pixiu/user/quickstart.md similarity index 95% rename from content/zh-cn/overview/mannual/dubbo-go-pixiu/user/quickstart.md rename to content/zh-cn/overview/reference/pixiu/user/quickstart.md index 02219dd02a37..8f89a64b01a6 100755 --- a/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/quickstart.md +++ b/content/zh-cn/overview/reference/pixiu/user/quickstart.md @@ -1,7 +1,9 @@ --- aliases: - - /zh/docs3-v2/dubbo-go-pixiu/user/quickstart/ - - /zh-cn/docs3-v2/dubbo-go-pixiu/user/quickstart/ + - /zh/docs3-v2/dubbo-go-pixiu/user/quickstart/ + - /zh-cn/docs3-v2/dubbo-go-pixiu/user/quickstart/ + - /zh-cn/overview/reference/pixiu/user/quickstart/ + - /zh-cn/overview/mannual/dubbo-go-pixiu/user/quickstart/ description: 快速开始 linkTitle: 快速开始 title: 快速开始 diff --git a/content/zh-cn/overview/reference/pixiu/user/samples/_index.md b/content/zh-cn/overview/reference/pixiu/user/samples/_index.md new file mode 100755 index 000000000000..29f0f01d1015 --- /dev/null +++ b/content/zh-cn/overview/reference/pixiu/user/samples/_index.md @@ -0,0 +1,12 @@ +--- +aliases: + - /zh/docs3-v2/dubbo-go-pixiu/user/samples/ + - /zh-cn/docs3-v2/dubbo-go-pixiu/user/samples/ + - /zh-cn/overview/reference/pixiu/user/samples/ + - /zh-cn/overview/mannual/dubbo-go-pixiu/user/samples/ +description: 案例介绍 +linkTitle: 案例介绍 +title: 案例介绍 +type: docs +weight: 70 +--- diff --git a/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/samples/http_proxy.md b/content/zh-cn/overview/reference/pixiu/user/samples/http_proxy.md similarity index 94% rename from content/zh-cn/overview/mannual/dubbo-go-pixiu/user/samples/http_proxy.md rename to content/zh-cn/overview/reference/pixiu/user/samples/http_proxy.md index 5f9d091c1a47..312762bb7dfe 100644 --- a/content/zh-cn/overview/mannual/dubbo-go-pixiu/user/samples/http_proxy.md +++ b/content/zh-cn/overview/reference/pixiu/user/samples/http_proxy.md @@ -2,6 +2,8 @@ aliases: - /zh/docs3-v2/dubbo-go-pixiu/user/samples/http_proxy/ - /zh-cn/docs3-v2/dubbo-go-pixiu/user/samples/http_proxy/ + - /zh-cn/overview/reference/pixiu/user/samples/http_proxy/ + - /zh-cn/overview/mannual/dubbo-go-pixiu/user/samples/http_proxy/ description: Http Proxy 案例介绍 linkTitle: Http Proxy 案例介绍 title: Http Proxy 案例介绍 @@ -70,4 +72,4 @@ static_resources: ``` pixiu gateway start -c /pixiu/conf.yaml -``` \ No newline at end of file +``` diff --git a/content/zh-cn/overview/reference/pixiu/user/samples/http_to_dubbo.md b/content/zh-cn/overview/reference/pixiu/user/samples/http_to_dubbo.md new file mode 100644 index 000000000000..bf3ba20048ca --- /dev/null +++ b/content/zh-cn/overview/reference/pixiu/user/samples/http_to_dubbo.md @@ -0,0 +1,19 @@ +--- +aliases: + - /zh/docs3-v2/dubbo-go-pixiu/user/samples/http_to_dubbo/ + - /zh-cn/docs3-v2/dubbo-go-pixiu/user/samples/http_to_dubbo/ + - /zh-cn/overview/reference/pixiu/user/samples/http_to_dubbo/ + - /zh-cn/overview/mannual/dubbo-go-pixiu/user/samples/http_to_dubbo/ +description: Http to Dubbo 案例介绍 +linkTitle: Http to Dubbo 案例介绍 +title: Http to Dubbo 案例介绍 +type: docs +weight: 20 +--- + + + + + + +欢迎认领补充此文档。 diff --git a/content/zh-cn/overview/reference/pixiu/user/samples/https.md b/content/zh-cn/overview/reference/pixiu/user/samples/https.md new file mode 100644 index 000000000000..2caa4212b7ea --- /dev/null +++ b/content/zh-cn/overview/reference/pixiu/user/samples/https.md @@ -0,0 +1,19 @@ +--- +aliases: + - /zh/docs3-v2/dubbo-go-pixiu/user/samples/https/ + - /zh-cn/docs3-v2/dubbo-go-pixiu/user/samples/https/ + - /zh-cn/overview/reference/pixiu/user/samples/https/ + - /zh-cn/overview/mannual/dubbo-go-pixiu/user/samples/https/ +description: Https 案例介绍 +linkTitle: Https 案例介绍 +title: Https 案例介绍 +type: docs +weight: 30 +--- + + + + + + +欢迎认领补充此文档。 diff --git a/content/zh-cn/overview/reference/protoc-installation.md b/content/zh-cn/overview/reference/protoc-installation.md new file mode 100644 index 000000000000..c06bd064ef81 --- /dev/null +++ b/content/zh-cn/overview/reference/protoc-installation.md @@ -0,0 +1,73 @@ +--- +title: 如何安装 Protocol Buffer Compiler +linkTitle: Protoc安装 +description: 如何安装 protocol buffer 编译器。 +protoc-version: 3.15.8 +toc_hide: true +type: docs +--- + +虽然不是强制性的,但 Apache Dubbo 支持使用 [Protocol Buffers (proto3版本)](https://protobuf.dev/programming-guides/proto3) 作为服务定义和序列化协议。 + +在 Protocol buffer 体系下,我们使用 `.proto` 文件定义服务和消息体格式,使用 `protoc` 编译器编译 `.proto` 文件,你可以使用以下几种方式安装 `protoc`。 + +### 使用包管理器安装 + +在 Linux 或 macOS 环境下,你可以使用包管理器安装 `protoc`。 + +{{% alert title="Warning" color="warning" %}} +**一定要注意检查所安装 `protoc` 的版本!** 检查方法如下文说述,因为有时一些包管理器安装的 `protoc` 版本是严重过时的。 + +下一节所展示的 [使用预先编译好的二进制文件安装](#binary-install) 可以确保你安装正确的 `protoc` 版本。 +{{% /alert %}} + +- Linux,使用 `apt` 或者 `apt-get`,比如: + + ```sh + $ apt install -y protobuf-compiler + $ protoc --version # Ensure compiler version is 3+ + ``` + +- MacOS,使用 [Homebrew](https://brew.sh): + + ```sh + $ brew install protobuf + $ protoc --version # Ensure compiler version is 3+ + ``` + + + +### 使用预先编译好的二进制文件安装(适用任何操作系统) + +参考以下步骤安装 [最新版本](https://protobuf.dev/downloads#release-packages) 的 protoc 二进制包: + + 1. 根据你的操作系统类型,手动下载 [github.com/google/protobuf/releases](https://github.com/google/protobuf/releases) 二进制文件 + (`protoc---.zip`),你也可以使用以下命令直接下载: + + ```sh + $ PB_REL="https://github.com/protocolbuffers/protobuf/releases" + $ curl -LO $PB_REL/download/v{{< param protoc-version >}}/protoc-{{< param protoc-version >}}-linux-x86_64.zip + ``` + + 2. 将文件解压到`$HOME/.local` 目录,或者任意你想要的目录也可以。比如: + + ```sh + $ unzip protoc-{{< param protoc-version >}}-linux-x86_64.zip -d $HOME/.local + ``` + + 3. 修改系统 `PATH` 路径,将 `protoc` 加入可执行文件路径。比如: + + ```sh + $ export PATH="$PATH:$HOME/.local/bin" + ``` + +### 其他安装方法 + +如果你想要自行编译源码安装,或者想要安装老版本的二进制包。请参考 [下载 Protocol Buffers](https://protobuf.dev/downloads) + +[download]: https://protobuf.dev/downloads +[github.com/google/protobuf/releases]: https://github.com/google/protobuf/releases +[Homebrew]: https://brew.sh +[latest release]: https://protobuf.dev/downloads#release-packages +[pb]: https://developers.google.com/protocol-buffers +[proto3]: https://protobuf.dev/programming-guides/proto3 diff --git a/content/zh-cn/overview/reference/protocols/http.md b/content/zh-cn/overview/reference/protocols/http.md index 0da4d7b29d09..2c1c5b24b78d 100644 --- a/content/zh-cn/overview/reference/protocols/http.md +++ b/content/zh-cn/overview/reference/protocols/http.md @@ -7,6 +7,10 @@ weight: 3 working_in_progress: true --- +{{% alert title="注意" color="warning" %}} +从 Dubbo 3.3 版本开始,Rest 协议已移至 Extensions 库,由 Triple 协议来对 Rest 提供更全面的支持,具体参见 [Triple Rest用户手册](../../../mannual/java-sdk/reference-manual/protocol/tripe-rest-manual/), +如需继续使用原 Rest 协议,可引入对应 [dubbo-spi-extensions](https://github.com/apache/dubbo-spi-extensions/tree/master/dubbo-rpc-extensions/dubbo-rpc-rest) 库依赖 +{{% /alert %}} ## 什么是 Dubbo Http 基于 spring web 和 resteasy 注解编码风格,通过http协议进行服务间调用互通,dubbo protocol扩展实现的协议 diff --git a/content/zh-cn/overview/tasks/_index.md b/content/zh-cn/overview/tasks/_index.md deleted file mode 100755 index 2af26da6ba55..000000000000 --- a/content/zh-cn/overview/tasks/_index.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -aliases: - - /zh/overview/tasks/ -description: "" -linkTitle: 任务 -title: 跟随示例任务学习 Dubbo -type: docs -weight: 5 ---- diff --git a/content/zh-cn/overview/tasks/deploy/_index.md b/content/zh-cn/overview/tasks/deploy/_index.md deleted file mode 100644 index f97928ff99e9..000000000000 --- a/content/zh-cn/overview/tasks/deploy/_index.md +++ /dev/null @@ -1,66 +0,0 @@ ---- -aliases: - - /zh/overview/tasks/deploy/ -description: 部署 Dubbo 应用 -feature: - description: | - 一键拉起服务治理体系,屏蔽底层跨平台的微服务基础设施复杂度,支持虚拟机、Docker、Kubernetes、服务网格等多种部署模式。 - title: 灵活部署模式 -linkTitle: 部署服务 -no_list: true -title: 部署服务 -type: docs -weight: 2 ---- - - - -{{< blocks/section color="white" height="auto">}} -
-
-
-
-
-

- 虚拟机环境部署 -

-

部署在虚拟机环境

-
-
-
-
-
-
-

- Docker 部署 -

-

部署在 docker 环境

-
-
-
-
-
-
-

- Kubernetes + Docker 部署 -

-

部署在 docker 环境的 kubernetes

-
-
-
-
-
-
-

- Kubernetes + Containerd 部署 -

-

部署在 containerd 环境的 kubernetes

-
-
-
-
-
-
- -{{< /blocks/section >}} diff --git a/content/zh-cn/overview/tasks/deploy/deploy-on-docker.md b/content/zh-cn/overview/tasks/deploy/deploy-on-docker.md deleted file mode 100644 index 5ce41feb80c3..000000000000 --- a/content/zh-cn/overview/tasks/deploy/deploy-on-docker.md +++ /dev/null @@ -1,221 +0,0 @@ ---- -aliases: - - /zh/overview/tasks/deploy/deploy-on-docker/ -description: 部署 Dubbo 应用到 Docker 示例 -linkTitle: 部署到 Docker -title: 部署 Dubbo 应用到 Docker 环境 -type: docs -weight: 2 ---- - - -## 总体目标 - -- 部署 [Docker](https://docs.docker.com/engine/install/) -- 部署 Zookeeper -- 部署 Dubbo-admin + Zookeeper -- 部署 Producer + Zookeeper 与 Consumer + Zookeeper - -## 基本流程与工作原理 - -![img](/imgs/v3/tasks/deploy/docker.jpg) - -## 详细步骤 - -### zookeeper - -下载项目到本地 -``` -wget https://dlcdn.apache.org/zookeeper/zookeeper-x.x.x/apache-zookeeper-x.x.x-bin.tar.gz -``` -> apache-zookeeper-x.x.x.tar.gz 为未编译版本, 自 3.5.5 版本以后,已编译的 jar 包后缀 `-bin`,请使用 apache-zookeeper-x.x.x-bin.tar.gz - -解压项目到本地 -``` -tar zxvf apache-zookeeper-x.x.x-bin.tar.gz -C /usr/local/ && cd /usr/local -``` -移动项目修改为 zookeeper 并切换至 zookeeper -``` -mv apache-zookeeper-x.x.x-bin zookeeper && cd zookeeper -``` - -创建目录并切换此目录导入内容 -``` -mkdir -p /usr/local/docker/zookeeper/data && cd /usr/local/docker/zookeeper/data && echo 1 > myid -``` - -拉取 zookeeper -``` -docker pull zookeeper -``` - -运行 zookeeper -``` -docker run -p 2181:2181 -p 2888:2888 -p 3888:3888 -v /usr/local/docker/zookeeper/data:/data/ --name zookeeper --restart always -d zookeeper -``` - -测试 zookeeper -``` -docker run -it --rm --link zookeeper:zookeeper zookeeper zkCli.sh -server zookeeper -``` - -### dubbo-admin - -下载项目到本地 -``` -git clone https://github.com/apache/dubbo-admin.git && cd dubbo-admin -``` - -配置 -``` -# dubbo-admin-server/src/main/resources/application.properties -server.port=38080 -dubbo.protocol.port=30880 -dubbo.application.qos-port=32222 - -admin.registry.address=zookeeper://:2181 -admin.config-center=zookeeper://:2181 -admin.metadata-report.address=zookeeper://:2181 - -admin.root.user.name=root -admin.root.user.password=root -``` - -``` -docker run -it --rm -v /the/host/path/containing/properties:/config -p 38080:38080 apache/dubbo-admin -``` -> 将 /the/host/path/containing/properties 替换为宿主机上包含 application.properties 文件的实际路径(必须是一个有效目录的绝对路径)。 - -进入服务 -``` -http://:38080 -``` - -登录页面 -![img](/imgs/v3/tasks/deploy/dubbo-admin-login.jpg) - -服务查询 -![img](/imgs/v3/tasks/deploy/dubbo-admin-page.jpg) - -### dubbo - -下载项目到本地 -``` -git clone https://github.com/apache/dubbo-samples.git && cd dubbo-samples/1-basic/dubbo-samples-spring-boot -``` - -修改 Provider 的 zookeeper 地址 -``` -# dubbo-samples-spring-boot-provider/src/main/resources/application.yml -dubbo: - application: - name: dubbo-springboot-demo-provider - protocol: - name: dubbo - port: -1 - registry: - id: zk-registry - address: zookeeper://:2181 - config-center: - address: zookeeper://:2181 - metadata-report: - address: zookeeper://:2181 -``` - -修改 Consumer 的 zookeeper 地址 -``` -# dubbo-samples-spring-boot-consumer/src/main/resources/application.yml -dubbo: - application: - name: dubbo-springboot-demo-consumer - protocol: - name: dubbo - port: -1 - registry: - id: zk-registry - address: zookeeper://:2181 - config-center: - address: zookeeper://:2181 - metadata-report: - address: zookeeper://:2181 -``` - -切换到服务示例 -``` -cd && cd dubbo-samples/1-basic/dubbo-samples-spring-boot -``` - -打包编译 -``` -mvn clean package -``` -``` -[INFO] ------------------------------------------------------------------------ -[INFO] Reactor Summary: -[INFO] -[INFO] Dubbo Samples Spring Boot 1.0-SNAPSHOT ............. SUCCESS [ 8.147 s] -[INFO] dubbo-samples-spring-boot-interface ................ SUCCESS [ 51.524 s] -[INFO] dubbo-samples-spring-boot-provider ................. SUCCESS [02:27 min] -[INFO] dubbo-samples-spring-boot-consumer 1.0-SNAPSHOT .... SUCCESS [ 0.284 s] -[INFO] ------------------------------------------------------------------------ -[INFO] BUILD SUCCESS -[INFO] ------------------------------------------------------------------------ -[INFO] Total time: 03:49 min -[INFO] Finished at: 2023-01-16T09:34:39-05:00 -[INFO] ------------------------------------------------------------------------ -``` - -#### Producer - -切换至目标服务 -``` -cd dubbo-samples-spring-boot-provider/target -``` - -构建镜像 -``` -cat < Dockerfile -FROM openjdk:8-jdk-alpine -ADD dubbo-samples-spring-boot-provider-1.0-SNAPSHOT.jar /app.jar -ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/urandom", "-jar", "/app.jar"] -EOF -``` - -编译镜像 -``` -docker build --no-cache -t dubbo-springboot-provider:alpine . -``` - -运行服务 -``` -docker run --name provider -d dubbo-springboot-provider:alpine -``` - -#### Consumer - -切换至目标服务 -``` -cd dubbo-samples-spring-boot-consumer/target -``` - -构建镜像 -``` -cat < Dockerfile -FROM openjdk:8-jdk-alpine -ADD dubbo-samples-spring-boot-consumer-1.0-SNAPSHOT.jar /app.jar -ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/urandom", "-jar", "/app.jar"] -EOF -``` - -编译镜像 -``` -docker build --no-cache -t dubbo-springboot-consumer:alpine . -``` - -运行服务 -``` -docker run --name consumer -d dubbo-springboot-consumer:alpine -``` - -查看服务 -![img](/imgs/v3/tasks/deploy/consumer-provider.jpg) \ No newline at end of file diff --git a/content/zh-cn/overview/tasks/deploy/deploy-on-k8s-containerd.md b/content/zh-cn/overview/tasks/deploy/deploy-on-k8s-containerd.md deleted file mode 100644 index 9256f283c5ae..000000000000 --- a/content/zh-cn/overview/tasks/deploy/deploy-on-k8s-containerd.md +++ /dev/null @@ -1,232 +0,0 @@ ---- -aliases: - - /zh/overview/tasks/deploy/deploy-on-k8s-containerd/ -description: 部署 Dubbo 应用到 Kubernetes + Containerd 示例 -linkTitle: '部署到 Kubernetes + Containerd ' -title: 部署 Dubbo 应用到 Kubernetes + Containerd 环境 -type: docs -weight: 4 ---- - - -## 总体目标 - -- [Kubernetes](https://kubernetes.io/docs/setup/production-environment/tools/) -- Zookeeper -- Dubbo-admin + Zookeeper -- Producer + Zookeeper 与 Consumer + Zookeeper - -## 基本流程与工作原理 - -![img](/imgs/v3/tasks/deploy/dubbo-k8s-containerd.jpg) - -## 详细步骤 - -创建命名空间 -``` -kubectl create ns dubbo-demo -``` - -### zookeeper - -获取图表 -``` -helm repo add bitnami https://charts.bitnami.com/bitnami -``` - -安装 zookeeper -``` -helm install zookeeper bitnami/zookeeper --set persistence.enabled=false -n dubbo-demo -``` - -查看 zookeeper -``` -kubectl get pods -n dubbo-demo -``` - -### dubbo-admin - -克隆项目到本地 -``` -git clone https://github.com/apache/dubbo-admin.git && cd /dubbo-admin/deploy/k8s -``` - -配置 -``` -admin.registry.address=zookeeper://zookeeper:2181 -admin.config-center=zookeeper://zookeeper:2181 -admin.metadata-report.address=zookeeper://zookeeper:2181 -``` - -创建服务 -``` -kubectl apply -f ./ -n dubbo-demo -``` - -启动服务 -``` -kubectl --namespace dubbo-demo port-forward service/dubbo-admin 38080:38080 -``` - -登录页面 -![img](/imgs/v3/tasks/deploy/dubbo-admin-login.jpg) - -服务查询 -![img](/imgs/v3/tasks/deploy/dubbo-admin-page.jpg) - -### dubbo - -克隆项目到本地 -``` -git clone https://github.com/apache/dubbo-samples.git && cd dubbo-samples/1-basic/dubbo-samples-spring-boot -``` - -打包编译 -``` -mvn clean package -``` - -``` -[INFO] ------------------------------------------------------------------------ -[INFO] Reactor Summary: -[INFO] -[INFO] Dubbo Samples Spring Boot 1.0-SNAPSHOT ............. SUCCESS [ 8.147 s] -[INFO] dubbo-samples-spring-boot-interface ................ SUCCESS [ 51.524 s] -[INFO] dubbo-samples-spring-boot-provider ................. SUCCESS [02:27 min] -[INFO] dubbo-samples-spring-boot-consumer 1.0-SNAPSHOT .... SUCCESS [ 0.284 s] -[INFO] ------------------------------------------------------------------------ -[INFO] BUILD SUCCESS -[INFO] ------------------------------------------------------------------------ -[INFO] Total time: 03:49 min -[INFO] Finished at: 2023-01-16T09:34:39-05:00 -[INFO] ------------------------------------------------------------------------ -``` - -配置 -``` -### dubbo-samples-spring-boot-provider/src/main/resources/application.yml -dubbo: - application: - name: dubbo-springboot-demo-provider - protocol: - name: dubbo - port: -1 - registry: - id: zk-registry - address: zookeeper://zookeeper:2181 - config-center: - address: zookeeper://zookeeper:2181 - metadata-report: - address: zookeeper://zookeeper:2181 -``` - -配置 -``` -### dubbo-samples-spring-boot-consumer/src/main/resources/application.yml -dubbo: - application: - name: dubbo-springboot-demo-consumer - protocol: - name: dubbo - port: -1 - registry: - id: zk-registry - address: zookeeper://zookeeper:2181 - config-center: - address: zookeeper://zookeeper:2181 - metadata-report: - address: zookeeper://zookeeper:2181 -``` - -切换到服务示例 -``` -cd && cd dubbo-samples/1-basic/dubbo-samples-spring-boot -``` - -打包编译 -``` -mvn clean package -``` - -#### Producer - -切换至目标服务 -``` -cd dubbo-samples-spring-boot-provider/target -``` - -构建镜像 -``` -cat < Dockerfile -FROM openjdk:8-jdk-alpine -ADD dubbo-samples-spring-boot-provider-1.0-SNAPSHOT.jar /app.jar -ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/urandom", "-jar", "/app.jar"] -EOF -``` - -编译镜像 -``` -nerdctl build --no-cache -t dubbo-springboot-provider:alpine -f Dockerfile . -``` - -导入服务 -``` -cat < provider.yaml -apiVersion: v1 -kind: Pod -metadata: - name: dubbo-springboot-provider - namespace: dubbo-demo -spec: - containers: - - name: provider - image: dubbo-springboot-provider:alpine -EOF -``` -创建服务 -``` -kubectl create -f provider.yaml -``` - -#### Consumer - -切换至目标服务 -``` -cd dubbo-samples-spring-boot-consumer/target -``` -构建镜像 -``` -cat < Dockerfile -FROM openjdk:8-jdk-alpine -ADD dubbo-samples-spring-boot-consumer-1.0-SNAPSHOT.jar /app.jar -ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/urandom", "-jar", "/app.jar"] -EOF -``` - -编译服务 -``` -nerdctl build --no-cache -t dubbo-springboot-consumer:alpine -f Dockerfile . -``` - -导入服务 -``` -cat < consumer.yaml -apiVersion: v1 -kind: Pod -metadata: - name: dubbo-springboot-consumer - namespace: dubbo-demo -spec: - containers: - - name: consumer - image: dubbo-springboot-consumer:alpine -EOF -``` - -创建服务 -``` -kubectl create -f consumer.yaml -``` - -查看服务 -![img](/imgs/v3/tasks/deploy/consumer-provider.jpg) diff --git a/content/zh-cn/overview/tasks/deploy/deploy-on-k8s-docker.md b/content/zh-cn/overview/tasks/deploy/deploy-on-k8s-docker.md deleted file mode 100644 index 89e45dbae192..000000000000 --- a/content/zh-cn/overview/tasks/deploy/deploy-on-k8s-docker.md +++ /dev/null @@ -1,226 +0,0 @@ ---- -aliases: - - /zh/overview/tasks/deploy/deploy-on-k8s-docker/ -description: 部署 Dubbo 应用到 Kubernetes + Docker 示例 -linkTitle: 部署到 Kubernetes + Docker -title: 部署 Dubbo 应用到 Kubernetes + Docker 环境 -type: docs -weight: 3 ---- - - -## 总体目标 - -- [Kubernetes](https://kubernetes.io/docs/setup/production-environment/tools/) -- Zookeeper -- Dubbo-admin + Zookeeper -- Producer + Zookeeper 与 Consumer + Zookeeper - -## 基本流程与工作原理 - -![img](/imgs/v3/tasks/deploy/dubbo-k8s-docker.jpg) - -## 详细步骤 - -创建命名空间 -``` -kubectl create ns dubbo-demo -``` - -### zookeeper - -获取图表 -``` -helm repo add bitnami https://charts.bitnami.com/bitnami -``` -安装 zookeeper -``` -helm install zookeeper bitnami/zookeeper --set persistence.enabled=false -n dubbo-demo -``` - -查看 zookeeper -``` -kubectl get pods -n dubbo-demo -``` - -### dubbo-admin - -克隆项目到本地 -``` -git clone https://github.com/apache/dubbo-admin.git && cd /dubbo-admin/deploy/k8s -``` - -创建服务 -``` -kubectl apply -f ./ -n dubbo-demo -``` - -启动服务 -``` -kubectl --namespace dubbo-demo port-forward service/dubbo-admin 38080:38080 -``` - -登录页面 -![img](/imgs/v3/tasks/deploy/dubbo-admin-login.jpg) - -服务查询 -![img](/imgs/v3/tasks/deploy/dubbo-admin-page.jpg) - -### dubbo - -克隆项目到本地 -``` -git clone https://github.com/apache/dubbo-samples.git && cd dubbo-samples/1-basic/dubbo-samples-spring-boot -``` - -打包编译 -``` -mvn clean package -``` - -``` -[INFO] ------------------------------------------------------------------------ -[INFO] Reactor Summary: -[INFO] -[INFO] Dubbo Samples Spring Boot 1.0-SNAPSHOT ............. SUCCESS [ 8.147 s] -[INFO] dubbo-samples-spring-boot-interface ................ SUCCESS [ 51.524 s] -[INFO] dubbo-samples-spring-boot-provider ................. SUCCESS [02:27 min] -[INFO] dubbo-samples-spring-boot-consumer 1.0-SNAPSHOT .... SUCCESS [ 0.284 s] -[INFO] ------------------------------------------------------------------------ -[INFO] BUILD SUCCESS -[INFO] ------------------------------------------------------------------------ -[INFO] Total time: 03:49 min -[INFO] Finished at: 2023-01-16T09:34:39-05:00 -[INFO] ------------------------------------------------------------------------ -``` - -配置 -``` -### dubbo-samples-spring-boot-provider/src/main/resources/application.yml -dubbo: - application: - name: dubbo-springboot-demo-provider - protocol: - name: dubbo - port: -1 - registry: - id: zk-registry - address: zookeeper://zookeeper:2181 - config-center: - address: zookeeper://zookeeper:2181 - metadata-report: - address: zookeeper://zookeeper:2181 -``` - -配置 -``` -### dubbo-samples-spring-boot-consumer/src/main/resources/application.yml -dubbo: - application: - name: dubbo-springboot-demo-consumer - protocol: - name: dubbo - port: -1 - registry: - id: zk-registry - address: zookeeper://zookeeper:2181 - config-center: - address: zookeeper://zookeeper:2181 - metadata-report: - address: zookeeper://zookeeper:2181 -``` - -切换到服务示例 -``` -cd && cd dubbo-samples/1-basic/dubbo-samples-spring-boot -``` - -打包编译 -``` -mvn clean package -``` - -#### Producer - -切换至目标服务 -``` -cd dubbo-samples-spring-boot-provider/target -``` - -构建镜像 -``` -cat < Dockerfile -FROM openjdk:8-jdk-alpine -ADD dubbo-samples-spring-boot-provider-1.0-SNAPSHOT.jar /app.jar -ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/urandom", "-jar", "/app.jar"] -EOF -``` - -编译镜像 -``` -docker build --no-cache -t dubbo-springboot-provider:alpine . -``` - -导入服务 -``` -cat < provider.yaml -apiVersion: v1 -kind: Pod -metadata: - name: dubbo-springboot-provider - namespace: dubbo-demo -spec: - containers: - - name: provider - image: dubbo-springboot-provider:alpine -EOF -``` - -创建服务 -``` -kubectl create -f provider.yaml -``` - -#### Consumer - -切换至目标服务 -``` -cd dubbo-samples-spring-boot-consumer/target -``` - -构建镜像 -``` -cat < Dockerfile -FROM openjdk:8-jdk-alpine -ADD dubbo-samples-spring-boot-consumer-1.0-SNAPSHOT.jar /app.jar -ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/urandom", "-jar", "/app.jar"] -EOF -``` - -编译服务 -``` -docker build --no-cache -t dubbo-springboot-consumer:alpine . -``` - -导入服务 -``` -cat < consumer.yaml -apiVersion: v1 -kind: Pod -metadata: - name: dubbo-springboot-consumer - namespace: dubbo-demo -spec: - containers: - - name: consumer - image: dubbo-springboot-consumer:alpine -EOF -``` - -创建服务 -``` -kubectl create -f consumer.yaml -``` - -查看服务 -![img](/imgs/v3/tasks/deploy/consumer-provider.jpg) diff --git a/content/zh-cn/overview/tasks/deploy/deploy-on-vm.md b/content/zh-cn/overview/tasks/deploy/deploy-on-vm.md deleted file mode 100644 index 44cafa1d4f94..000000000000 --- a/content/zh-cn/overview/tasks/deploy/deploy-on-vm.md +++ /dev/null @@ -1,199 +0,0 @@ ---- -aliases: - - /zh/overview/tasks/deploy/deploy-on-vm/ -description: "" -linkTitle: 部署到虚拟机 -title: 部署 Dubbo 应用到虚拟机环境 -type: docs -weight: 1 ---- - - - -## 总体目标 -- 虚拟机环境 -- 部署 Zookeeper -- 部署 Dubbo-admin + Zookeeper -- 部署 Provider + Zookeeper 与 Consumer + Zookeeper - -## 基本流程与工作原理 - -![img](/imgs/v3/tasks/deploy/linux.jpg) - -## 详细步骤 - -### zookeeper - -下载项目到本地 -``` -wget https://dlcdn.apache.org/zookeeper/zookeeper-x.x.x/apache-zookeeper-x.x.x-bin.tar.gz -``` - -> apache-zookeeper-x.x.x.tar.gz 为未编译版本, 自 3.5.5 版本以后,已编译的 jar 包后缀 `-bin`,请使用 apache-zookeeper-x.x.x-bin.tar.gz - -解压项目到本地 -``` -tar zxvf apache-zookeeper-x.x.x-bin.tar.gz -C /usr/local/ && cd /usr/local -``` - -移动项目修改为 zookeeper 并切换至 zookeeper -``` -mv apache-zookeeper-x.x.x-bin zookeeper && cd zookeeper -``` - -创建目录并切换此目录导入内容 -``` -mkdir data && cd data && echo 1 > myid -``` - -切换至 zookeeper 配置文件 -``` -cd .. && cp conf/zoo_sample.cfg conf/zoo.cfg && vim conf/zoo.cfg -``` - -配置 -``` -# zoo.cfg -tickTime=2000 -initLimit=10 -syncLimit=5 -dataDir=/usr/local/zookeeper/data -clientPort=2181 -admin.serverPort=2182 -``` - -启动 zookeeper -``` -./bin/zkServer.sh start -``` - -克隆项目到本地 -``` -git clone https://github.com/apache/dubbo-samples.git && cd dubbo-samples/1-basic/dubbo-samples-spring-boot -``` - -打包编译 -``` -mvn clean package -``` - -``` -[INFO] ------------------------------------------------------------------------ -[INFO] Reactor Summary: -[INFO] -[INFO] Dubbo Samples Spring Boot 1.0-SNAPSHOT ............. SUCCESS [ 0.178 s] -[INFO] dubbo-samples-spring-boot-interface ................ SUCCESS [ 2.169 s] -[INFO] dubbo-samples-spring-boot-provider ................. SUCCESS [12:37 min] -[INFO] dubbo-samples-spring-boot-consumer 1.0-SNAPSHOT .... SUCCESS [ 0.219 s] -[INFO] ------------------------------------------------------------------------ -[INFO] BUILD SUCCESS -[INFO] ------------------------------------------------------------------------ -[INFO] Total time: 12:54 min -[INFO] Finished at: 2023-01-16T01:17:09-05:00 -[INFO] ------------------------------------------------------------------------ -``` - -### dubbo-admin - -克隆项目到本地 -``` -# 默认配置 -git clone https://github.com/apache/dubbo-admin.git && cd dubbo-admin -# 修改配置 -git clone https://github.com/apache/dubbo-admin.git && cd dubbo-admin && vim dubbo-admin-server/src/main/resources/application.properties -``` - -配置 -``` -# dubbo-admin-server/src/main/resources/application.properties -server.port=38080 -dubbo.protocol.port=30880 -dubbo.application.qos-port=32222 - -admin.registry.address=zookeeper://127.0.0.1:2181 -admin.config-center=zookeeper://127.0.0.1:2181 -admin.metadata-report.address=zookeeper://127.0.0.1:2181 - -admin.root.user.name=root -admin.root.user.password=root -``` -打包编译 -``` -mvn clean package -Dmaven.test.skip=true -``` - -切换至目标服务 -``` -cd dubbo-admin/dubbo-admin-server/target -``` - -后台运行 -``` -nohup java -jar dubbo-admin-server-0.5.0-SNAPSHOT.jar > /dev/null 2>&1 & -``` - -进入服务 -``` -http://:38080 -``` - -登录页面 -![img](/imgs/v3/tasks/deploy/dubbo-admin-login.jpg) - -服务查询 -![img](/imgs/v3/tasks/deploy/dubbo-admin-page.jpg) - -### dubbo - -克隆项目到本地 -``` -git clone https://github.com/apache/dubbo-samples.git && cd dubbo-samples/1-basic/dubbo-samples-spring-boot -``` - -打包编译 -``` -mvn clean package -``` - -``` -[INFO] ------------------------------------------------------------------------ -[INFO] Reactor Summary: -[INFO] -[INFO] Dubbo Samples Spring Boot 1.0-SNAPSHOT ............. SUCCESS [ 8.147 s] -[INFO] dubbo-samples-spring-boot-interface ................ SUCCESS [ 51.524 s] -[INFO] dubbo-samples-spring-boot-provider ................. SUCCESS [02:27 min] -[INFO] dubbo-samples-spring-boot-consumer 1.0-SNAPSHOT .... SUCCESS [ 0.284 s] -[INFO] ------------------------------------------------------------------------ -[INFO] BUILD SUCCESS -[INFO] ------------------------------------------------------------------------ -[INFO] Total time: 03:49 min -[INFO] Finished at: 2023-01-16T09:34:39-05:00 -[INFO] ------------------------------------------------------------------------ -``` - -#### Provider - -切换至目标服务 -``` -cd dubbo-samples-spring-boot-provider/target -``` - -后台运行 -``` -nohup java -jar dubbo-samples-spring-boot-provider-1.0-SNAPSHOT.jar > /dev/null 2>&1 & -``` - -#### Consumer - -切换至目标服务 -``` -cd dubbo-samples-spring-boot-consumer/target -``` - -后台运行 -``` -nohup java -jar dubbo-samples-spring-boot-consumer-1.0-SNAPSHOT.jar > /dev/null 2>&1 & -``` - -查看服务 -![img](/imgs/v3/tasks/deploy/consumer-provider.jpg) \ No newline at end of file diff --git a/content/zh-cn/overview/tasks/develop/_index.md b/content/zh-cn/overview/tasks/develop/_index.md deleted file mode 100755 index f938c772713a..000000000000 --- a/content/zh-cn/overview/tasks/develop/_index.md +++ /dev/null @@ -1,82 +0,0 @@ ---- -aliases: - - /zh/overview/tasks/develop/ -description: 演示 Dubbo 框架提供的微服务开发 API 与编程模式 -linkTitle: 开发服务 -no_list: true -title: 开发服务 -type: docs -weight: 1 ---- - - - -{{< blocks/section color="white" height="auto">}} -
-
-
-
-
-

- 生成项目模板 -

-

使用项目脚手架快速生成微服务项目模板

-
-
-
-
-
-
-

- 发布和引用服务 -

-

演示如何定义、发布和调用 Dubbo 服务。

-
-
-
-
-
-
-

- 异步调用 -

-

演示 Dubbo 服务的异步调用编程模式,支持客户端异步和服务端异步。

-
-
-
-
-
-
-

- 版本与分组 -

-

演示 Dubbo 如何通过 group、version 隔离不同版本的服务。

-
-
-
-
-
-
-

- 上下文参数 -

-

演示如何在 RPC 请求中传递额外参数。

-
-
-
-
-
-
-

- 泛化调用 -

-

演示 Dubbo 泛化调用的使用方式。

-
-
-
-
-
-
- -{{< /blocks/section >}} diff --git a/content/zh-cn/overview/tasks/develop/async.md b/content/zh-cn/overview/tasks/develop/async.md deleted file mode 100644 index 335073242644..000000000000 --- a/content/zh-cn/overview/tasks/develop/async.md +++ /dev/null @@ -1,168 +0,0 @@ ---- -aliases: - - /zh/overview/tasks/develop/async/ -description: 某些情况下希望dubbo接口异步调用,避免不必要的等待。 -linkTitle: Provider端和Consumer端异步调用 -title: 异步调用 -type: docs -weight: 3 ---- - -文档完整的示例地址请参见 -* [服务调用异步](https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-async/dubbo-samples-async-simple-boot) -* [服务执行异步](https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-async/dubbo-samples-async-provider) -* [定义 CompletableFuture 方法签名的服务](https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-async/dubbo-samples-async-original-future) - -## 异步调用 -Dubbo异步调用分为Provider端异步调用和Consumer端异步调用。 -Provider端异步执行将阻塞的业务从Dubbo内部线程池切换到业务自定义线程, -避免Dubbo线程池的过度占用,有助于避免不同服务间的互相影响。异步执行无异于节省资源或提升RPC响应性能。 - -* 注意 * - -> Provider 端异步执行和 Consumer 端异步调用是相互独立的,你可以任意正交组合两端配置 -> + Consumer同步 - Provider同步 -> + Consumer异步 - Provider同步 -> + Consumer同步 - Provider异步 -> + Consumer异步 - Provider异步 - -## 使用场景 -* 对于Provider端来说,如果接口比较耗时,避免dubbo线程被阻塞,可以使用异步将线程切换到业务线程。 -* 对于Consumer端来说,调用Dubbo接口没有严格时序上的关系、不是原子操作、不影响逻辑情况下可以使用异步调用。 - - -## Provider异步 - -### 1、使用CompletableFuture实现异步 - -接口定义: -```java -public interface AsyncService { - /** - * 同步调用方法 - */ - String invoke(String param); - /** - * 异步调用方法 - */ - CompletableFuture asyncInvoke(String param); -} - -``` -服务实现: -```java -@DubboService -public class AsyncServiceImpl implements AsyncService { - - @Override - public String invoke(String param) { - try { - long time = ThreadLocalRandom.current().nextLong(1000); - Thread.sleep(time); - StringBuilder s = new StringBuilder(); - s.append("AsyncService invoke param:").append(param).append(",sleep:").append(time); - return s.toString(); - } - catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - return null; - } - - @Override - public CompletableFuture asyncInvoke(String param) { - // 建议为supplyAsync提供自定义线程池 - return CompletableFuture.supplyAsync(() -> { - try { - // Do something - long time = ThreadLocalRandom.current().nextLong(1000); - Thread.sleep(time); - StringBuilder s = new StringBuilder(); - s.append("AsyncService asyncInvoke param:").append(param).append(",sleep:").append(time); - return s.toString(); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - return null; - }); - } -} - -``` -通过 return CompletableFuture.supplyAsync() ,业务执行已从 Dubbo 线程切换到业务线程,避免了对 Dubbo 线程池的阻塞。 - -### 2、使用AsyncContext实现异步 - -Dubbo 提供了一个类似 Servlet 3.0 的异步接口AsyncContext,在没有 CompletableFuture 签名接口的情况下,也可以实现 Provider 端的异步执行。 - -接口定义: -```java -public interface AsyncService { - String sayHello(String name); -} - -``` - -服务实现: - -```java -public class AsyncServiceImpl implements AsyncService { - public String sayHello(String name) { - final AsyncContext asyncContext = RpcContext.startAsync(); - new Thread(() -> { - // 如果要使用上下文,则必须要放在第一句执行 - asyncContext.signalContextSwitch(); - try { - Thread.sleep(500); - } catch (InterruptedException e) { - e.printStackTrace(); - } - // 写回响应 - asyncContext.write("Hello " + name + ", response from provider."); - }).start(); - return null; - } -} - -``` - -## Consumer异步 -```java -@DubboReference -private AsyncService asyncService; - -@Override -public void run(String... args) throws Exception { - //调用异步接口 - CompletableFuture future1 = asyncService.asyncInvoke("async call request1"); - future1.whenComplete((v, t) -> { - if (t != null) { - t.printStackTrace(); - } else { - System.out.println("AsyncTask Response-1: " + v); - } - }); - //两次调用并非顺序返回 - CompletableFuture future2 = asyncService.asyncInvoke("async call request2"); - future2.whenComplete((v, t) -> { - if (t != null) { - t.printStackTrace(); - } else { - System.out.println("AsyncTask Response-2: " + v); - } - }); - //consumer异步调用 - CompletableFuture future3 = CompletableFuture.supplyAsync(() -> { - return asyncService.invoke("invoke call request3"); - }); - future3.whenComplete((v, t) -> { - if (t != null) { - t.printStackTrace(); - } else { - System.out.println("AsyncTask Response-3: " + v); - } - }); - - System.out.println("AsyncTask Executed before response return."); -} -``` \ No newline at end of file diff --git a/content/zh-cn/overview/tasks/develop/context.md b/content/zh-cn/overview/tasks/develop/context.md deleted file mode 100644 index cb6a4c324259..000000000000 --- a/content/zh-cn/overview/tasks/develop/context.md +++ /dev/null @@ -1,104 +0,0 @@ ---- -aliases: - - /zh/overview/tasks/develop/context/ -description: 通过 Dubbo 中的 Attachment 在服务消费方和提供方之间传递参数 -linkTitle: 上下文参数传递 -title: 上下文参数传递 -type: docs -weight: 5 ---- - - -## 上下文参数传递 -在 Dubbo 3 中,RpcContext 被拆分为四大模块(ServerContext、ClientAttachment、ServerAttachment 和 ServiceContext)。 - -它们分别承担了不同的职责: - -* ServiceContext:在 Dubbo 内部使用,用于传递调用链路上的参数信息,如 invoker 对象等 -* ClientAttachment:在 Client 端使用,往 ClientAttachment 中写入的参数将被传递到 Server 端 -* ServerAttachment:在 Server 端使用,从 ServerAttachment 中读取的参数是从 Client 中传递过来的 -* ServerContext:在 Client 端和 Server 端使用,用于从 Server 端回传 Client 端使用,Server 端写入到 ServerContext 的参数在调用结束后可以在 Client 端的 ServerContext 获取到 - -## 使用场景 -1、Dubbo系统间调用时,想传递一些通用参数,可通过Dubbo提供的扩展如Filter等实现统一的参数传递 - -2、Dubbo系统间调用时,想传递接口定义之外的参数,可在调用接口前使用setAttachment传递参数。 - -## 使用方式 -setAttachment 设置的 KV 对,在完成下面一次远程调用会被清空,即多次远程调用要多次设置。 - -接口定义: -```java -public interface ContextService { - String invoke(String param); -} - -``` -服务实现: -```java -@DubboService -public class ContextServiceImpl implements ContextService{ - @Override - public String invoke(String param) { - //ServerAttachment接收客户端传递过来的参数 - Map serverAttachments = RpcContext.getServerAttachment().getObjectAttachments(); - System.out.println("ContextService serverAttachments:" + JSON.toJSONString(serverAttachments)); - //往客户端传递参数 - RpcContext.getServerContext().setAttachment("serverKey","serverValue"); - StringBuilder s = new StringBuilder(); - s.append("ContextService param:").append(param); - return s.toString(); - } -} - -``` - -接口调用: -```java - //往服务端传递参数 - RpcContext.getClientAttachment().setAttachment("clientKey1","clientValue1"); - String res = contextService.invoke("context1"); - //接收传递回来参数 - Map clientAttachment = RpcContext.getServerContext().getObjectAttachments(); - System.out.println("ContextTask clientAttachment:" + JSON.toJSONString(clientAttachment)); - System.out.println("ContextService Return : " + res); - -``` - -* 注意 * -> path, group, version, dubbo, token, timeout 几个 key 是保留字段,请使用其它值。 - -# 历史遗留问题 - -在之前的版本中,你可能会见到这样的使用方式: -```java -@Activate(group = {CommonConstants.CONSUMER}) -public class DubboConsumerFilter implements Filter { - - @Override - public Result invoke(Invoker invoker, Invocation invocation) throws RpcException { - - RpcContext.getContext().setAttachment("demo","demo02"); - - - return invoker.invoke(invocation); - } -} -``` - -但是在新版本中我们的建议是 **在 Filter 里面的尽可能不要操作 RpcContext**,上面的使用方式会导致不生效。原因在于新版本中,我们在`ConsumerContextFilter`类中做了`ClientAttachment` -> `Invocation`属性的复制,该类是Dubbo内置Filter类,而内置Filter类先于用户定义Filter类执行,所以在自定义Filter类中这样使用不会生效。 -可以直接使用这种方式进行传递: - -```java -@Activate(group = {CommonConstants.CONSUMER}) -public class DubboConsumerFilter implements Filter { - - @Override - public Result invoke(Invoker invoker, Invocation invocation) throws RpcException { - - invocation.setAttachment("demo","demo02"); - - return invoker.invoke(invocation); - } -} -``` diff --git a/content/zh-cn/overview/tasks/develop/generic.md b/content/zh-cn/overview/tasks/develop/generic.md deleted file mode 100644 index 1b201124166e..000000000000 --- a/content/zh-cn/overview/tasks/develop/generic.md +++ /dev/null @@ -1,73 +0,0 @@ ---- -aliases: - - /zh/overview/tasks/develop/generic/ -description: 在调用方没有服务方提供的 API(SDK)的情况下,对服务方进行调用 -linkTitle: 泛化调用 -title: 开发服务 -type: docs -weight: 6 ---- - - -## 泛化调用 -泛化调用(客户端泛化调用)是指在调用方没有服务方提供的 API(SDK)的情况下,对服务方进行调用,并且可以正常拿到调用结果。 - -## 使用场景 -调用方没有接口及模型类元,知道服务的接口的全限定类名和方法名的情况下,可以通过泛化调用调用对应接口。 -比如:实现一个通用的服务测试框架 - -## 使用方式 - -本示例中使用"发布和调用" 中示例代码 - -接口定义: -```java -public interface DevelopService { - String invoke(String param); -} -``` - -接口实现1: -```java -@DubboService(group = "group1",version = "1.0") -public class DevelopProviderServiceV1 implements DevelopService{ - @Override - public String invoke(String param) { - StringBuilder s = new StringBuilder(); - s.append("ServiceV1 param:").append(param); - return s.toString(); - } -} -``` - -## 客户端调用 - -```java -@Component -public class GenericTask implements CommandLineRunner { - - @Override - public void run(String... args) throws Exception { - GenericService genericService = buildGenericService("org.apache.dubbo.samples.develop.DevelopService","group1","1.0"); - //传入需要调用的方法,参数类型列表,参数列表 - Object result = genericService.$invoke("invoke", new String[]{"java.lang.String"}, new Object[]{"g1"}); - System.out.println("GenericTask Response: " + JSON.toJSONString(result)); - } - - private GenericService buildGenericService(String interfaceClass, String group, String version) { - ReferenceConfig reference = new ReferenceConfig<>(); - reference.setInterface(interfaceClass); - reference.setVersion(version); - //开启泛化调用 - reference.setGeneric("true"); - reference.setTimeout(30000); - reference.setGroup(group); - ReferenceCache cache = SimpleReferenceCache.getCache(); - try { - return cache.get(reference); - } catch (Exception e) { - throw new RuntimeException(e.getMessage()); - } - } -} -``` \ No newline at end of file diff --git a/content/zh-cn/overview/tasks/develop/idl.md b/content/zh-cn/overview/tasks/develop/idl.md deleted file mode 100644 index 3bcabd540eba..000000000000 --- a/content/zh-cn/overview/tasks/develop/idl.md +++ /dev/null @@ -1,242 +0,0 @@ ---- -aliases: - - /zh/overview/tasks/develop/idl/ -description: "" -linkTitle: IDL开发服务 -title: 使用 IDL 定义与开发服务 -type: docs -weight: 7 ---- - - - -服务是 Dubbo 中的核心概念,一个服务代表一组 RPC 方法的集合,服务是面向用户编程、服务发现机制等的基本单位。Dubbo 开发的基本流程是:用户定义 RPC 服务,通过约定的配置 -方式将 RPC 声明为 Dubbo 服务,然后就可以基于服务 API 进行编程了。对服务提供者来说是提供 RPC 服务的具体实现,而对服务消费者来说则是使用特定数据发起服务调用。 - -下面从定义服务、编译服务、配置并加载服务三个方面说明如何快速的开发 Dubbo 服务。 - -具体用例可以参考:[dubbo-samples-triple/stub](https://github.com/apache/dubbo-samples/tree/master/3-extensions/protocol/dubbo-samples-triple/src/main/java/org/apache/dubbo/sample/tri/stub); - -## 定义服务 -Dubbo3 推荐使用 IDL 定义跨语言服务,如您更习惯使用特定语言的服务定义方式,请移步[多语言 SDK](/zh-cn/overview/mannual/)查看。 - -```text -syntax = "proto3"; - -option java_multiple_files = true; -option java_package = "org.apache.dubbo.demo"; -option java_outer_classname = "DemoServiceProto"; -option objc_class_prefix = "DEMOSRV"; - -package demoservice; - -// The demo service definition. -service DemoService { - rpc SayHello (HelloRequest) returns (HelloReply) {} -} - -// The request message containing the user's name. -message HelloRequest { - string name = 1; -} - -// The response message containing the greetings -message HelloReply { - string message = 1; -} - -``` - -以上是使用 IDL 定义服务的一个简单示例,我们可以把它命名为 `DemoService.proto`,proto 文件中定义了 RPC 服务名称 `DemoService` 与方法签名 -`SayHello (HelloRequest) returns (HelloReply) {}`,同时还定义了方法的入参结构体、出参结构体 `HelloRequest` 与 `HelloReply`。 -IDL 格式的服务依赖 Protobuf 编译器,用来生成可以被用户调用的客户端与服务端编程 API,Dubbo 在原生 Protobuf Compiler 的基础上提供了适配多种语言的特有插件,用于适配 Dubbo 框架特有的 API 与编程模型。 - -> 使用 Dubbo3 IDL 定义的服务只允许一个入参与出参,这种形式的服务签名有两个优势,一是对多语言实现更友好,二是可以保证服务的向后兼容性,依赖于 Protobuf 序列化的兼容性,我们可以很容易的调整传输的数据结构如增、删字段等,完全不用担心接口的兼容性。 - -## 编译服务 -根据当前采用的语言,配置相应的 Protobuf 插件,编译后将生产语言相关的服务定义 stub。 - -### Java - -Java compiler 配置参考: -```xml - - org.xolstice.maven.plugins - protobuf-maven-plugin - 0.6.1 - - com.google.protobuf:protoc:${protoc.version}:exe:${os.detected.classifier} - - grpc-java - io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier} - - - - dubbo - org.apache.dubbo - dubbo-compiler - 3.0.10 - org.apache.dubbo.gen.tri.Dubbo3TripleGenerator - - - - - - - compile - test-compile - compile-custom - test-compile-custom - - - - -``` - -Java 语言生成的 stub 如下,核心是一个接口定义 -```java -@javax.annotation.Generated( -value = "by Dubbo generator", -comments = "Source: DemoService.proto") -public interface DemoService { - static final String JAVA_SERVICE_NAME = "org.apache.dubbo.demo.DemoService"; - static final String SERVICE_NAME = "demoservice.DemoService"; - - org.apache.dubbo.demo.HelloReply sayHello(org.apache.dubbo.demo.HelloRequest request); - - CompletableFuture sayHelloAsync(org.apache.dubbo.demo.HelloRequest request); -} -``` - -### Golang - -Go 语言生成的 stub 如下,这个 stub 里存了用户定义的接口和数据的类型。 - -```go -func _DUBBO_Greeter_SayHello_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(HelloRequest) - if err := dec(in); err != nil { - return nil, err - } - base := srv.(dgrpc.Dubbo3GrpcService) - args := []interface{}{} - args = append(args, in) - invo := invocation.NewRPCInvocation("SayHello", args, nil) - if interceptor == nil { - result := base.GetProxyImpl().Invoke(ctx, invo) - return result.Result(), result.Error() - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/main.Greeter/SayHello", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - result := base.GetProxyImpl().Invoke(context.Background(), invo) - return result.Result(), result.Error() - } - return interceptor(ctx, in, info, handler) -} -``` - - -## 配置并加载服务 -提供端负责提供具体的 Dubbo 服务实现,也就是遵循 RPC 签名所约束的格式,去实现具体的业务逻辑代码。在实现服务之后,要将服务实现注册为标准的 Dubbo 服务, -之后 Dubbo 框架就能根据接收到的请求转发给服务实现,执行方法,并将结果返回。 - -消费端的配置会更简单一些,只需要声明 IDL 定义的服务为标准的 Dubbo 服务,框架就可以帮助开发者生成相应的 proxy,开发者将完全面向 proxy 编程, -基本上 Dubbo 所有语言的实现都保证了 proxy 依据 IDL 服务定义暴露标准化的接口。 - -### Java -提供端,实现服务 -```java -public class DemoServiceImpl implements DemoService { - private static final Logger logger = LoggerFactory.getLogger(DemoServiceImpl.class); - - @Override - public HelloReply sayHello(HelloRequest request) { - logger.info("Hello " + request.getName() + ", request from consumer: " + RpcContext.getContext().getRemoteAddress()); - return HelloReply.newBuilder() - .setMessage("Hello " + request.getName() + ", response from provider: " - + RpcContext.getContext().getLocalAddress()) - .build(); - } - - @Override - public CompletableFuture sayHelloAsync(HelloRequest request) { - return CompletableFuture.completedFuture(sayHello(request)); - } -} -``` - -提供端,注册服务(以 Spring XML 为例) -```xml - - -``` - -消费端,引用服务 -```xml - -``` - -消费端,使用服务 proxy -```java -public void callService() throws Exception { - ... - DemoService demoService = context.getBean("demoService", DemoService.class); - HelloRequest request = HelloRequest.newBuilder().setName("Hello").build(); - HelloReply reply = demoService.sayHello(request); - System.out.println("result: " + reply.getMessage()); -} -``` - -### Golang - -提供端,实现服务 - -```go -type User struct { - ID string - Name string - Age int32 - Time time.Time -} - -type UserProvider struct { -} - -func (u *UserProvider) GetUser(ctx context.Context, req []interface{}) (*User, error) { - gxlog.CInfo("req:%#v", req) - rsp := User{"A001", "Alex Stocks", 18, time.Now()} - gxlog.CInfo("rsp:%#v", rsp) - return &rsp, nil -} - -func (u *UserProvider) Reference() string { - return "UserProvider" -} - -func (u User) JavaClassName() string { - return "org.apache.dubbo.User" -} - -func main() { - hessian.RegisterPOJO(&User{}) - config.SetProviderService(new(UserProvider)) -} -``` - -消费端,使用服务 proxy - -```go -func main() { - config.Load() - user := &pkg.User{} - err := userProvider.GetUser(context.TODO(), []interface{}{"A001"}, user) - if err != nil { - os.Exit(1) - return - } - gxlog.CInfo("response result: %v\n", user) -} -``` diff --git a/content/zh-cn/overview/tasks/develop/service_reference.md b/content/zh-cn/overview/tasks/develop/service_reference.md deleted file mode 100644 index 769ee5ddb919..000000000000 --- a/content/zh-cn/overview/tasks/develop/service_reference.md +++ /dev/null @@ -1,131 +0,0 @@ ---- -aliases: - - /zh/overview/tasks/develop/service_reference/ -description: 通过示例简单展示一个Dubbo服务的发布和调用 -linkTitle: 发布和调用 Dubbo 服务 -title: 开发服务 -type: docs -weight: 2 ---- - - -## 发布和调用 -通过一个简单的Springboot实例代码,展示Dubbo服务的发布和调用 - -本文将基于 Dubbo Samples 示例演示如何快速搭建并部署一个微服务应用。 -代码地址:[dubbo-samples-develop](https://github.com/apache/dubbo-samples/tree/master/10-task/dubbo-samples-develop) -代码分为三个模块 -* api -* develop-provider -* develop-consumer - -## 准备 -本示例代码基于Springboot 3.0 - -1、首先需要一个可用的注册中心 Zookeeper,Nacos,Redis 均可。 - -2、新建一个maven工程,添加如下依赖 -```xml - - - com.alibaba.nacos - nacos-client - ${nacos.version} - - - - - org.apache.dubbo - dubbo-spring-boot-starter - ${dubbo.version} - - - - org.springframework.boot - spring-boot-starter - - -``` -本示例使用的注册中心为Nacos,使用ZK请将nacos-client包替换为对应版本zk客户端包。 - -## 发布服务 -1、定义服务接口 -```java -public interface DevelopService { - String invoke(String param); -} -``` -2、服务接口实现 -```java -@DubboService(group = "group1",version = "1.0") -public class DevelopProviderServiceV1 implements DevelopService{ - @Override - public String invoke(String param) { - StringBuilder s = new StringBuilder(); - s.append("ServiceV1 param:").append(param); - return s.toString(); - } -} -``` -使用@DubboService 注解,Dubbo会将对应的服务注册到spring, -在spring启动后调用对应的服务导出方法,将服务注册到注册中心, -这样Consumer端才能发现我们发布的服务并调用 - -3、添加Dubbo配置 - -添加application.properties相关配置,也可新建dubbo.properties保存dubbo相关配置,内容如下: -```properties -dubbo.application.name=provider - -# Enable token verification for each invocation -dubbo.provider.token=false - -# Specify the registry address -# dubbo.registry.address=nacos://localhost:8848?username=nacos&password=nacos -dubbo.registry.address=nacos://${nacos.address:localhost}:8848?username=nacos&password=nacos - -dubbo.protocol.name=dubbo -dubbo.protocol.port=20881 -``` - -4、启动服务 - -创建Springboot启动类,需添加@EnableDubbo注解,开启Dubbo自动配置功能 -```java -@EnableDubbo -@SpringBootApplication -public class DevelopApplication { - - public static void main(String[] args) { - SpringApplication.run(DevelopApplication.class, args); - } -} - -``` -启动成功后,在注册中心可以看到对应的服务列表,如图: -`![serviceList](/imgs/v3/develop/develop-service-list.png)` - -## 调用服务 - -创建DemoTask类,通过@DubboReference注解对需要调用的服务进行引入。即可像调用本地方法一样调用远程服务了。 - -```java -//实现CommandLineRunner 让Springboot启动后调用run方法 -@Component -public class DemoTask implements CommandLineRunner { - @DubboReference(group = "group1",version = "1.0") - private DevelopService developService; - - @Override - public void run(String... args) throws Exception { - //调用DevelopService的group1分组实现 - System.out.println("Dubbo Remote Return ======> " + developService.invoke("1")); - } -} -``` - -启动服务 打印 - -`Dubbo Remote Return ======> ServiceV1 param:1` - -说明服务调用成功 \ No newline at end of file diff --git a/content/zh-cn/overview/tasks/develop/template.md b/content/zh-cn/overview/tasks/develop/template.md deleted file mode 100644 index f616eb089f9b..000000000000 --- a/content/zh-cn/overview/tasks/develop/template.md +++ /dev/null @@ -1,61 +0,0 @@ ---- -aliases: - - /zh/overview/tasks/develop/template/ -description: "" -linkTitle: 生成项目 -title: 通过模板生成项目脚手架 -type: docs -weight: 1 ---- - -Dubbo Initializer 可用来快速生成 Java 项目脚手架,帮助简化微服务项目搭建、基本配置、组件依赖管理等。 - -> Initializer 仍在持续更新中,更多 Dubbo Feature 的支持将会陆续发布。 - -## 选择 Dubbo 版本 -Initializer 将使用 `dubbo-spring-boot-starter` 创建 Spring Boot 项目,因此我们首先需要选择 Dubbo 与 Spring Boot 的版本。 - -![initializer-choose-version](/imgs/v3/tasks/develop/initializer-choose-version.png) - -## 录入项目基本信息 -接下来,填入项目基本信息,包括项目坐标、项目名称、包名、JDK 版本等。 - -![initializer-project-info](/imgs/v3/tasks/develop/initializer-project-info.png) - -## 选择项目结构 -有两种项目结构可共选择,分别是 `单模块` 和 `多模块`,在这个示例中我们选择 `单模块`。 - -![initializer-project-architecture](/imgs/v3/tasks/develop/initializer-project-architecture.png) - -* 单模块,所有组件代码存放在一个 module 中,特点是结构简单。 -* 多模块,生成的项目有 `API`、`Service` 两个模块,其中 `API` 用于存放 Dubbo 服务定义,`Service` 用于存放服务实现或调用逻辑。通常多模块更有利于服务定义的单独管理与发布。 - -## 选择依赖组件 -我们为模板默认选择如下几个依赖组件: -* Dubbo 组件 - * Java Interface - * 注册中心,zookeeper - * 协议 TCP -* 常用微服务组件 - * Web - * Mybatis - * 模版引擎 - -![initializer-dependencies](/imgs/v3/tasks/develop/initializer-dependencies.png) - -基于以上选项,生成的项目将以 Zookeeper 为注册中心,以高性能 Dubbo2 TCP 协议为 RPC 通信协议,并且增加了 Web、Mybatis 等组件依赖和示例。 - -> 注意:上面选中的 Dubbo 组件也都是默认选项,即在不手动添加任何依赖的情况下,打开页面后直接点击代码生成,生成的代码即包含以上 Dubbo 组件。 -> -> 如手动添加依赖组件,请注意 Dubbo 各个依赖组件之间的隐含组合关系限制,比如 -> * 如果选择了【Dubbo Service API】-【IDL】,则目前仅支持选择 【Dubbo Protocol】中的 【HTTP/2】或 【gRPC】 协议。 -> * 同一个依赖分组下,相同类型的依赖只能选择一个,比如 【Dubbo Registry&Config&Metadata】分组下,从注册中心视角【Zookeeper】、【Nacos】只能选一个,如果要设置多注册中心,请在生成的代码中手动修改配置。但注册中心、配置中心可以分别选一个,比如 Zookeeper 和 Apollo 可同时选中。 - -## 生成项目模板 -* 点击 “浏览代码” 可在线浏览项目结构与代码 -* 点击 “获取代码” 生成项目下载地址 - -![initializer-preview](/imgs/v3/tasks/develop/initializer-preview.png) - -项目下载到本地后,解压并导入 IDE 后即可根据需要开发定制 Dubbo 应用。 - diff --git a/content/zh-cn/overview/tasks/develop/version_group.md b/content/zh-cn/overview/tasks/develop/version_group.md deleted file mode 100644 index 0b4e64010720..000000000000 --- a/content/zh-cn/overview/tasks/develop/version_group.md +++ /dev/null @@ -1,78 +0,0 @@ ---- -aliases: - - /zh/overview/tasks/develop/version_group/ -description: "" -linkTitle: 版本与分组 -title: 版本与分组 -type: docs -weight: 4 ---- - - -## 版本与分组 -Dubbo服务中,接口并不能唯一确定一个服务,只有接口+分组+版本号才能唯一确定一个服务。 - -## 使用场景 -* 当同一个接口针对不同的业务场景、不同的使用需求或者不同的功能模块等场景,可使用服务分组来区分不同的实现方式。同时,这些不同实现所提供的服务是可并存的,也支持互相调用。 -* 当接口实现需要升级又要保留原有实现的情况下,即出现不兼容升级时,我们可以使用不同版本号进行区分。 - - -## 使用方式 -使用 @DubboService 注解,添加 group 参数和 version 参数 -本示例中使用"发布和调用" 中示例代码 - -接口定义: -```java -public interface DevelopService { - String invoke(String param); -} -``` - -接口实现1: -```java -@DubboService(group = "group1",version = "1.0") -public class DevelopProviderServiceV1 implements DevelopService{ - @Override - public String invoke(String param) { - StringBuilder s = new StringBuilder(); - s.append("ServiceV1 param:").append(param); - return s.toString(); - } -} -``` -接口实现2: -```java -@DubboService(group = "group2",version = "2.0") -public class DevelopProviderServiceV2 implements DevelopService{ - @Override - public String invoke(String param) { - StringBuilder s = new StringBuilder(); - s.append("ServiceV2 param:").append(param); - return s.toString(); - } -} -``` - -启动服务后,可以在注册中心看到对应的服务列表,如下: -`![serviceList](/imgs/v3/develop/develop-service-list.png)` - - -客户端接口调用: - -> 使用 @DubboReference 注解,添加 group 参数和 version 参数 - -```java -@DubboReference(group = "group1",version = "1.0") -private DevelopService developService; - -@DubboReference(group = "group2",version = "2.0") -private DevelopService developServiceV2; - -@Override -public void run(String... args) throws Exception { - //调用DevelopService的group1分组实现 - System.out.println("Dubbo Remote Return ======> " + developService.invoke("1")); - //调用DevelopService的另一个实现 - System.out.println("Dubbo Remote Return ======> " + developServiceV2.invoke("2")); -} -``` \ No newline at end of file diff --git a/content/zh-cn/overview/tasks/ecosystem/_index.md b/content/zh-cn/overview/tasks/ecosystem/_index.md deleted file mode 100755 index 22fcb37b9289..000000000000 --- a/content/zh-cn/overview/tasks/ecosystem/_index.md +++ /dev/null @@ -1,70 +0,0 @@ ---- -aliases: - - /zh/overview/tasks/ecosystem/ -description: 围绕 Dubbo 生态的限流降级、全链路追踪、分布式一致性等解决方案 -linkTitle: 微服务生态 -no_list: true -title: 微服务生态 -type: docs -weight: 4 ---- - -{{< blocks/section color="white" height="auto">}} -
-
-
-
-
-

- 事务管理 -

-

本示例演示如何通过 Seata 实现分布式 Dubbo 服务的事务管理,保证数据一致性。

-
-
-
-
-
-
-

- 网关接入 -

-

通过网关 http 到 dubbo 协议转换,实现前端流量接入后端 dubbo 服务。

-
-
-
-
-
-
-

- 服务发现 -

-

Dubbo 官方支持的常见注册中心扩展实现及其使用方式。

-
-
-
-
-
-
-

- 配置中心 -

-

Dubbo 官方支持的常见配置中心扩展实现及其使用方式。

-
-
-
-
-
-
-

- 元数据中心 -

-

Dubbo 官方支持的常见元数据中心扩展实现及其使用方式。

-
-
-
-
-
-
- -{{< /blocks/section >}} diff --git a/content/zh-cn/overview/tasks/ecosystem/configuration.md b/content/zh-cn/overview/tasks/ecosystem/configuration.md deleted file mode 100644 index cc0893298487..000000000000 --- a/content/zh-cn/overview/tasks/ecosystem/configuration.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -_build: - render: link -description: "" -icon: fas fa-external-link-alt -linkTitle: 配置中心 -manualLinkRelref: ../../mannual/java-sdk/reference-manual/config-center/ -manualLinkTarget: _blank -title: 配置中心 -type: docs -weight: 31 ---- diff --git a/content/zh-cn/overview/tasks/ecosystem/gateway.md b/content/zh-cn/overview/tasks/ecosystem/gateway.md deleted file mode 100644 index 5fa3d450b30f..000000000000 --- a/content/zh-cn/overview/tasks/ecosystem/gateway.md +++ /dev/null @@ -1,242 +0,0 @@ ---- -aliases: - - /zh/overview/tasks/ecosystem/gateway/ -description: | - 本文为大家介绍了如何借助 Apache APISIX 实现 Dubbo Service 的代理,通过引入 dubbo-proxy 插件便可为 Dubbo 框架的后端系统构建更简单更高效的流量链路 -linkTitle: HTTP网关 -title: 通过网关将 http 流量接入 Dubbo 后端服务 -type: docs -weight: 2 ---- - -更多网关接入案例,请参考 -* [使用 Apache Shenyu 代理 Dubbo 流量]({{< relref "../../../../blog/integration/how-to-proxy-dubbo-in-apache-shenyu" >}}) -* [使用 Higress 代理 Dubbo 流量]({{< relref "../../../../blog/integration/how-to-proxy-dubbo-in-higress" >}}) - -## 背景 - -[Apache Dubbo](/zh-cn/) 是由阿里巴巴开源并捐赠给 Apache 的微服务开发框架,它提供了 RPC 通信与微服务治理两大关键能力。不仅经过了阿里电商场景中海量流量的验证,也在国内的技术公司中被广泛落地。 - -在实际应用场景中,Apache Dubbo 一般会作为后端系统间 RPC 调用的实现框架,当需要提供 HTTP 接口给到前端时,会通过一个「胶水层」将 Dubbo Service 包装成 HTTP 接口,再交付到前端系统。 - -[Apache APISIX](https://apisix.apache.org/) 是 Apache 软件基金会的顶级开源项目,也是当前最活跃的开源网关项目。作为一个动态、实时、高性能的开源 API 网关,Apache APISIX 提供了负载均衡、动态上游、灰度发布、服务熔断、身份认证、可观测性等丰富的流量管理功能。 - -得益于 Apache Dubbo 的应用场景优势,Apache APISIX 基于开源项目 tengine/mod_dubbo 模块为 Apache Dubbo 服务配备了HTTP 网关能力。通过 dubbo-proxy 插件,可以轻松地将 Dubbo Service 发布为 HTTP 服务。 - -![架构图](/imgs/blog/apisix-plugin/1.png) - -## 如何使用 - -### 入门篇:安装使用 - ->这里我们建议使用 Apache APISIX 2.11 版本镜像进行安装。该版本的 APISIX-Base 中已默认编译了 Dubbo 模块,可直接使用 `dubbo-proxy` 插件。 - -在接下来的操作中,我们将使用 [`dubbo-samples`](https://github.com/apache/dubbo-samples) 项目进行部分展示。该项目是一些使用 Apache Dubbo 实现的 Demo 应用,本文中我们采用其中的一个子模块作为 Dubbo Provider。 - -在进入正式操作前,我们先简单看下 Dubbo 接口的定义、配置以及相关实现。 - -#### 接口实现一览 - -```java -public interface DemoService { - - /** - * standard samples dubbo infterace demo - * @param context pass http infos - * @return Map pass to response http - **/ - Map apisixDubbo(Map httpRequestContext); -} -``` - -如上所示,Dubbo 接口的定义是固定的。即方法参数中 `Map` 表示 APISIX 传递给 Dubbo Provider 关于 HTTP request 的一些信息(如:header、body...)。而方法返回值的 `Map` 表示 Dubbo Provider 传递给 APISIX 要如何返回 HTTP response 的一些信息。 - -接口信息配置好之后可通过 XML 配置方式发布 DemoService。 - -```xml - - - - - -``` - -通过上述配置后,Consumer 可通过 `org.apache.dubbo.samples.apisix.DemoService` 访问其中的`apisixDubbo` 方法。具体接口实现如下: - -```java -public class DemoServiceImpl implements DemoService { - @Override - public Map apisixDubbo(Map httpRequestContext) { - for (Map.Entry entry : httpRequestContext.entrySet()) { - System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue()); - } - - Map ret = new HashMap(); - ret.put("body", "dubbo success\n"); // http response body - ret.put("status", "200"); // http response status - ret.put("test", "123"); // http response header - - return ret; - } -} -``` - -上述代码中,`DemoServiceImpl` 会打印接收到的 `httpRequestContext`,并通过返回包含有指定 Key 的 Map 对象去描述该 Dubbo 请求的 HTTP 响应。 - -#### 操作步骤 - -1. 启动 [`dubbo-samples`](https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-tengine#install-dubbo)。 -2. 在 `config.yaml` 文件中进行 `dubbo-proxy` 插件启用。 - -```yaml -# Add this in config.yaml -plugins: - - ... # plugin you need - - dubbo-proxy -``` - -3. 创建指向 Dubbo Provider 的 Upstream。 - -```shell -curl http://127.0.0.1:9180/apisix/admin/upstreams/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d ' -{ - "nodes": { - "127.0.0.1:20880": 1 - }, - "type": "roundrobin" -}' -``` - -4. 为 DemoService 暴露一个 HTTP 路由。 - -```shell -curl http://127.0.0.1:9180/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d ' -{ - "host": "example.org" - "uris": [ - "/demo" - ], - "plugins": { - "dubbo-proxy": { - "service_name": "org.apache.dubbo.samples.apisix.DemoService", - "service_version": "0.0.0", - "method": "apisixDubbo" - } - }, - "upstream_id": 1 -}' -``` - -5. 使用 curl 命令请求 Apache APISIX,并查看返回结果。 - -```shell -curl http://127.0.0.1:9080/demo -H "Host: example.org" -X POST --data '{"name": "hello"}' - -< HTTP/1.1 200 OK -< Date: Sun, 26 Dec 2021 11:33:27 GMT -< Content-Type: text/plain; charset=utf-8 -< Content-Length: 14 -< Connection: keep-alive -< test: 123 -< Server: APISIX/2.11.0 -< -dubbo success -``` - -:::note 说明 -上述代码返回中包含了 `test: 123` Header,以及 `dubbo success` 字符串作为 Body 体。这与我们在 `DemoServiceImpl` 编码的预期效果一致。 -::: - -6. 查看 Dubbo Provider 的日志。 - -``` -Key = content-length, Value = 17 -Key = host, Value = example.org -Key = content-type, Value = application/x-www-form-urlencoded -Key = body, Value = [B@70754265 -Key = accept, Value = */* -Key = user-agent, Value = curl/7.80.0 -``` - -:::note 说明 -通过 `httpRequestContext` 可以拿到 HTTP 请求的 Header 和 Body。其中 Header 会作为 Map 元素,而 Body 中 Key 值是固定的字符串"body",Value 则代表 Byte 数组。 -::: - -### 进阶篇:复杂场景示例 - -在上述的简单用例中可以看出,我们确实通过 Apache APISIX 将 Dubbo Service 发布为一个 HTTP 服务,但是在使用过程中的限制也非常明显。比如:接口的参数和返回值都必须要是 `Map`。 - -那么,如果项目中出现已经定义好、但又不符合上述限制的接口,该如何通过 Apache APISIX 来暴露 HTTP 服务呢? - -#### 操作步骤 - -针对上述场景,我们可以通过 HTTP Request Body 描述要调用的 Service 和 Method 以及对应参数,再利用 Java 的反射机制实现目标方法的调用。最后将返回值序列化为 JSON,并写入到 HTTP Response Body 中。 - -这样就可以将 Apache APISIX 的 「HTTP to Dubbo」 能力进一步加强,并应用到所有已存在的 Dubbo Service 中。具体操作可参考下方: - -1. 为已有项目增加一个 Dubbo Service 用来统一处理 HTTP to Dubbo 的转化。 - -```java -public class DubboInvocationParameter { - private String type; - private String value; -} - -public class DubboInvocation { - private String service; - private String method; - private DubboInvocationParameter[] parameters; -} - -public interface HTTP2DubboService { - Map invoke(Map context) throws Exception; -} - - -@Component -public class HTTP2DubboServiceImpl implements HTTP2DubboService { - - @Autowired - private ApplicationContext appContext; - - @Override - public Map invoke(Map context) throws Exception { - DubboInvocation invocation = JSONObject.parseObject((byte[]) context.get("body"), DubboInvocation.class); - Object[] args = new Object[invocation.getParameters().size()]; - for (int i = 0; i < args.length; i++) { - DubboInvocationParameter parameter = invocation.getParameters().get(i); - args[i] = JSONObject.parseObject(parameter.getValue(), Class.forName(parameter.getType())); - } - - Object svc = appContext.getBean(Class.forName(invocation.getService())); - Object result = svc.getClass().getMethod(invocation.getMethod()).invoke(args); - Map httpResponse = new HashMap<>(); - httpResponse.put("status", 200); - httpResponse.put("body", JSONObject.toJSONString(result)); - return httpResponse; - } - -} -``` - -2. 通过如下命令请求来发起相关调用。 - -```shell -curl http://127.0.0.1:9080/demo -H "Host: example.org" -X POST --data ' -{ - "service": "org.apache.dubbo.samples.apisix.DemoService", - "method": "createUser", - "parameters": [ - { - "type": "org.apache.dubbo.samples.apisix.User", - "value": "{'name': 'hello'}" - } - ] -}' -``` - -## 总结 - -本文为大家介绍了如何借助 Apache APISIX 实现 Dubbo Service 的代理,通过引入 `dubbo-proxy` 插件便可为 Dubbo 框架的后端系统构建更简单更高效的流量链路。 - -希望通过上述操作步骤和用例场景分享,能为大家在相关场景的使用提供借鉴思路。更多关于 `dubbo-proxy` 插件的介绍与使用可参考[官方文档](https://apisix.apache.org/docs/apisix/plugins/dubbo-proxy/)。 \ No newline at end of file diff --git a/content/zh-cn/overview/tasks/ecosystem/metadata-center.md b/content/zh-cn/overview/tasks/ecosystem/metadata-center.md deleted file mode 100644 index c41b7d8f77a0..000000000000 --- a/content/zh-cn/overview/tasks/ecosystem/metadata-center.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -_build: - render: link -description: "" -icon: fas fa-external-link-alt -linkTitle: 元数据中心 -manualLinkRelref: ../../mannual/java-sdk/reference-manual/metadata-center/ -manualLinkTarget: _blank -title: 元数据中心 -type: docs -weight: 31 ---- diff --git a/content/zh-cn/overview/tasks/ecosystem/registry.md b/content/zh-cn/overview/tasks/ecosystem/registry.md deleted file mode 100644 index ebf83f938835..000000000000 --- a/content/zh-cn/overview/tasks/ecosystem/registry.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -_build: - render: link -description: "" -icon: fas fa-external-link-alt -linkTitle: 注册中心 -manualLinkRelref: ../../mannual/java-sdk/reference-manual/registry/ -manualLinkTarget: _blank -title: 注册中心 -type: docs -weight: 31 ---- diff --git a/content/zh-cn/overview/tasks/ecosystem/transaction.md b/content/zh-cn/overview/tasks/ecosystem/transaction.md deleted file mode 100644 index 8519c59d063d..000000000000 --- a/content/zh-cn/overview/tasks/ecosystem/transaction.md +++ /dev/null @@ -1,312 +0,0 @@ ---- -aliases: - - /zh/overview/tasks/ecosystem/transaction/ - - /zh-cn/overview/what/ecosystem/transaction/seata/ -description: 本示例演示如何通过 Seata 实现分布式 Dubbo 服务的事务管理,保证数据一致性。 -linkTitle: 事务管理 -title: 事务管理 -type: docs -weight: 1 ---- - -## Seata 是什么 -Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案。 - -## 一、示例架构说明 -可在此查看本示例完整代码地址:dubbo-samples-seata - -用户采购商品业务,整个业务包含3个微服务: - -- 库存服务: 扣减给定商品的库存数量。 -- 订单服务: 根据采购请求生成订单。 -- 账户服务: 用户账户金额扣减。 - -![image.png](/imgs/docs3-v2/java-sdk/seata/transaction-1.png) - -### StorageService - -```java -public interface StorageService { - - /** - * 扣除存储数量 - */ - void deduct(String commodityCode, int count); -} -``` - -### OrderService - -```java -public interface OrderService { - - /** - * 创建订单 - */ - Order create(String userId, String commodityCode, int orderCount); -} -``` - -### AccountService - -```java -public interface AccountService { - - /** - * 从用户账户中借出 - */ - void debit(String userId, int money); -} -``` - -## 二、主要的业务逻辑 - -### BusinessService - -```java -public class BusinessServiceImpl implements BusinessService { - - private StorageService storageService; - - private OrderService orderService; - - /** - * 采购 - */ - public void purchase(String userId, String commodityCode, int orderCount) { - // 扣除存储数量 - storageService.deduct(commodityCode, orderCount); - // 创建订单 - orderService.create(userId, commodityCode, orderCount); - } -} -``` - -### StorageService - -```java -public class StorageServiceImpl implements StorageService { - - private JdbcTemplate jdbcTemplate; - - @Override - public void deduct(String commodityCode, int count) { - // 修改数据库:扣减存储数量 - jdbcTemplate.update("update storage_tbl set count = count - ? where commodity_code = ?", - new Object[]{count, commodityCode}); - } -} -``` - -### OrderService - -```java -public class OrderServiceImpl implements OrderService { - - private AccountService accountService; - - private JdbcTemplate jdbcTemplate; - - public Order create(String userId, String commodityCode, int orderCount) { - // 计算金额 - int orderMoney = calculate(commodityCode, orderCount); - - // 用户账户中扣减金额 - accountService.debit(userId, orderMoney); - - // 修改数据库:新建订单 - final Order order = new Order(); - order.userId = userId; - order.commodityCode = commodityCode; - order.count = orderCount; - order.money = orderMoney; - KeyHolder keyHolder = new GeneratedKeyHolder(); - jdbcTemplate.update(con -> { - PreparedStatement pst = con.prepareStatement( - "insert into order_tbl (user_id, commodity_code, count, money) values (?, ?, ?, ?)", - PreparedStatement.RETURN_GENERATED_KEYS); - pst.setObject(1, order.userId); - pst.setObject(2, order.commodityCode); - pst.setObject(3, order.count); - pst.setObject(4, order.money); - return pst; - }, keyHolder); - order.id = keyHolder.getKey().longValue(); - return order; - } -} -``` - -### AccountService - - -```java -public class AccountServiceImpl implements AccountService { - - private JdbcTemplate jdbcTemplate; - - @Override - public void debit(String userId, int money) { - // 修改数据库:用户账户中扣减金额 - jdbcTemplate.update("update account_tbl set money = money - ? where user_id = ?", new Object[]{money, userId}); - } -} -``` - -## 三、快速启动示例 - -### Step 1: 下载源码 - -```shell script -git clone -b master https://github.com/apache/dubbo-samples.git -cd ./dubbo-samples-transaction/ -``` - -### Step 2: 通过 docker-compose 启动 Seata-Server 和 MySQL 等 - -在此示例中,我们使用 docker-compose 快速拉起 seata-server 和 mysql 等服务。 - -```bash -cd src/main/resources/docker -docker-compose up -``` - -### Step 3: 构建用例 - -执行 maven 命令,打包 demo 工程 - -```bash -mvn clean package -``` - -### Step 4: 启动 AccountService - -```java -java -classpath ./target/dubbo-samples-transaction-1.0-SNAPSHOT.jar org.apache.dubbo.samples.starter.DubboAccountServiceStarter -``` - -### Step 5: 启动 OrderService - -```java -java -classpath ./target/dubbo-samples-transaction-1.0-SNAPSHOT.jar org.apache.dubbo.samples.starter.DubboOrderServiceStarter -``` -### Step 6: 启动 StorageService - -```java -java -classpath ./target/dubbo-samples-transaction-1.0-SNAPSHOT.jar org.apache.dubbo.samples.starter.DubboStorageServiceStarter -``` - -### Step 7: 启动 BusinessService -```java -java -classpath ./target/dubbo-samples-transaction-1.0-SNAPSHOT.jar org.apache.dubbo.samples.starter.DubboBusinessTester -``` - -## 四、示例核心流程 - -![image.png](/imgs/docs3-v2/java-sdk/seata/transaction-2.png) - -### Step 1: 修改业务代码 -此处仅仅需要一行注解 `@GlobalTransactional` 写在业务发起方的方法上: - -```java - @GlobalTransactional - public void purchase(String userId, String commodityCode, int orderCount) { - ...... - } -``` - -### Step 2: 安装数据库 - -- 要求: MySQL (InnoDB 存储引擎)。 - -**提示:** 事实上例子中3个微服务需要3个独立的数据库,但为了方便我们使用同一物理库并配置3个逻辑连接串。 - -更改以下xml文件中的数据库url、username和password - -dubbo-account-service.xml -dubbo-order-service.xml -dubbo-storage-service.xml - -```xml - - - -``` - -### Step 3: 为 Seata 创建 undo_log 表 - -`UNDO_LOG` 此表用于 Seata 的AT模式。 - -```sql --- 注意当 Seata 版本升级至 0.3.0+ 将由之前的普通索引变更为唯一索引。 -CREATE TABLE `undo_log` ( - `id` bigint(20) NOT NULL AUTO_INCREMENT, - `branch_id` bigint(20) NOT NULL, - `xid` varchar(100) NOT NULL, - `context` varchar(128) NOT NULL, - `rollback_info` longblob NOT NULL, - `log_status` int(11) NOT NULL, - `log_created` datetime NOT NULL, - `log_modified` datetime NOT NULL, - `ext` varchar(100) DEFAULT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`) -) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; -``` - -### Step 4: 创建相关业务表 - -```sql - -DROP TABLE IF EXISTS `storage_tbl`; -CREATE TABLE `storage_tbl` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `commodity_code` varchar(255) DEFAULT NULL, - `count` int(11) DEFAULT 0, - PRIMARY KEY (`id`), - UNIQUE KEY (`commodity_code`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - - -DROP TABLE IF EXISTS `order_tbl`; -CREATE TABLE `order_tbl` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `user_id` varchar(255) DEFAULT NULL, - `commodity_code` varchar(255) DEFAULT NULL, - `count` int(11) DEFAULT 0, - `money` int(11) DEFAULT 0, - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - - -DROP TABLE IF EXISTS `account_tbl`; -CREATE TABLE `account_tbl` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `user_id` varchar(255) DEFAULT NULL, - `money` int(11) DEFAULT 0, - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; -``` - -### Step 5: 启动 Seata-Server 服务 - -- 下载[服务器软件包](https://github.com/seata/seata/releases),将其解压缩。 - -```shell -Usage: sh seata-server.sh(for linux and mac) or cmd seata-server.bat(for windows) [options] - Options: - --host, -h - The host to bind. - Default: 0.0.0.0 - --port, -p - The port to listen. - Default: 8091 - --storeMode, -m - log store mode : file、db - Default: file - --help - -e.g. - -sh seata-server.sh -p 8091 -h 127.0.0.1 -m file -``` \ No newline at end of file diff --git a/content/zh-cn/overview/tasks/extensibility/_index.md b/content/zh-cn/overview/tasks/extensibility/_index.md deleted file mode 100755 index d21e634fdc99..000000000000 --- a/content/zh-cn/overview/tasks/extensibility/_index.md +++ /dev/null @@ -1,103 +0,0 @@ ---- -aliases: - - /zh/overview/tasks/extensibility/ -description: 演示 Dubbo 扩展能力特性的使用方式。 -linkTitle: 自定义扩展 -no_list: true -title: 自定义扩展 -type: docs -weight: 7 ---- - - - -## Dubbo 扩展设计理念 - -* 平等对待第三方的实现。在 Dubbo 中,所有内部实现和第三方实现都是平等的,用户可以基于自身业务需求,替换 Dubbo 提供的原生实现。 -* 每个扩展点只封装一个变化因子,最大化复用。每个扩展点的实现者,往往都只是关心一件事。如果用户有需求需要进行扩展,那么只需要对其关注的扩展点进行扩展就好,极大的减少用户的工作量。 - -## 基于 Java SPI 的扩展能力设计 - -Dubbo 中的扩展能力是从 JDK 标准的 SPI 扩展点发现机制加强而来,它改进了 JDK 标准的 SPI 以下问题: - -* JDK 标准的 SPI 会一次性实例化扩展点所有实现,如果有扩展实现初始化很耗时,但如果没用上也加载,会很浪费资源。 -* 如果扩展点加载失败,连扩展点的名称都拿不到了。比如:JDK 标准的 ScriptEngine,通过 getName() 获取脚本类型的名称,但如果 RubyScriptEngine 因为所依赖的 jruby.jar 不存在,导致 RubyScriptEngine 类加载失败,这个失败原因被吃掉了,和 ruby 对应不起来,当用户执行 ruby 脚本时,会报不支持 ruby,而不是真正失败的原因。 - -用户能够基于 Dubbo 提供的扩展能力,很方便基于自身需求扩展其他协议、过滤器、路由等。下面介绍下 Dubbo 扩展能力的特性。 - -* 按需加载。Dubbo 的扩展能力不会一次性实例化所有实现,而是用哪个扩展类则实例化哪个扩展类,减少资源浪费。 -* 增加扩展类的 IOC 能力。Dubbo 的扩展能力并不仅仅只是发现扩展服务实现类,而是在此基础上更进一步,如果该扩展类的属性依赖其他对象,则 Dubbo 会自动的完成该依赖对象的注入功能。 -* 增加扩展类的 AOP 能力。Dubbo 扩展能力会自动的发现扩展类的包装类,完成包装类的构造,增强扩展类的功能。 -* 具备动态选择扩展实现的能力。Dubbo 扩展会基于参数,在运行时动态选择对应的扩展类,提高了 Dubbo 的扩展能力。 -* 可以对扩展实现进行排序。能够基于用户需求,指定扩展实现的执行顺序。 -* 提供扩展点的 Adaptive 能力。该能力可以使的一些扩展类在 consumer 端生效,一些扩展类在 provider 端生效。 - -从 Dubbo 扩展的设计目标可以看出,Dubbo 实现的一些例如动态选择扩展实现、IOC、AOP 等特性,能够为用户提供非常灵活的扩展能力。 - -### 扩展点加载流程 - -Dubbo 加载扩展的整个流程如下: - -![//imgs/v3/concepts/extension-load.png](/imgs/v3/concepts/extension-load.png) - -主要步骤为 4 个: -* 读取并解析配置文件 -* 缓存所有扩展实现 -* 基于用户执行的扩展名,实例化对应的扩展实现 -* 进行扩展实例属性的 IOC 注入以及实例化扩展的包装类,实现 AOP 特性 - -## 任务项 - -接下来,通过如下任务项分别来介绍 Dubbo 的扩展特性。 - -{{< blocks/section color="white" height="auto">}} -
-
-
-
-
-

- 自定义过滤器 -

-

通过SPI机制动态加载自定义过滤器,可以对返回的结果进行统一的处理、验证等,减少对开发人员的打扰。

-
-
-
-
-
-
-

- 自定义路由 -

-

在服务调用的过程中根据实际使用场景自定义路由策略,可以有效的改善服务吞吐量和耗时。

-
-
-
-
-
-
-

- 自定义协议 -

-

针对不同的异构系统可以使用自定义传输协议,为系统之间的整合屏蔽了协议之间的差异。 -

-
-
-
-
-
-
-

- 自定义注册中心 -

-

将不同注册中心中的服务都纳入到 Dubbo 体系中,自定义注册中心是打通异构服务体系之间的利刃。 -

-
-
-
-
-
-
- -{{< /blocks/section >}} diff --git a/content/zh-cn/overview/tasks/extensibility/filter.md b/content/zh-cn/overview/tasks/extensibility/filter.md deleted file mode 100644 index cae9192e3235..000000000000 --- a/content/zh-cn/overview/tasks/extensibility/filter.md +++ /dev/null @@ -1,158 +0,0 @@ ---- -aliases: - - /zh/overview/tasks/extensibility/filter/ -description: 自定义过滤器 -linkTitle: Filter -no_list: true -title: Filter -type: docs -weight: 1 ---- - - - -通过自定义过滤器,可以对返回的结果进行统一的处理、验证等,减少对开发人员的打扰。 - -## 开始之前 - -有两种部署运行方式,二选一 -### 基于Kubernetes -* 安装[Kubernetes](https://kubernetes.io/docs/tasks/tools/)环境 -* 修改[Provider](https://github.com/apache/dubbo-samples/blob/master/10-task/dubbo-samples-extensibility/dubbo-samples-extensibility-filter-provider/src/main/resources/application.properties)中的配置文件,启用Kubernetes中部署的nacos的地址 - ```properties - # Specify the application name of Dubbo - dubbo.application.name=extensibility-filter-provider - - # Enable token verification for each invocation - dubbo.provider.token=true - - # Specify the registry address - # dubbo.registry.address=nacos://localhost:8848?username=nacos&password=nacos - # 启用Kubernetes中部署的nacos的地址 - dubbo.registry.address=nacos://${nacos.address:localhost}:8848?username=nacos&password=nacos - - # Specify the port of Dubbo protocol - dubbo.protocol.port=20881 - - # Apply AppendedFilter - dubbo.provider.filter=appended - ``` -* 修改[Consumer](https://github.com/apache/dubbo-samples/blob/master/10-task/dubbo-samples-extensibility/dubbo-samples-extensibility-filter-consumer/src/main/resources/application.properties)中的配置文件,启用Kubernetes中部署的nacos的地址 - ```properties - # Specify the application name of Dubbo - dubbo.application.name=extensibility-filter-consumer - - # Enable token verification for each invocation - dubbo.provider.token=true - - # Specify the registry address - # dubbo.registry.address=nacos://localhost:8848?username=nacos&password=nacos - # 启用Kubernetes中部署的nacos的地址 - dubbo.registry.address=nacos://${nacos.address:localhost}:8848?username=nacos&password=nacos - ``` -* 部署`[Extensibility Filter Task](https://github.com/apache/dubbo-samples/blob/master/10-task/dubbo-samples-extensibility/deploy/All.yml)` - -### 使用本地IDE -* 部署[Nacos](https://nacos.io/zh-cn/docs/quick-start.html)2.2.0版本 -* 修改[Provider](https://github.com/apache/dubbo-samples/blob/master/10-task/dubbo-samples-extensibility/dubbo-samples-extensibility-filter-provider/src/main/resources/application.properties)中的配置文件,启用本地nacos的地址 - ```properties - # Specify the application name of Dubbo - dubbo.application.name=extensibility-filter-provider - - # Enable token verification for each invocation - dubbo.provider.token=true - - # Specify the registry address - # 启用本地nacos的地址 - dubbo.registry.address=nacos://localhost:8848?username=nacos&password=nacos - # dubbo.registry.address=nacos://${nacos.address:localhost}:8848?username=nacos&password=nacos - - # Specify the port of Dubbo protocol - dubbo.protocol.port=20881 - - # Apply AppendedFilter - dubbo.provider.filter=appended - ``` -* 修改[Consumer](https://github.com/apache/dubbo-samples/blob/master/10-task/dubbo-samples-extensibility/dubbo-samples-extensibility-filter-consumer/src/main/resources/application.properties)中的配置文件,启用本地nacos的地址 - ```properties - # Specify the application name of Dubbo - dubbo.application.name=extensibility-filter-consumer - - # Enable token verification for each invocation - dubbo.provider.token=true - - # Specify the registry address - # 启用本地nacos的地址 - dubbo.registry.address=nacos://localhost:8848?username=nacos&password=nacos - # dubbo.registry.address=nacos://${nacos.address:localhost}:8848?username=nacos&password=nacos - ``` - -## 任务详情 - -对所有调用Provider服务的请求在返回的结果的后面统一添加`'s customized AppendedFilter`。 - -## 实现方式 - -在Provider中自定义一个Filter,在Filter中修改返回结果。 - -#### 代码结构 -```properties -src - |-main - |-java - |-org - |-apache - |-dubbo - |-samples - |-extensibility - |-filter - |-provider - |-AppendedFilter.java (实现Filter接口) - |-resources - |-META-INF - |-application.properties (Dubbo Provider配置文件) - |-dubbo - |-org.apache.dubbo.rpc.Filter (纯文本文件) -``` -#### 代码详情 -```java -package org.apache.dubbo.samples.extensibility.filter.provider; - -import org.apache.dubbo.rpc.Filter; -import org.apache.dubbo.rpc.Result; -import org.apache.dubbo.rpc.Invoker; -import org.apache.dubbo.rpc.Invocation; -import org.apache.dubbo.rpc.RpcException; -import org.apache.dubbo.rpc.AsyncRpcResult; - -public class AppendedFilter implements Filter { - - @Override - public Result invoke(Invoker invoker, Invocation invocation) throws RpcException { - Result result= invoker.invoke(invocation); - // Obtain the returned value - Result appResponse = ((AsyncRpcResult) result).getAppResponse(); - // Appended value - appResponse.setValue(appResponse.getValue()+"'s customized AppendedFilter"); - return result; - } -} -``` - -#### SPI配置 -在`resources/META-INF/dubbo/org.apache.dubbo.rpc.Filter`文件中添加如下配置: -```properties -appended=org.apache.dubbo.samples.extensibility.filter.provider.AppendedFilter -``` - -#### 配置文件 -在`resources/application.properties`文件中添加如下配置: -```properties -# Apply AppendedFilter -dubbo.provider.filter=appended -``` - -## 运行结果 -以**使用本地IDE**的方式来运行任务,结果如下: - -![dubbo-samples-extensibility-filter-output.jpg](/imgs/v3/tasks/extensibility/dubbo-samples-extensibility-filter-output.jpg) diff --git a/content/zh-cn/overview/tasks/extensibility/protocol.md b/content/zh-cn/overview/tasks/extensibility/protocol.md deleted file mode 100644 index ae4bb34b5f01..000000000000 --- a/content/zh-cn/overview/tasks/extensibility/protocol.md +++ /dev/null @@ -1,274 +0,0 @@ ---- -aliases: - - /zh/overview/tasks/extensibility/protocol/ -description: 自定义协议 -linkTitle: Protocol -no_list: true -title: Protocol -type: docs -weight: 2 ---- - -Dubbo 通过协议扩展实现了很多内置的功能,同时也支持很多常用的协议。所有的自定义协议在`org.apache.dubbo.rpc.Protocol`文件中可以看到,以Dubbo 3为例,具体如下: - -```properties -# Dubbo通过协议扩展实现的内置功能 -filter=org.apache.dubbo.rpc.cluster.filter.ProtocolFilterWrapper -qos=org.apache.dubbo.qos.protocol.QosProtocolWrapper -registry=org.apache.dubbo.registry.integration.InterfaceCompatibleRegistryProtocol -service-discovery-registry=org.apache.dubbo.registry.integration.RegistryProtocol -listener=org.apache.dubbo.rpc.protocol.ProtocolListenerWrapper -mock=org.apache.dubbo.rpc.support.MockProtocol -serializationwrapper=org.apache.dubbo.rpc.protocol.ProtocolSerializationWrapper -securitywrapper=org.apache.dubbo.rpc.protocol.ProtocolSecurityWrapper - -# Dubbo对外支持的常用协议 -dubbo=org.apache.dubbo.rpc.protocol.dubbo.DubboProtocol -injvm=org.apache.dubbo.rpc.protocol.injvm.InjvmProtocol -rest=org.apache.dubbo.rpc.protocol.rest.RestProtocol -grpc=org.apache.dubbo.rpc.protocol.grpc.GrpcProtocol -tri=org.apache.dubbo.rpc.protocol.tri.TripleProtocol -``` - -我们可以看到,在Dubbo中通过协议扩展的能力实现了过滤、监控数据采集、服务发现、监听器、mock、序列化、安全等一系列能力,同时对外提供了`dubbo`,`injvm`,`rest`,`grpc`和`tri`协议。 - -自定义一套私有协议有两种方式,第一种是对原有的协议进行包装,添加一些特定的业务逻辑。另外一种是完全自定义一套协议。前者实现简单,在`dubbo`中也是有广泛的使用,比如:`ProtocolFilterWrapper`, `QosProtocolWrapper`, `ProtocolListenerWrapper`等。后者实现复杂,一般常见的协议`dubbo`都实现了,并且通过了大量生产实践的验证。 - -本文会通过示例演示如何通过现有协议实现一套自定义协议。 - -## 开始之前 - -有两种部署运行方式,二选一 -### 基于Kubernetes -* 安装[Kubernetes](https://kubernetes.io/docs/tasks/tools/)环境 -* 修改[Provider](https://github.com/apache/dubbo-samples/blob/master/10-task/dubbo-samples-extensibility/dubbo-samples-extensibility-protocol-provider/src/main/resources/application.properties)中的配置文件,启用Kubernetes中部署的nacos的地址 - ```properties - # Specify the application name of Dubbo - dubbo.application.name=extensibility-protocol-provider - - # Enable token verification for each invocation - dubbo.provider.token=true - - # Specify the registry address - # dubbo.registry.address=nacos://localhost:8848?username=nacos&password=nacos - dubbo.registry.address=nacos://${nacos.address:localhost}:8848?username=nacos&password=nacos - - # 自定义协议edubbo - dubbo.provider.protocol=edubbo - ``` -* 修改[Consumer](https://github.com/apache/dubbo-samples/blob/master/10-task/dubbo-samples-extensibility/dubbo-samples-extensibility-protocol-consumer/src/main/resources/application.properties)中的配置文件,启用Kubernetes中部署的nacos的地址 - ```properties - # Specify the application name of Dubbo - dubbo.application.name=extensibility-protocol-consumer - - # Enable token verification for each invocation - dubbo.provider.token=true - - # Specify the registry address - # dubbo.registry.address=nacos://localhost:8848?username=nacos&password=nacos - dubbo.registry.address=nacos://${nacos.address:localhost}:8848?username=nacos&password=nacos - - # 自定义协议edubbo - dubbo.consumer.protocol=edubbo - ``` -* 部署`[Extensibility Protocol Task](https://github.com/apache/dubbo-samples/blob/master/10-task/dubbo-samples-extensibility/deploy/All.yml)` - -### 使用本地IDE -* 部署[Nacos](https://nacos.io/zh-cn/docs/quick-start.html)2.2.0版本 -* 修改[Provider](https://github.com/apache/dubbo-samples/blob/master/10-task/dubbo-samples-extensibility/dubbo-samples-extensibility-protocol-provider/src/main/resources/application.properties)中的配置文件,启用本地nacos的地址 - ```properties - # Specify the application name of Dubbo - dubbo.application.name=extensibility-protocol-provider - - # Enable token verification for each invocation - dubbo.provider.token=true - - # Specify the registry address - # 启用本地nacos的地址 - dubbo.registry.address=nacos://localhost:8848?username=nacos&password=nacos - # dubbo.registry.address=nacos://${nacos.address:localhost}:8848?username=nacos&password=nacos - - # 自定义协议edubbo - dubbo.provider.protocol=edubbo - ``` -* 修改[Consumer](https://github.com/apache/dubbo-samples/blob/master/10-task/dubbo-samples-extensibility/dubbo-samples-extensibility-protocol-consumer/src/main/resources/application.properties)中的配置文件,启用本地nacos的地址 - ```properties - # Specify the application name of Dubbo - dubbo.application.name=extensibility-protocol-consumer - - # Enable token verification for each invocation - dubbo.provider.token=true - - # Specify the registry address - # 启用本地nacos的地址 - dubbo.registry.address=nacos://localhost:8848?username=nacos&password=nacos - # dubbo.registry.address=nacos://${nacos.address:localhost}:8848?username=nacos&password=nacos - - # 自定义协议edubbo - dubbo.consumer.protocol=edubbo - ``` - -## 任务详情 - -基于现有的`dubbo`协议来实现自定义协议`edubbo`。 - -## 实现方式 - -通过对`dubbo`协议进行包装来实现`edubbo`协议。 - -#### 代码结构 - -##### Common - -```properties -src - |-main - |-java - |-org - |-apache - |-dubbo - |-samples - |-extensibility - |-protocol - |-common - |-EnhancedProtocol.java (实现Protocol接口) -``` - -##### Provider -```properties -src - |-main - |-java - |-org - |-apache - |-dubbo - |-samples - |-extensibility - |-protocol - |-provider - |-ExtensibilityProtocolProviderApplication.java - |-ExtensibilityProtocolServiceImpl.java - |-resources - |-META-INF - |-application.properties (Dubbo Provider配置文件) - |-dubbo - |-org.apache.dubbo.rpc.Protocol (纯文本文件) -``` - -##### Consumer -```properties -src - |-main - |-java - |-org - |-apache - |-dubbo - |-samples - |-extensibility - |-protocol - |-consumer - |-ExtensibilityProtocolConsumerApplication.java - |-ExtensibilityProtocolConsumerTask.java - |-resources - |-META-INF - |-application.properties (Dubbo Consumer配置文件) - |-dubbo - |-org.apache.dubbo.rpc.Protocol (纯文本文件) -``` - -#### 代码详情 -```java -package org.apache.dubbo.samples.extensibility.protocol.common; - -import org.apache.dubbo.common.URL; -import org.apache.dubbo.rpc.Protocol; -import org.apache.dubbo.rpc.Invoker; -import org.apache.dubbo.rpc.Exporter; -import org.apache.dubbo.rpc.ProtocolServer; -import org.apache.dubbo.rpc.RpcException; -import org.apache.dubbo.rpc.model.FrameworkModel; -import org.apache.dubbo.rpc.protocol.dubbo.DubboProtocol; - -import java.util.List; - -public class EnhancedProtocol implements Protocol { - - public EnhancedProtocol(FrameworkModel frameworkModel) { - this.protocol = new DubboProtocol(frameworkModel); - } - - private final Protocol protocol; - - @Override - public int getDefaultPort() { - return this.protocol.getDefaultPort(); - } - - @Override - public Exporter export(Invoker invoker) throws RpcException { - // do something - return this.protocol.export(invoker); - } - - @Override - public Invoker refer(Class type, URL url) throws RpcException { - // do something - return this.protocol.refer(type, url); - } - - @Override - public void destroy() { - this.protocol.destroy(); - } - - @Override - public List getServers() { - return protocol.getServers(); - } -} -``` - -#### SPI配置 - -##### Provider - -在`resources/META-INF/dubbo/org.apache.dubbo.rpc.Protocol`文件中添加如下配置: -```properties -edubbo=org.apache.dubbo.samples.extensibility.protocol.common.EnhancedProtocol -``` - -##### Consumer - -在`resources/META-INF/dubbo/org.apache.dubbo.rpc.Protocol`文件中添加如下配置: -```properties -edubbo=org.apache.dubbo.samples.extensibility.protocol.common.EnhancedProtocol -``` - -#### 配置文件 - -##### Provider - -在`resources/application.properties`文件中添加如下配置: -```properties -# 自定义协议 -dubbo.provider.protocol=edubbo -``` - -##### Consumer - -在`resources/application.properties`文件中添加如下配置: -```properties -# 自定义协议 -dubbo.consumer.protocol=edubbo -``` - -## 运行结果 -以**使用本地IDE**的方式来运行任务,结果如下: - -#### 注册协议 - -![dubbo-samples-extensibility-protocol-output2.jpg](/imgs/v3/tasks/extensibility/dubbo-samples-extensibility-protocol-output2.jpg) - -#### 输出结果 - -![dubbo-samples-extensibility-protocol-output1.png](/imgs/v3/tasks/extensibility/dubbo-samples-extensibility-protocol-output1.png) diff --git a/content/zh-cn/overview/tasks/extensibility/registry.md b/content/zh-cn/overview/tasks/extensibility/registry.md deleted file mode 100644 index 5b1488a57c25..000000000000 --- a/content/zh-cn/overview/tasks/extensibility/registry.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -aliases: - - /zh/overview/tasks/extensibility/registry/ -description: 自定义注册中心 -linkTitle: Registry -no_list: true -title: Registry -type: docs -weight: 3 ---- - -文档编写中... diff --git a/content/zh-cn/overview/tasks/extensibility/router.md b/content/zh-cn/overview/tasks/extensibility/router.md deleted file mode 100644 index dc49fecbd425..000000000000 --- a/content/zh-cn/overview/tasks/extensibility/router.md +++ /dev/null @@ -1,220 +0,0 @@ ---- -aliases: - - /zh/overview/tasks/extensibility/router/ -description: 自定义路由策略 -linkTitle: Router -no_list: true -title: Router -type: docs -weight: 4 ---- - - - -通过自定义路由,可以根据业务场景的特点来实现特定的路由方式。 - -## 开始之前 - -有两种部署运行方式,二选一 -### 基于Kubernetes -* 安装[Kubernetes](https://kubernetes.io/docs/tasks/tools/)环境 -* 修改[Provider](https://github.com/apache/dubbo-samples/blob/master/10-task/dubbo-samples-extensibility/dubbo-samples-extensibility-router-provider/src/main/resources/application.properties)中的配置文件,启用Kubernetes中部署的nacos的地址 - ```properties - # Specify the application name of Dubbo - dubbo.application.name=extensibility-router-provider - - # Enable token verification for each invocation - dubbo.provider.token=true - - # Specify the registry address - # dubbo.registry.address=nacos://localhost:8848?username=nacos&password=nacos - # 启用Kubernetes中部署的nacos的地址 - dubbo.registry.address=nacos://${nacos.address:localhost}:8848?username=nacos&password=nacos - # Specify the port of Dubbo protocol - dubbo.protocol.port=20881 - ``` -* 修改[Consumer](https://github.com/apache/dubbo-samples/blob/master/10-task/dubbo-samples-extensibility/dubbo-samples-extensibility-filter-consumer/src/main/resources/application.properties)中的配置文件,启用Kubernetes中部署的nacos的地址 - ```properties - # Specify the application name of Dubbo - dubbo.application.name=extensibility-filter-consumer - - # Enable token verification for each invocation - dubbo.provider.token=true - - # Specify the registry address - #dubbo.registry.address=nacos://localhost:8848?username=nacos&password=nacos - # 启用Kubernetes中部署的nacos的地址 - dubbo.registry.address=nacos://${nacos.address:localhost}:8848?username=nacos&password=nacos - # 配置自定义路由 - dubbo.consumer.router=stickfirst - ``` -* 部署[Extensibility Router Task](https://github.com/apache/dubbo-samples/blob/master/10-task/dubbo-samples-extensibility/deploy/All.yml) - -### 使用本地IDE -* 部署[Nacos](https://nacos.io/zh-cn/docs/quick-start.html)2.2.0版本 -* 修改[Provider](https://github.com/apache/dubbo-samples/blob/master/10-task/dubbo-samples-extensibility/dubbo-samples-extensibility-filter-provider/src/main/resources/application.properties)中的配置文件,启用本地nacos的地址 - ```properties - # Specify the application name of Dubbo - dubbo.application.name=extensibility-router-provider - - # Enable token verification for each invocation - dubbo.provider.token=true - - # Specify the registry address - # 启用本地nacos的地址 - dubbo.registry.address=nacos://localhost:8848?username=nacos&password=nacos - # dubbo.registry.address=nacos://${nacos.address:localhost}:8848?username=nacos&password=nacos - - # Specify the port of Dubbo protocol - dubbo.protocol.port=20881 - ``` -* 修改[Consumer](https://github.com/apache/dubbo-samples/blob/master/10-task/dubbo-samples-extensibility/dubbo-samples-extensibility-filter-consumer/src/main/resources/application.properties)中的配置文件,启用本地nacos的地址 - ```properties - # Specify the application name of Dubbo - dubbo.application.name=extensibility-filter-consumer - - # Enable token verification for each invocation - dubbo.provider.token=true - - # Specify the registry address - # 启用本地nacos的地址 - dubbo.registry.address=nacos://localhost:8848?username=nacos&password=nacos - #dubbo.registry.address=nacos://${nacos.address:localhost}:8848?username=nacos&password=nacos - - # 配置自定义路由 - dubbo.consumer.router=stickfirst - ``` - -## 任务详情 - -对所有的请求都使用第一提供服务的Provider,如果该Provider下线,则从新选择一个新的Provider。 - -## 实现方式 - -在Consumer中自定义一个Router,在Router中将第一次调用的Provider保存下来,如果后续有请求调用且Provider列表中包含第一次调用时使用的Provider,则继续使用第一次调用时使用的Provider,否则重新选去一个Provider。 - -#### 代码结构 -```properties -src - |-main - |-java - |-org - |-apache - |-dubbo - |-samples - |-extensibility - |-router - |-consumer - |-router - |-StickFirstStateRouter.java (实现StateRouter接口) - |-StickFirstStateRouterFactory.java (实现StateRouterFactory接口) - |-resources - |-META-INF - |-application.properties (Dubbo Consumer配置文件) - |-dubbo - |-org.apache.dubbo.rpc.cluster.router.state.StateRouterFactory (纯文本文件) -``` -#### 代码详情 - -+ StickFirstStateRouter -```java -package org.apache.dubbo.samples.extensibility.router.consumer.router; - -import org.apache.dubbo.common.URL; -import org.apache.dubbo.common.config.configcenter.ConfigChangeType; -import org.apache.dubbo.common.config.configcenter.ConfigChangedEvent; -import org.apache.dubbo.common.config.configcenter.ConfigurationListener; -import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; -import org.apache.dubbo.common.logger.LoggerFactory; -import org.apache.dubbo.common.utils.CollectionUtils; -import org.apache.dubbo.common.utils.Holder; -import org.apache.dubbo.rpc.Invocation; -import org.apache.dubbo.rpc.Invoker; -import org.apache.dubbo.rpc.RpcException; -import org.apache.dubbo.rpc.cluster.router.RouterSnapshotNode; -import org.apache.dubbo.rpc.cluster.router.state.AbstractStateRouter; -import org.apache.dubbo.rpc.cluster.router.state.BitList; - -public class StickFirstStateRouter extends AbstractStateRouter implements ConfigurationListener { - public StickFirstStateRouter(URL url) { - super(url); - } - - public static final String NAME = "STICK_FIRST_ROUTER"; - private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(StickFirstStateRouter.class); - private volatile BitList> firstInvokers; - - @Override - protected BitList> doRoute(BitList> invokers, URL url, Invocation invocation, boolean needToPrintMessage, Holder> routerSnapshotNodeHolder, Holder messageHolder) throws RpcException { - if (CollectionUtils.isEmpty(invokers)) { - if (needToPrintMessage) { - messageHolder.set("Directly Return. Reason: Invokers from previous router is empty."); - } - return invokers; - } - BitList> copy = invokers.clone(); - if (CollectionUtils.isEmpty(copy)) { - this.firstInvokers = new BitList<>(BitList.emptyList()); - this.firstInvokers.add(copy.get(0)); - } else { - this.firstInvokers = copy.and(invokers); - if(CollectionUtils.isEmpty(this.firstInvokers)){ - this.firstInvokers.add(copy.get(0)); - } - } - return this.firstInvokers; - } - - @Override - public void process(ConfigChangedEvent event) { - if (logger.isDebugEnabled()) { - logger.debug("Notification of tag rule, change type is: " + event.getChangeType() + ", raw rule is:\n " + - event.getContent()); - } - // Reset - if (event.getChangeType().equals(ConfigChangeType.DELETED)) { - this.firstInvokers = null; - } - } - - @Override - public void stop() { - super.stop(); - this.firstInvokers = null; - } -} -``` - -+ StickFirstStateRouterFactory -```java -package org.apache.dubbo.samples.extensibility.router.consumer.router; - -import org.apache.dubbo.common.URL; -import org.apache.dubbo.rpc.cluster.router.state.StateRouter; -import org.apache.dubbo.rpc.cluster.router.state.StateRouterFactory; - -public class StickFirstStateRouterFactory implements StateRouterFactory { - @Override - public StateRouter getRouter(Class interfaceClass, URL url) { - return new StickFirstStateRouter<>(url); - } -} -``` - -#### SPI配置 -在`resources/META-INF/dubbo/org.apache.dubbo.rpc.cluster.router.state.StateRouterFactory`文件中添加如下配置: -```properties -stickfirst=org.apache.dubbo.samples.extensibility.router.consumer.router.StickFirstStateRouterFactory -``` - -#### 配置文件 -在`resources/application.properties`文件中添加如下配置: -```properties -# 配置自定义路由 -dubbo.consumer.router=stickfirst -``` - -## 运行结果 -以**使用本地IDE**的方式来运行任务,结果如下: - -![dubbo-samples-extensibility-router-output.png](/imgs/v3/tasks/extensibility/dubbo-samples-extensibility-router-output.png) diff --git a/content/zh-cn/overview/tasks/mesh/_index.md b/content/zh-cn/overview/tasks/mesh/_index.md deleted file mode 100755 index 4e10672dd00a..000000000000 --- a/content/zh-cn/overview/tasks/mesh/_index.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -aliases: - - /zh/overview/tasks/mesh/ -description: '演示多种部署形态的 Dubbo Mesh 解决方案,以及 Dubbo Mesh 如何帮助用户实现架构的平滑迁移。 ' -linkTitle: 服务网格 -no_list: true -title: 服务网格 -toc_hide: true -type: docs -weight: 70 ---- - - - -{{< blocks/section color="white" height="auto">}} -
-
-
-
-
-

- Istio & Envoy 示例 -

-

演示 Dubbo 服务接入基于 Envoy 代理的 Istio 服务网格体系。

-
-
-
-
-
-
-

- Istio & Proxyless 示例 -

-

演示 Dubbo Proxyless 接入 Istio 服务网格体系。

-
-
-
-
-
-
- -{{< /blocks/section >}} \ No newline at end of file diff --git a/content/zh-cn/overview/tasks/mesh/bookinfo-proxyless/_index.md b/content/zh-cn/overview/tasks/mesh/bookinfo-proxyless/_index.md deleted file mode 100755 index 54d47ae99940..000000000000 --- a/content/zh-cn/overview/tasks/mesh/bookinfo-proxyless/_index.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -aliases: - - /zh/overview/tasks/mesh/bookinfo-proxyless/ -description: 通过完整的 Bookinfo 示例操作演示 Dubbo Proxyless 接入 Istio 服务网格体系。 -linkTitle: Proxyless Bookinfo -no_list: true -title: Proxyless Bookinfo 示例 -type: docs -weight: 70 ---- - - - -通过完整的 Bookinfo 示例操作演示 Dubbo 服务接入基于 Envoy 代理的 Istio 服务网格体系。 - -{{< blocks/section color="white" height="auto">}} -{{< /blocks/section >}} - -{{< blocks/section color="white" height="auto">}} -
-
-
-
-
-

- Traffic Management -

-

Tasks that demonstrates how to use Istio's traffic routing features.

-
-
-
-
-
-
-

- Security -

-

Demonstrates how to secure Dubbo proxyless mesh.

-
-
-
-
-
-
- -{{< /blocks/section >}} diff --git a/content/zh-cn/overview/tasks/mesh/bookinfo-proxyless/security/_index.md b/content/zh-cn/overview/tasks/mesh/bookinfo-proxyless/security/_index.md deleted file mode 100755 index b029e904daea..000000000000 --- a/content/zh-cn/overview/tasks/mesh/bookinfo-proxyless/security/_index.md +++ /dev/null @@ -1,91 +0,0 @@ ---- -aliases: - - /zh/overview/tasks/mesh/bookinfo-proxyless/security/ -description: Envoy Security Bookinfo 示例。 -linkTitle: security -no_list: true -title: Envoy Bookinfo 认证鉴权示例 -type: docs -weight: 20 ---- - - - -通过完整的 Bookinfo 示例操作演示 Dubbo 服务接入基于 Envoy 代理的 Istio 服务网格体系,如何配置认证鉴权体系。 - -{{< blocks/section color="white" height="auto">}} -{{< /blocks/section >}} - -{{< blocks/section color="white" height="auto">}} -
-
-
-
-
-

- Request Routing -

-

This task shows you how to configure dynamic request routing to multiple versions of a microservice.

-
-
-
-
-
-
-

- Traffic Shifting -

-

Shows you how to migrate traffic from an old to new version of a service.

-
-
-
-
-
-
-

- TCP Traffic Shifting -

Shows you how to migrate TCP traffic from an old to new version of a TCP service.

-

-

-
-
-
-
-
-
-

- Request Timeouts -

This task shows you how to set up request timeouts in Envoy using Istio.

-

-

-
-
-
-
-
-
-

- Mirroring -

This task demonstrates the traffic mirroring/shadowing capabilities of Istio.

-

-

-
-
-
-
-
-
-

- Locality Load Balancing -

This series of tasks demonstrate how to configure locality load balancing in Istio.

-

-

-
-
-
-
-
-
- -{{< /blocks/section >}} diff --git a/content/zh-cn/overview/tasks/mesh/bookinfo-proxyless/security/request-routing.md b/content/zh-cn/overview/tasks/mesh/bookinfo-proxyless/security/request-routing.md deleted file mode 100644 index 559ec400a448..000000000000 --- a/content/zh-cn/overview/tasks/mesh/bookinfo-proxyless/security/request-routing.md +++ /dev/null @@ -1,151 +0,0 @@ ---- -aliases: - - /zh/overview/tasks/mesh/bookinfo-proxyless/security/request-routing/ -description: This task shows you how to route requests dynamically to multiple versions of a microservice. -linkTitle: Request Routing -title: Request Routing -toc_hide: true -type: docs -weight: 1 ---- - - - -Before you begin -Setup Istio by following the instructions in the Installation guide. - -Deploy the Bookinfo sample application. - -Review the Traffic Management concepts doc. - -About this task -The Istio Bookinfo sample consists of four separate microservices, each with multiple versions. Three different versions of one of the microservices, reviews, have been deployed and are running concurrently. To illustrate the problem this causes, access the Bookinfo app’s /productpage in a browser and refresh several times. The URL is http://$GATEWAY_URL/productpage, where $GATEWAY_URL is the External IP address of the ingress, as explained in the Bookinfo doc. - -You’ll notice that sometimes the book review output contains star ratings and other times it does not. This is because without an explicit default service version to route to, Istio routes requests to all available versions in a round robin fashion. - -The initial goal of this task is to apply rules that route all traffic to v1 (version 1) of the microservices. Later, you will apply a rule to route traffic based on the value of an HTTP request header. - -Route to version 1 -To route to one version only, you configure route rules that send traffic to default versions for the microservices. - -If you haven’t already, follow the instructions in define the service versions. -Run the following command to create the route rules: -Istio classicGateway API -Istio uses virtual services to define route rules. Run the following command to apply virtual services that will route all traffic to v1 of each microservice: - -$ kubectl apply -f @samples/bookinfo/networking/virtual-service-all-v1.yaml@ -Because configuration propagation is eventually consistent, wait a few seconds for the virtual services to take effect. - -Display the defined routes with the following command: -Istio classicGateway API -$ kubectl get virtualservices -o yaml -- apiVersion: networking.istio.io/v1beta1 - kind: VirtualService - ... - spec: - hosts: - - details - http: - - route: - - destination: - host: details - subset: v1 -- apiVersion: networking.istio.io/v1beta1 - kind: VirtualService - ... - spec: - hosts: - - productpage - http: - - route: - - destination: - host: productpage - subset: v1 -- apiVersion: networking.istio.io/v1beta1 - kind: VirtualService - ... - spec: - hosts: - - ratings - http: - - route: - - destination: - host: ratings - subset: v1 -- apiVersion: networking.istio.io/v1beta1 - kind: VirtualService - ... - spec: - hosts: - - reviews - http: - - route: - - destination: - host: reviews - subset: v1 -You can also display the corresponding subset definitions with the following command: - -$ kubectl get destinationrules -o yaml -You have configured Istio to route to the v1 version of the Bookinfo microservices, most importantly the reviews service version 1. - -Test the new routing configuration -You can easily test the new configuration by once again refreshing the /productpage of the Bookinfo app in your browser. Notice that the reviews part of the page displays with no rating stars, no matter how many times you refresh. This is because you configured Istio to route all traffic for the reviews service to the version reviews:v1 and this version of the service does not access the star ratings service. - -You have successfully accomplished the first part of this task: route traffic to one version of a service. - -Route based on user identity -Next, you will change the route configuration so that all traffic from a specific user is routed to a specific service version. In this case, all traffic from a user named Jason will be routed to the service reviews:v2. - -This example is enabled by the fact that the productpage service adds a custom end-user header to all outbound HTTP requests to the reviews service. - -Istio also supports routing based on strongly authenticated JWT on ingress gateway, refer to the JWT claim based routing for more details. - -Remember, reviews:v2 is the version that includes the star ratings feature. - -Run the following command to enable user-based routing: -Istio classicGateway API -$ kubectl apply -f @samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml@ -You can confirm the rule is created using the following command: - -$ kubectl get virtualservice reviews -o yaml -apiVersion: networking.istio.io/v1beta1 -kind: VirtualService -... -spec: - hosts: - - reviews - http: - - match: - - headers: - end-user: - exact: jason - route: - - destination: - host: reviews - subset: v2 - - route: - - destination: - host: reviews - subset: v1 -On the /productpage of the Bookinfo app, log in as user jason. - -Refresh the browser. What do you see? The star ratings appear next to each review. - -Log in as another user (pick any name you wish). - -Refresh the browser. Now the stars are gone. This is because traffic is routed to reviews:v1 for all users except Jason. - -You have successfully configured Istio to route traffic based on user identity. - -Understanding what happened -In this task, you used Istio to send 100% of the traffic to the v1 version of each of the Bookinfo services. You then set a rule to selectively send traffic to version v2 of the reviews service based on a custom end-user header added to the request by the productpage service. - -Note that Kubernetes services, like the Bookinfo ones used in this task, must adhere to certain restrictions to take advantage of Istio’s L7 routing features. Refer to the Requirements for Pods and Services for details. - -In the traffic shifting task, you will follow the same basic pattern you learned here to configure route rules to gradually send traffic from one version of a service to another. - -Cleanup -Remove the application route rules: -Istio classicGateway API -$ kubectl delete -f @samples/bookinfo/networking/virtual-service-all-v1.yaml@ -If you are not planning to explore any follow-on tasks, refer to the Bookinfo cleanup instructions to shutdown the application. \ No newline at end of file diff --git a/content/zh-cn/overview/tasks/mesh/bookinfo-proxyless/traffic/_index.md b/content/zh-cn/overview/tasks/mesh/bookinfo-proxyless/traffic/_index.md deleted file mode 100755 index 81a00fb252c5..000000000000 --- a/content/zh-cn/overview/tasks/mesh/bookinfo-proxyless/traffic/_index.md +++ /dev/null @@ -1,91 +0,0 @@ ---- -aliases: - - /zh/overview/tasks/mesh/bookinfo-proxyless/traffic/ -description: Envoy Traffic Management Bookinfo 示例。 -linkTitle: Traffic Management -no_list: true -title: Envoy Bookinfo 流量管控示例 -type: docs -weight: 10 ---- - - - -通过完整的 Bookinfo 示例操作演示 Dubbo 服务接入基于 Envoy 代理的 Istio 服务网格体系,如何进行流量管理。 - -{{< blocks/section color="white" height="auto">}} -{{< /blocks/section >}} - -{{< blocks/section color="white" height="auto">}} -
-
-
-
-
-

- Request Routing -

-

This task shows you how to configure dynamic request routing to multiple versions of a microservice.

-
-
-
-
-
-
-

- Traffic Shifting -

-

Shows you how to migrate traffic from an old to new version of a service.

-
-
-
-
-
-
-

- TCP Traffic Shifting -

Shows you how to migrate TCP traffic from an old to new version of a TCP service.

-

-

-
-
-
-
-
-
-

- Request Timeouts -

This task shows you how to set up request timeouts in Envoy using Istio.

-

-

-
-
-
-
-
-
-

- Mirroring -

This task demonstrates the traffic mirroring/shadowing capabilities of Istio.

-

-

-
-
-
-
-
-
-

- Locality Load Balancing -

This series of tasks demonstrate how to configure locality load balancing in Istio.

-

-

-
-
-
-
-
-
- -{{< /blocks/section >}} diff --git a/content/zh-cn/overview/tasks/mesh/bookinfo-proxyless/traffic/request-routing.md b/content/zh-cn/overview/tasks/mesh/bookinfo-proxyless/traffic/request-routing.md deleted file mode 100644 index 9e277a3a658a..000000000000 --- a/content/zh-cn/overview/tasks/mesh/bookinfo-proxyless/traffic/request-routing.md +++ /dev/null @@ -1,151 +0,0 @@ ---- -aliases: - - /zh/overview/tasks/mesh/bookinfo-proxyless/traffic/request-routing/ -description: This task shows you how to route requests dynamically to multiple versions of a microservice. -linkTitle: Request Routing -title: Request Routing -toc_hide: true -type: docs -weight: 1 ---- - - - -Before you begin -Setup Istio by following the instructions in the Installation guide. - -Deploy the Bookinfo sample application. - -Review the Traffic Management concepts doc. - -About this task -The Istio Bookinfo sample consists of four separate microservices, each with multiple versions. Three different versions of one of the microservices, reviews, have been deployed and are running concurrently. To illustrate the problem this causes, access the Bookinfo app’s /productpage in a browser and refresh several times. The URL is http://$GATEWAY_URL/productpage, where $GATEWAY_URL is the External IP address of the ingress, as explained in the Bookinfo doc. - -You’ll notice that sometimes the book review output contains star ratings and other times it does not. This is because without an explicit default service version to route to, Istio routes requests to all available versions in a round robin fashion. - -The initial goal of this task is to apply rules that route all traffic to v1 (version 1) of the microservices. Later, you will apply a rule to route traffic based on the value of an HTTP request header. - -Route to version 1 -To route to one version only, you configure route rules that send traffic to default versions for the microservices. - -If you haven’t already, follow the instructions in define the service versions. -Run the following command to create the route rules: -Istio classicGateway API -Istio uses virtual services to define route rules. Run the following command to apply virtual services that will route all traffic to v1 of each microservice: - -$ kubectl apply -f @samples/bookinfo/networking/virtual-service-all-v1.yaml@ -Because configuration propagation is eventually consistent, wait a few seconds for the virtual services to take effect. - -Display the defined routes with the following command: -Istio classicGateway API -$ kubectl get virtualservices -o yaml -- apiVersion: networking.istio.io/v1beta1 - kind: VirtualService - ... - spec: - hosts: - - details - http: - - route: - - destination: - host: details - subset: v1 -- apiVersion: networking.istio.io/v1beta1 - kind: VirtualService - ... - spec: - hosts: - - productpage - http: - - route: - - destination: - host: productpage - subset: v1 -- apiVersion: networking.istio.io/v1beta1 - kind: VirtualService - ... - spec: - hosts: - - ratings - http: - - route: - - destination: - host: ratings - subset: v1 -- apiVersion: networking.istio.io/v1beta1 - kind: VirtualService - ... - spec: - hosts: - - reviews - http: - - route: - - destination: - host: reviews - subset: v1 -You can also display the corresponding subset definitions with the following command: - -$ kubectl get destinationrules -o yaml -You have configured Istio to route to the v1 version of the Bookinfo microservices, most importantly the reviews service version 1. - -Test the new routing configuration -You can easily test the new configuration by once again refreshing the /productpage of the Bookinfo app in your browser. Notice that the reviews part of the page displays with no rating stars, no matter how many times you refresh. This is because you configured Istio to route all traffic for the reviews service to the version reviews:v1 and this version of the service does not access the star ratings service. - -You have successfully accomplished the first part of this task: route traffic to one version of a service. - -Route based on user identity -Next, you will change the route configuration so that all traffic from a specific user is routed to a specific service version. In this case, all traffic from a user named Jason will be routed to the service reviews:v2. - -This example is enabled by the fact that the productpage service adds a custom end-user header to all outbound HTTP requests to the reviews service. - -Istio also supports routing based on strongly authenticated JWT on ingress gateway, refer to the JWT claim based routing for more details. - -Remember, reviews:v2 is the version that includes the star ratings feature. - -Run the following command to enable user-based routing: -Istio classicGateway API -$ kubectl apply -f @samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml@ -You can confirm the rule is created using the following command: - -$ kubectl get virtualservice reviews -o yaml -apiVersion: networking.istio.io/v1beta1 -kind: VirtualService -... -spec: - hosts: - - reviews - http: - - match: - - headers: - end-user: - exact: jason - route: - - destination: - host: reviews - subset: v2 - - route: - - destination: - host: reviews - subset: v1 -On the /productpage of the Bookinfo app, log in as user jason. - -Refresh the browser. What do you see? The star ratings appear next to each review. - -Log in as another user (pick any name you wish). - -Refresh the browser. Now the stars are gone. This is because traffic is routed to reviews:v1 for all users except Jason. - -You have successfully configured Istio to route traffic based on user identity. - -Understanding what happened -In this task, you used Istio to send 100% of the traffic to the v1 version of each of the Bookinfo services. You then set a rule to selectively send traffic to version v2 of the reviews service based on a custom end-user header added to the request by the productpage service. - -Note that Kubernetes services, like the Bookinfo ones used in this task, must adhere to certain restrictions to take advantage of Istio’s L7 routing features. Refer to the Requirements for Pods and Services for details. - -In the traffic shifting task, you will follow the same basic pattern you learned here to configure route rules to gradually send traffic from one version of a service to another. - -Cleanup -Remove the application route rules: -Istio classicGateway API -$ kubectl delete -f @samples/bookinfo/networking/virtual-service-all-v1.yaml@ -If you are not planning to explore any follow-on tasks, refer to the Bookinfo cleanup instructions to shutdown the application. \ No newline at end of file diff --git a/content/zh-cn/overview/tasks/mesh/bookinfo-sidecar/_index.md b/content/zh-cn/overview/tasks/mesh/bookinfo-sidecar/_index.md deleted file mode 100755 index b046e564d62f..000000000000 --- a/content/zh-cn/overview/tasks/mesh/bookinfo-sidecar/_index.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -aliases: - - /zh/overview/tasks/mesh/bookinfo-sidecar/ -description: 通过完整的 Bookinfo 示例操作演示 Dubbo 服务接入基于 Envoy 代理的 Istio 服务网格体系。 -linkTitle: Envoy Bookinfo -no_list: true -title: Envoy Bookinfo 示例 -type: docs -weight: 70 ---- - - - -通过完整的 Bookinfo 示例操作演示 Dubbo 服务接入基于 Envoy 代理的 Istio 服务网格体系。 - -{{< blocks/section color="white" height="auto">}} -{{< /blocks/section >}} - -{{< blocks/section color="white" height="auto">}} -
-
-
-
-
-

- Traffic Management -

-

Tasks that demonstrates how to use Istio's traffic routing features.

-
-
-
-
-
-
-

- Security -

-

Demonstrates how to secure Dubbo mesh.

-
-
-
-
-
-
- -{{< /blocks/section >}} diff --git a/content/zh-cn/overview/tasks/mesh/bookinfo-sidecar/security/_index.md b/content/zh-cn/overview/tasks/mesh/bookinfo-sidecar/security/_index.md deleted file mode 100755 index c803952b16fc..000000000000 --- a/content/zh-cn/overview/tasks/mesh/bookinfo-sidecar/security/_index.md +++ /dev/null @@ -1,91 +0,0 @@ ---- -aliases: - - /zh/overview/tasks/mesh/bookinfo-sidecar/security/ -description: Envoy Security Bookinfo 示例。 -linkTitle: security -no_list: true -title: Envoy Bookinfo 认证鉴权示例 -type: docs -weight: 20 ---- - - - -通过完整的 Bookinfo 示例操作演示 Dubbo 服务接入基于 Envoy 代理的 Istio 服务网格体系,如何配置认证鉴权体系。 - -{{< blocks/section color="white" height="auto">}} -{{< /blocks/section >}} - -{{< blocks/section color="white" height="auto">}} -
-
-
-
-
-

- Request Routing -

-

This task shows you how to configure dynamic request routing to multiple versions of a microservice.

-
-
-
-
-
-
-

- Traffic Shifting -

-

Shows you how to migrate traffic from an old to new version of a service.

-
-
-
-
-
-
-

- TCP Traffic Shifting -

Shows you how to migrate TCP traffic from an old to new version of a TCP service.

-

-

-
-
-
-
-
-
-

- Request Timeouts -

This task shows you how to set up request timeouts in Envoy using Istio.

-

-

-
-
-
-
-
-
-

- Mirroring -

This task demonstrates the traffic mirroring/shadowing capabilities of Istio.

-

-

-
-
-
-
-
-
-

- Locality Load Balancing -

This series of tasks demonstrate how to configure locality load balancing in Istio.

-

-

-
-
-
-
-
-
- -{{< /blocks/section >}} diff --git a/content/zh-cn/overview/tasks/mesh/bookinfo-sidecar/security/request-routing.md b/content/zh-cn/overview/tasks/mesh/bookinfo-sidecar/security/request-routing.md deleted file mode 100644 index 18ca76bb0ce1..000000000000 --- a/content/zh-cn/overview/tasks/mesh/bookinfo-sidecar/security/request-routing.md +++ /dev/null @@ -1,151 +0,0 @@ ---- -aliases: - - /zh/overview/tasks/mesh/bookinfo-sidecar/security/request-routing/ -description: This task shows you how to route requests dynamically to multiple versions of a microservice. -linkTitle: Request Routing -title: Request Routing -toc_hide: true -type: docs -weight: 1 ---- - - - -Before you begin -Setup Istio by following the instructions in the Installation guide. - -Deploy the Bookinfo sample application. - -Review the Traffic Management concepts doc. - -About this task -The Istio Bookinfo sample consists of four separate microservices, each with multiple versions. Three different versions of one of the microservices, reviews, have been deployed and are running concurrently. To illustrate the problem this causes, access the Bookinfo app’s /productpage in a browser and refresh several times. The URL is http://$GATEWAY_URL/productpage, where $GATEWAY_URL is the External IP address of the ingress, as explained in the Bookinfo doc. - -You’ll notice that sometimes the book review output contains star ratings and other times it does not. This is because without an explicit default service version to route to, Istio routes requests to all available versions in a round robin fashion. - -The initial goal of this task is to apply rules that route all traffic to v1 (version 1) of the microservices. Later, you will apply a rule to route traffic based on the value of an HTTP request header. - -Route to version 1 -To route to one version only, you configure route rules that send traffic to default versions for the microservices. - -If you haven’t already, follow the instructions in define the service versions. -Run the following command to create the route rules: -Istio classicGateway API -Istio uses virtual services to define route rules. Run the following command to apply virtual services that will route all traffic to v1 of each microservice: - -$ kubectl apply -f @samples/bookinfo/networking/virtual-service-all-v1.yaml@ -Because configuration propagation is eventually consistent, wait a few seconds for the virtual services to take effect. - -Display the defined routes with the following command: -Istio classicGateway API -$ kubectl get virtualservices -o yaml -- apiVersion: networking.istio.io/v1beta1 - kind: VirtualService - ... - spec: - hosts: - - details - http: - - route: - - destination: - host: details - subset: v1 -- apiVersion: networking.istio.io/v1beta1 - kind: VirtualService - ... - spec: - hosts: - - productpage - http: - - route: - - destination: - host: productpage - subset: v1 -- apiVersion: networking.istio.io/v1beta1 - kind: VirtualService - ... - spec: - hosts: - - ratings - http: - - route: - - destination: - host: ratings - subset: v1 -- apiVersion: networking.istio.io/v1beta1 - kind: VirtualService - ... - spec: - hosts: - - reviews - http: - - route: - - destination: - host: reviews - subset: v1 -You can also display the corresponding subset definitions with the following command: - -$ kubectl get destinationrules -o yaml -You have configured Istio to route to the v1 version of the Bookinfo microservices, most importantly the reviews service version 1. - -Test the new routing configuration -You can easily test the new configuration by once again refreshing the /productpage of the Bookinfo app in your browser. Notice that the reviews part of the page displays with no rating stars, no matter how many times you refresh. This is because you configured Istio to route all traffic for the reviews service to the version reviews:v1 and this version of the service does not access the star ratings service. - -You have successfully accomplished the first part of this task: route traffic to one version of a service. - -Route based on user identity -Next, you will change the route configuration so that all traffic from a specific user is routed to a specific service version. In this case, all traffic from a user named Jason will be routed to the service reviews:v2. - -This example is enabled by the fact that the productpage service adds a custom end-user header to all outbound HTTP requests to the reviews service. - -Istio also supports routing based on strongly authenticated JWT on ingress gateway, refer to the JWT claim based routing for more details. - -Remember, reviews:v2 is the version that includes the star ratings feature. - -Run the following command to enable user-based routing: -Istio classicGateway API -$ kubectl apply -f @samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml@ -You can confirm the rule is created using the following command: - -$ kubectl get virtualservice reviews -o yaml -apiVersion: networking.istio.io/v1beta1 -kind: VirtualService -... -spec: - hosts: - - reviews - http: - - match: - - headers: - end-user: - exact: jason - route: - - destination: - host: reviews - subset: v2 - - route: - - destination: - host: reviews - subset: v1 -On the /productpage of the Bookinfo app, log in as user jason. - -Refresh the browser. What do you see? The star ratings appear next to each review. - -Log in as another user (pick any name you wish). - -Refresh the browser. Now the stars are gone. This is because traffic is routed to reviews:v1 for all users except Jason. - -You have successfully configured Istio to route traffic based on user identity. - -Understanding what happened -In this task, you used Istio to send 100% of the traffic to the v1 version of each of the Bookinfo services. You then set a rule to selectively send traffic to version v2 of the reviews service based on a custom end-user header added to the request by the productpage service. - -Note that Kubernetes services, like the Bookinfo ones used in this task, must adhere to certain restrictions to take advantage of Istio’s L7 routing features. Refer to the Requirements for Pods and Services for details. - -In the traffic shifting task, you will follow the same basic pattern you learned here to configure route rules to gradually send traffic from one version of a service to another. - -Cleanup -Remove the application route rules: -Istio classicGateway API -$ kubectl delete -f @samples/bookinfo/networking/virtual-service-all-v1.yaml@ -If you are not planning to explore any follow-on tasks, refer to the Bookinfo cleanup instructions to shutdown the application. \ No newline at end of file diff --git a/content/zh-cn/overview/tasks/mesh/bookinfo-sidecar/traffic/_index.md b/content/zh-cn/overview/tasks/mesh/bookinfo-sidecar/traffic/_index.md deleted file mode 100755 index 10741f9f5a38..000000000000 --- a/content/zh-cn/overview/tasks/mesh/bookinfo-sidecar/traffic/_index.md +++ /dev/null @@ -1,91 +0,0 @@ ---- -aliases: - - /zh/overview/tasks/mesh/bookinfo-sidecar/traffic/ -description: Envoy Traffic Management Bookinfo 示例。 -linkTitle: Traffic Management -no_list: true -title: Envoy Bookinfo 流量管控示例 -type: docs -weight: 10 ---- - - - -通过完整的 Bookinfo 示例操作演示 Dubbo 服务接入基于 Envoy 代理的 Istio 服务网格体系,如何进行流量管理。 - -{{< blocks/section color="white" height="auto">}} -{{< /blocks/section >}} - -{{< blocks/section color="white" height="auto">}} -
-
-
-
-
-

- Request Routing -

-

This task shows you how to configure dynamic request routing to multiple versions of a microservice.

-
-
-
-
-
-
-

- Traffic Shifting -

-

Shows you how to migrate traffic from an old to new version of a service.

-
-
-
-
-
-
-

- TCP Traffic Shifting -

Shows you how to migrate TCP traffic from an old to new version of a TCP service.

-

-

-
-
-
-
-
-
-

- Request Timeouts -

This task shows you how to set up request timeouts in Envoy using Istio.

-

-

-
-
-
-
-
-
-

- Mirroring -

This task demonstrates the traffic mirroring/shadowing capabilities of Istio.

-

-

-
-
-
-
-
-
-

- Locality Load Balancing -

This series of tasks demonstrate how to configure locality load balancing in Istio.

-

-

-
-
-
-
-
-
- -{{< /blocks/section >}} diff --git a/content/zh-cn/overview/tasks/mesh/bookinfo-sidecar/traffic/request-routing.md b/content/zh-cn/overview/tasks/mesh/bookinfo-sidecar/traffic/request-routing.md deleted file mode 100644 index 43718d07468c..000000000000 --- a/content/zh-cn/overview/tasks/mesh/bookinfo-sidecar/traffic/request-routing.md +++ /dev/null @@ -1,151 +0,0 @@ ---- -aliases: - - /zh/overview/tasks/mesh/bookinfo-sidecar/traffic/request-routing/ -description: This task shows you how to route requests dynamically to multiple versions of a microservice. -linkTitle: Request Routing -title: Request Routing -toc_hide: true -type: docs -weight: 1 ---- - - - -Before you begin -Setup Istio by following the instructions in the Installation guide. - -Deploy the Bookinfo sample application. - -Review the Traffic Management concepts doc. - -About this task -The Istio Bookinfo sample consists of four separate microservices, each with multiple versions. Three different versions of one of the microservices, reviews, have been deployed and are running concurrently. To illustrate the problem this causes, access the Bookinfo app’s /productpage in a browser and refresh several times. The URL is http://$GATEWAY_URL/productpage, where $GATEWAY_URL is the External IP address of the ingress, as explained in the Bookinfo doc. - -You’ll notice that sometimes the book review output contains star ratings and other times it does not. This is because without an explicit default service version to route to, Istio routes requests to all available versions in a round robin fashion. - -The initial goal of this task is to apply rules that route all traffic to v1 (version 1) of the microservices. Later, you will apply a rule to route traffic based on the value of an HTTP request header. - -Route to version 1 -To route to one version only, you configure route rules that send traffic to default versions for the microservices. - -If you haven’t already, follow the instructions in define the service versions. -Run the following command to create the route rules: -Istio classicGateway API -Istio uses virtual services to define route rules. Run the following command to apply virtual services that will route all traffic to v1 of each microservice: - -$ kubectl apply -f @samples/bookinfo/networking/virtual-service-all-v1.yaml@ -Because configuration propagation is eventually consistent, wait a few seconds for the virtual services to take effect. - -Display the defined routes with the following command: -Istio classicGateway API -$ kubectl get virtualservices -o yaml -- apiVersion: networking.istio.io/v1beta1 - kind: VirtualService - ... - spec: - hosts: - - details - http: - - route: - - destination: - host: details - subset: v1 -- apiVersion: networking.istio.io/v1beta1 - kind: VirtualService - ... - spec: - hosts: - - productpage - http: - - route: - - destination: - host: productpage - subset: v1 -- apiVersion: networking.istio.io/v1beta1 - kind: VirtualService - ... - spec: - hosts: - - ratings - http: - - route: - - destination: - host: ratings - subset: v1 -- apiVersion: networking.istio.io/v1beta1 - kind: VirtualService - ... - spec: - hosts: - - reviews - http: - - route: - - destination: - host: reviews - subset: v1 -You can also display the corresponding subset definitions with the following command: - -$ kubectl get destinationrules -o yaml -You have configured Istio to route to the v1 version of the Bookinfo microservices, most importantly the reviews service version 1. - -Test the new routing configuration -You can easily test the new configuration by once again refreshing the /productpage of the Bookinfo app in your browser. Notice that the reviews part of the page displays with no rating stars, no matter how many times you refresh. This is because you configured Istio to route all traffic for the reviews service to the version reviews:v1 and this version of the service does not access the star ratings service. - -You have successfully accomplished the first part of this task: route traffic to one version of a service. - -Route based on user identity -Next, you will change the route configuration so that all traffic from a specific user is routed to a specific service version. In this case, all traffic from a user named Jason will be routed to the service reviews:v2. - -This example is enabled by the fact that the productpage service adds a custom end-user header to all outbound HTTP requests to the reviews service. - -Istio also supports routing based on strongly authenticated JWT on ingress gateway, refer to the JWT claim based routing for more details. - -Remember, reviews:v2 is the version that includes the star ratings feature. - -Run the following command to enable user-based routing: -Istio classicGateway API -$ kubectl apply -f @samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml@ -You can confirm the rule is created using the following command: - -$ kubectl get virtualservice reviews -o yaml -apiVersion: networking.istio.io/v1beta1 -kind: VirtualService -... -spec: - hosts: - - reviews - http: - - match: - - headers: - end-user: - exact: jason - route: - - destination: - host: reviews - subset: v2 - - route: - - destination: - host: reviews - subset: v1 -On the /productpage of the Bookinfo app, log in as user jason. - -Refresh the browser. What do you see? The star ratings appear next to each review. - -Log in as another user (pick any name you wish). - -Refresh the browser. Now the stars are gone. This is because traffic is routed to reviews:v1 for all users except Jason. - -You have successfully configured Istio to route traffic based on user identity. - -Understanding what happened -In this task, you used Istio to send 100% of the traffic to the v1 version of each of the Bookinfo services. You then set a rule to selectively send traffic to version v2 of the reviews service based on a custom end-user header added to the request by the productpage service. - -Note that Kubernetes services, like the Bookinfo ones used in this task, must adhere to certain restrictions to take advantage of Istio’s L7 routing features. Refer to the Requirements for Pods and Services for details. - -In the traffic shifting task, you will follow the same basic pattern you learned here to configure route rules to gradually send traffic from one version of a service to another. - -Cleanup -Remove the application route rules: -Istio classicGateway API -$ kubectl delete -f @samples/bookinfo/networking/virtual-service-all-v1.yaml@ -If you are not planning to explore any follow-on tasks, refer to the Bookinfo cleanup instructions to shutdown the application. \ No newline at end of file diff --git a/content/zh-cn/overview/tasks/mesh/migration/_index.md b/content/zh-cn/overview/tasks/mesh/migration/_index.md deleted file mode 100755 index 431646548ca4..000000000000 --- a/content/zh-cn/overview/tasks/mesh/migration/_index.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -aliases: - - /zh/overview/tasks/mesh/migration/ -description: 演示 Dubbo Mesh 如何帮助用户实现架构的平滑迁移。 -linkTitle: Dubbo2 平滑迁移 -no_list: true -title: 传统 Dubbo 微服务集群如何平滑迁移到 Istio 服务网格体系 -type: docs -weight: 70 ---- - - - -{{< blocks/section color="white" height="auto">}} -
-
-
-
-
-

- 地址同步问题 -

-

如何解决地址同步问题?

-
-
-
-
-
-
-

- 协议识别问题 -

-

如何解决 Dubbo2+hessian2 协议问题?

-
-
-
-
-
-
- -{{< /blocks/section >}} \ No newline at end of file diff --git a/content/zh-cn/overview/tasks/observability/_index.md b/content/zh-cn/overview/tasks/observability/_index.md deleted file mode 100755 index bd3a22de8586..000000000000 --- a/content/zh-cn/overview/tasks/observability/_index.md +++ /dev/null @@ -1,85 +0,0 @@ ---- -aliases: - - /zh/overview/tasks/observability/ -description: 基于 Admin、Metrics、Grafana 等可视化的观测集群状态。 -linkTitle: 观测服务 -no_list: true -title: 观测服务 -type: docs -weight: 5 ---- - - - -{{< blocks/section color="white" height="auto">}} -
-
- -
-
-
-
-

- Admin 可视化控制台 -

-

演示如何通过 Admin 控制台可视化管控 Dubbo 微服务集群,包括查询服务、实例运行状态、服务测试、文档管理、流量规则下发等。

-
-
-
-
-
-
-

- Grafana 可视化展示集群指标 -

-

演示如何通过 Grafana 可视化展示 Dubbo 集群的 Metrics 埋点监控指标。

-
-
-
-
-
-
-

- 使用 Prometheus 查询指标 -

-

演示如何根据条件从 Prometheus 中查询 Metrics 指标。

-
-
-
-
-
-
-

- Zipkin 全链路追踪 -

-

演示如果通过 Zipkin 实现对 Dubbo 服务的全链路追踪。 -

-
-
-
-
-
-
-

- Skywalking 全链路追踪 -

-

演示如果通过 Skywalking 实现对 Dubbo 服务的全链路追踪。 -

-
-
-
-
-
-
-

- OTlp 全链路追踪 -

-

演示如果通过 OpenTelemetry 的 Otlp Collector 实现对 Dubbo 服务的全链路追踪。 -

-
-
-
-
-
-
-{{< /blocks/section >}} diff --git a/content/zh-cn/overview/tasks/observability/admin.md b/content/zh-cn/overview/tasks/observability/admin.md deleted file mode 100644 index 4d9e1f185f75..000000000000 --- a/content/zh-cn/overview/tasks/observability/admin.md +++ /dev/null @@ -1,92 +0,0 @@ ---- -aliases: - - /zh/overview/tasks/observability/admin/ -description: "" -linkTitle: Admin -no_list: true -title: 使用 Admin 可视化查看集群状态 -type: docs -weight: 1 ---- - -前面章节我们提到 Dubbo 框架提供了丰富的服务治理功能如流量控制、动态配置、服务 Mock、服务测试等,而 Dubbo Admin 控制台的一部分重要作用在于将 dubbo 框架提供的服务治理能力提供一个开箱即用的可视化平台。本文将介绍 Dubbo Admin 控制台所提供的功能,让大家快速了解和使用 Admin 并对 Dubbo 所提供的服务治理能力有个更直观的了解。 - -> Dubbo Admin 已经升级为 Dubbo 服务治理统一入口,涵盖的范围非常广泛,本文讲解的只是 Admin 可视化控制台部分。 - -## 安装 Admin -首先,需要正确 [安装&配置 Dubbo Admin](../../../reference/admin/architecture/) 控制台 - -## 功能介绍 -Admin 控制台提供了从开发、测试到流量治理等不同层面的丰富功能,功能总体上可分为以下几类: -* 服务状态与依赖关系查询 -* 服务在线测试与文档管理 -* 集群状态监控 -* 实例诊断 -* 流量管控 - -### 服务状态与依赖关系查询 -服务状态查询以接口为维度展示 dubbo 集群信息,包含服务提供者、消费者信息和服务的元数据等。元数据包含了服务定义、方法名和参数列表等信息。Admin 支持最新版本 dubbo3 所提供的应用级发现模型,以统一的页面交互展示了应用级&接口级地址信息,并以特殊的标记对记录进行区分。 - -#### 基于服务名查询 -![img](/imgs/v3/tasks/observability/admin/1-search-by-service.png) - -#### 基于应用名查询 -![img](/imgs/v3/tasks/observability/admin/1-search-by-appname.png) - -#### 基于实例地址查询 -![img](/imgs/v3/tasks/observability/admin/1-search-by-ip.png) - -#### 服务实例详情 -![img](/imgs/v3/tasks/observability/admin/1-service-detail.png) - -### 服务在线测试与文档管理 -#### 服务测试 -服务测试相,主要用于模拟服务消费方,验证 Dubbo 服务的使用方式与正确性。 - -![img](/imgs/v3/tasks/observability/admin/2-service-test2.png) - -![img](/imgs/v3/tasks/observability/admin/2-service-test.png) - -#### 服务 Mock -服务Mock通过无代码嵌入的方式将Consumer对Provider的请求进行拦截,动态的对Consumer的请求进行放行或返回用户自定义的Mock数据。从而解决在前期开发过程中,Consumer所依赖的Provider未准备就绪时,造成Consumer开发方的阻塞问题。 -只需要以下两步,即可享受服务Mock功能带来的便捷: - -第一步: -Consumer应用引入服务Mock依赖,添加JVM启动参数-Denable.dubbo.admin.mock=true开启服务Mock功能。 -```xml - - org.apache.dubbo.extensions - dubbo-mock-admin - ${version} - -``` - -第二步:在Dubbo Admin中配置对应的Mock数据。 - -![img](/imgs/v3/tasks/observability/admin/2-service-mock.png) - -#### 服务文档管理 -Admin 提供的接口文档,相当于 swagger 对于 RESTful 风格的 Web 服务的作用。使用该功能可以有效的管理 Dubbo 接口文档。 - -![img](/imgs/v3/tasks/observability/admin/2-service-doc.png) - -### 集群状态监控 -#### 首页大盘 -TBD - -#### Grafana -![img](/imgs/v3/tasks/observability/admin/3-grafana.png) - -#### Tracing -![img](/imgs/v3/tasks/observability/admin/3-tracing-zipkin.png) - -### 流量管控 -Admin 提供了四种路由规则的可视化管理支持,分别是条件路由规则、标签路由规则、动态配置规则、脚本路由规则,所提供的功能可以轻松实现黑白名单、灰度环境隔离、多套测试环境、金丝雀发布等服务治理诉求。接下来以条件路由为例,可以可视化的创建条件路由规则。 - -#### 条件路由 - -条件路由可以编写一些自定义路由规则实现服务治理的需求比如同区域优先、参数路由、黑白名单、读写分离等。路由规则在发起一次RPC调用前起到过滤目标服务器地址的作用,过滤后的地址列表,将作为消费端最终发起RPC调用的备选地址。 - -![img](/imgs/v3/tasks/observability/admin/4-traffic-management.png) - -请参考 [流量管控任务](../../traffic-management/) 中关于如何进行路由规则配置的更多详细描述。 diff --git a/content/zh-cn/overview/tasks/observability/prometheus.md b/content/zh-cn/overview/tasks/observability/prometheus.md deleted file mode 100644 index 3fdcfce00d43..000000000000 --- a/content/zh-cn/overview/tasks/observability/prometheus.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -aliases: - - /zh/overview/tasks/observability/prometheus/ -description: "" -linkTitle: Prometheus -no_list: true -title: 从 Prometheus 查询 Metrics 监控指标 -type: docs -weight: 4 ---- - -## 准备条件 - -本文演示如何在 Kubernetes 环境下部署 Prometheus 并实现对 Dubbo 集群的监控数据统计与查询,你需要完成或具备以下内容: - -* 本地或远端 Kubernetes 集群 -* 确保 [Prometheus 正确安装](../../../reference/integrations/prometheus/#安装) -* 部署 [示例应用](https://github.com/apache/dubbo-samples/tree/master/4-governance/dubbo-samples-metrics-spring-boot) 并开启指标采集 -* 使用 Prometheus dashboard 查询数据指标 - -## 确保 Prometheus 正确运行 - -验证 Prometheus 已经正确部署 - -```yaml -kubectl -n dubbo-system get svc prometheus-server -NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE -prometheus-server ClusterIP 10.109.160.254 9090/TCP 4m -``` - -## 查询 Prometheus - -获得 Prometheus 访问地址 `kubectl port-forward service/prometheus-server 9090:9090`, -打开浏览器,访问 localhost:9090/graph 即可打开 Prometheus 控制台。 - -接下来,执行 Prometheus 查询命令。可以在此确认 [Dubbo 支持的 Metrics 指标](../../../reference/proposals/metrics/)。 - -**1. 在 “Expression” 一览,输入 `dubbo_consumer_qps_total`,返回以下结果** - -![img](/imgs/v3/tasks/observability/prometheus.png) diff --git a/content/zh-cn/overview/tasks/observability/tracing/_index.md b/content/zh-cn/overview/tasks/observability/tracing/_index.md deleted file mode 100755 index d1ea87640cc4..000000000000 --- a/content/zh-cn/overview/tasks/observability/tracing/_index.md +++ /dev/null @@ -1,164 +0,0 @@ ---- -aliases: - - /zh/overview/tasks/observability/tracing/ -description: "" -linkTitle: 全链路追踪 -no_list: true -title: 全链路追踪 -type: docs -weight: 2 ---- - - -{{< blocks/section color="white" height="auto">}} -
-
- -
-
-
-
-

- Zipkin 全链路追踪 -

-

演示如果通过 Zipkin 实现对 Dubbo 服务的全链路追踪。 -

-
-
-
-
-
-
-

- Skywalking 全链路追踪 -

-

演示如果通过 Skywalking 实现对 Dubbo 服务的全链路追踪。 -

-
-
-
-
-
-
-

- OTlp 全链路追踪 -

-

演示如果通过 OpenTelemetry 的 Otlp Collector 实现对 Dubbo 服务的全链路追踪。 -

-
-
-
-
-
-
-{{< /blocks/section >}} - -## 说明 - -目前 Dubbo 内置了 [Micrometer](https://micrometer.io/)(Micrometer 为最流行的可观察性系统在检测客户端上提供了一个统一的门面,相当于日志领域的SLF4J,SpringBoot3 内置的可观测门面组件)。 - -## Tracing相关概念 - -- Span:基本工作单元。例如,发送 RPC 是一个新的 span,发送对 RPC 的响应也是如此。Span还有其他数据,例如description、带时间戳的事件、键值注释(标签)、导致它们的跨度的 ID 和进程 ID(通常是 IP 地址)。跨度可以启动和停止,并且它们会跟踪它们的时间信息。创建跨度后,您必须在将来的某个时间点停止它。 - -- Trace:一组形成树状结构的跨度。例如,如果您运行分布式大数据存储,则可能会通过请求形成跟踪PUT。 - -- Annotation/Event : 用于及时记录一个事件的存在。 - -- Tracing context:为了使分布式跟踪工作,跟踪上下文(跟踪标识符、跨度标识符等)必须通过进程(例如通过线程)和网络传播。 - -- Log correlation:部分跟踪上下文(例如跟踪标识符、跨度标识符)可以填充到给定应用程序的日志中。然后可以将所有日志收集到一个存储中,并通过跟踪 ID 对它们进行分组。这样就可以从所有按时间顺序排列的服务中获取单个业务操作(跟踪)的所有日志。 - -- Latency analysis tools:一种收集导出跨度并可视化整个跟踪的工具。允许轻松进行延迟分析。 - -- Tracer: 处理span生命周期的库(Dubbo 目前支持 OpenTelemetry 和 Brave)。它可以通过 Exporter 创建、启动、停止和报告 Spans 到外部系统(如 Zipkin、Jagger 等)。 - -- Exporter: 将产生的 Trace 信息通过 http 等接口上报到外部系统,比如上报到 Zipkin。 - -## SpringBoot Starters - -对于 SpringBoot 用户,Dubbo 提供了 Tracing 相关的 starters,自动装配 Micrometer 相关的配置代码,且用户可自由选择 Tracer 和Exporter。 - -### OpenTelemetry 作为 Tracer,将 Trace 信息 export 到 Zipkin - -```yml - - org.apache.dubbo - dubbo-spring-boot-tracing-otel-zipkin-starter - ${version} - -``` - -### OpenTelemetry 作为 Tracer,将 Trace 信息 export 到 OTlp Collector - -```yml - - org.apache.dubbo - dubbo-spring-boot-tracing-otel-otlp-starter - ${version} - -``` - -### Brave 作为 Tracer,将 Trace 信息 export 到 Zipkin - -```yml - - org.apache.dubbo - dubbo-spring-boot-tracing-brave-zipkin-starter - ${version} - -``` - -### 自由组装 Tracer 和 Exporter - -如果用户基于 Micrometer 有自定义的需求,想将 Trace 信息上报至其他外部系统观测,可参照如下自由组装 Tracer 和 Exporter: - -```yml - - - org.apache.dubbo - dubbo-spring-boot-observability-starter - ${version} - - - - io.micrometer - micrometer-tracing-bridge-otel - ${version} - - - - io.opentelemetry - opentelemetry-exporter-zipkin - ${version} - -``` - -```yml - - - org.apache.dubbo - dubbo-spring-boot-observability-starter - ${version} - - - - io.micrometer - micrometer-tracing-bridge-brave - ${version} - - - - io.zipkin.reporter2 - zipkin-reporter-brave - ${version} - -``` - -后续还会补齐更多的 starters,如 Jagger、SkyWalking等。 - -## Dubbo Bootstrap API - -对于像非 SpringBoot 的项目,可以使用 Dubbo API 使用Tracing。 - -详细案例可参考[代码地址](https://github.com/conghuhu/dubbo-samples/tree/master/4-governance/dubbo-samples-tracing/dubbo-sample-api-tracing-otel-zipkin) \ No newline at end of file diff --git a/content/zh-cn/overview/tasks/protocols/_index.md b/content/zh-cn/overview/tasks/protocols/_index.md deleted file mode 100755 index 7bdb084d7b01..000000000000 --- a/content/zh-cn/overview/tasks/protocols/_index.md +++ /dev/null @@ -1,63 +0,0 @@ ---- -aliases: - - /zh/overview/tasks/protocols/ -description: 演示 Dubbo 多协议的应用场景 -hide: true -linkTitle: 通信协议 -no_list: true -title: 通信协议 -type: docs -weight: 6 ---- - - - -{{< blocks/section color="white" height="auto">}} -
-
-
-
-
-

- 使用 Dubbo 开发 gRPC 服务 -

-

演示 Dubbo 如何简化 gRPC 服务开发。

-
-
-
-
-
-
-

- 使用 Dubbo 开发 Web 应用 -

-

演示使用 Dubbo 对外暴露 HTTP 接口,支持 Spring Web 标准开发方式。

-
-
-
-
-
-
-

- 与 Spring Cloud 互调 -

-

演示如何使用 Dubbo 作为消费端调用 Spring Cloud 服务

-
-
-
-
-
-
-

- 单端口多协议发布服务 -

-

演示如何在一个应用内发布多个使用不同协议的服务,并通过唯一的一个端口对外发布。

-
-
-
-
-
-
- -{{< /blocks/section >}} diff --git a/content/zh-cn/overview/tasks/protocols/dubbo.md b/content/zh-cn/overview/tasks/protocols/dubbo.md deleted file mode 100644 index 539f63c38998..000000000000 --- a/content/zh-cn/overview/tasks/protocols/dubbo.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -description: "使用 Dubbo 开发 TCP 通信协议服务" -linkTitle: 开发 Dubbo2 服务 -title: 使用 Dubbo 开发 TCP 通信协议服务 -type: docs -weight: 1 ---- - -文档编写中... \ No newline at end of file diff --git a/content/zh-cn/overview/tasks/protocols/grpc.md b/content/zh-cn/overview/tasks/protocols/grpc.md deleted file mode 100644 index a7eb9a05ec6c..000000000000 --- a/content/zh-cn/overview/tasks/protocols/grpc.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -aliases: - - /zh/overview/tasks/protocols/grpc/ -description: "使用 Dubbo 开发 gRPC 服务" -linkTitle: 开发 gRPC 服务 -title: 使用 Dubbo 开发 gRPC 服务 -type: docs -weight: 1 ---- - -文档编写中... \ No newline at end of file diff --git a/content/zh-cn/overview/tasks/protocols/multi-protocols.md b/content/zh-cn/overview/tasks/protocols/multi-protocols.md deleted file mode 100644 index f8257244ea6d..000000000000 --- a/content/zh-cn/overview/tasks/protocols/multi-protocols.md +++ /dev/null @@ -1,132 +0,0 @@ ---- -aliases: - - /zh/overview/tasks/protocols/multi-protocols/ -description: "" -linkTitle: 单端口多协议 -title: 发布使用不同协议的多个服务,通过单端口监听 -type: docs -weight: 4 ---- - - - -## 特性说明 -通过对protocol进行配置,dubbo3可以支持端口的协议复用。 -比如使用Triple协议启动端口复用后,可以在相同的端口上为服务增加 -Dubbo协议支持,以及Qos协议支持。这些协议的识别都是由一个统一的端口复用 -服务器进行处理的,可以用于服务的协议迁移,并且可以节约端口以及相关的资源,减少运维的复杂性。 - -![pu-server-image1](/imgs/blog/pu-server/pu-server-flow.png) - -- 在服务的创建阶段,通过从Config层获取到服务导出的协议配置从而创建不同的Protocol对象进行导出。在导出的过程 -中,如果不是第一次创建端口复用的Server,那么Exchanger会将Protcol层传递的数据保存到Server,用于后续处理该协议类型的消息。 - -- 当客户端的消息传递过来后,首先会通过Server传递给ProtocolDetector,如果完成了识别,那么就会标记该客户端为对应的协议。并通过WireProtocol配置对应的处理逻辑,最后交给ChannelOperator完成底层的IO框架和对应的Dubbo框架的处理逻辑的绑定。 - -- 以上的协议识别完成之后,Channel已经确定了如何处理远程的客户端消息,通过对应的ServerPipeline进行处理即可(在处理的过程中也会根据配置信息决定消息的处理线程)。 - -## 使用方式 -在同一主机上部署多个服务或需要通过负载均衡器访问多个服务。 - -## 参考用例 -[https://github.com/apache/dubbo-samples/tree/master/dubbo-samples-port-unification](https://github.com/apache/dubbo-samples/tree/master/3-extensions/protocol/dubbo-samples-port-unification) - - -## 配置方式 - -关于Dubbo支持的配置方式,可以参考[配置说明](/zh-cn/overview/mannual/java-sdk/reference-manual/config/) - -### 服务多协议导出 - -ext-protocol参数支持配置多个不同的协议,协议之间通过","进行分隔。 - -#### xml 配置 - -```xml - - - - - - -``` - -#### API 配置 - -```java -ProtocolConfig config = new ProtocolConfig(CommonConstants.TRIPLE, -1); - -config.setExtProtocol(CommonConstants.DUBBO+","); -``` - -#### yaml 配置 - -``` yaml -dubbo: - application: - name: dubbo-springboot-demo-provider - protocol: - name: tri - port: -1 - ext-protocol: dubbo, -``` - -#### properties 配置 -```properties -dubbo.protocol.name=tri -dubbo.protocol.ext-protocol=dubbo, -dubbo.protocol.port=20880 -``` - -### Qos接入 - -#### Qos模块导入 - -```xml - - org.apache.dubbo - dubbo-qos - -``` - -完成Qos模块的导入之后,相关的配置项可参考[Qos操作手册](/zh-cn/overview/mannual/java-sdk/reference-manual/qos/overview/)进行配置。 - -默认情况下,基于端口复用的Qos服务在模块导入后是启动的。 - -## 使用方式 - -### Qos使用 - -将Qos协议接入到端口复用的场景下,需要在建立连接之后,客户端先向服务端发送消息,对比将Qos协议通过单个端口提供服务,端口复用版的Qos协议在处理telnet连接的情况下需要用户执行一些操作,完成协议识别(二选一)。 - -1. 直接调用命令 - - 直接调用telnet支持的命令也可以完成识别,在用户不熟悉的情况下可以调用help指令完成识别 - - ![pu-server-image2](/imgs/blog/pu-server/qos-telnet-directcall.png) - -2. 发送telnet命令识别 - - 通过telnet命令建立连接之后,执行以下几个步骤: - - 1. 使用 crtl + "]" 进入到telnet交互界面(telnet默认的escape character) - 2. 调用 "send ayt" 向服务端发送特殊识别字段(为telnet协议的一个特殊字段) - 3. 回车完成消息发送并进入到dubbo的交互界面 - - ![pu-server-imgs3](/imgs/blog/pu-server/qos-telnet-sendayt.png) - - -### 服务引用 - -以[dubbo-samples-port-unification](https://github.com/apache/dubbo-samples/tree/master/3-extensions/protocol/dubbo-samples-port-unification)中的例子作为基础, 引用不同协议的服务和非端口复用情况下的配置是一致的,下面通过Consumer端的InvokerListener输出调用过程中的URL信息。 - -```java -ReferenceConfig reference = new ReferenceConfig<>(); -reference.setInterface(GreetingService.class); -reference.setListener("consumer"); -reference.setProtocol(this.protocol); -// reference.setProtocol(CommonConstants.DUBBO); -// reference.setProtocol(CommonConstants.TRIPLE); -``` - -![pu-server-imgs4](/imgs/blog/pu-server/reference-service.png) diff --git a/content/zh-cn/overview/tasks/protocols/springcloud.md b/content/zh-cn/overview/tasks/protocols/springcloud.md deleted file mode 100644 index 50c39d526cea..000000000000 --- a/content/zh-cn/overview/tasks/protocols/springcloud.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -aliases: - - /zh/overview/tasks/protocols/springcloud/ -description: "" -linkTitle: 调用 Spring Cloud -title: 使用 Dubbo 作为消费端调用 Spring Cloud 服务 -type: docs -weight: 3 ---- - - -最新版本的 Dubbo3、Spring Cloud 体系互通方案已经设计完成,相关示例文档将在随后发布。 diff --git a/content/zh-cn/overview/tasks/protocols/triple.md b/content/zh-cn/overview/tasks/protocols/triple.md deleted file mode 100644 index 84f49fdf76e3..000000000000 --- a/content/zh-cn/overview/tasks/protocols/triple.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -description: "使用 Dubbo 开发 Triple 协议通信服务" -linkTitle: 开发 Triple 服务 -title: 使用 Dubbo 开发 Triple 协议通信服务 -type: docs -weight: 1 ---- - -文档编写中... diff --git a/content/zh-cn/overview/tasks/protocols/web.md b/content/zh-cn/overview/tasks/protocols/web.md deleted file mode 100644 index 955210fc7020..000000000000 --- a/content/zh-cn/overview/tasks/protocols/web.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -aliases: - - /zh/overview/tasks/protocols/web/ -description: "" -linkTitle: 开发 Web 应用 -title: 使用 Dubbo 开发 Web 应用 -type: docs -weight: 2 ---- - -文档编写中... - -Dubbo3 HTTP 协议支持仍在建设中,目前最新的 3.3 开发分支已经有初版原型供体验。正式的生产可用版本预计会在 3.4/3.4 的某个正式版本发布。 - -以下是 Dubbo3 HTTP 协议与编程模式计划支持的几种业务场景: -* 调用 http 协议的微服务体系 -* 发布 http 协议的服务 -* 多协议发布,一个服务同时发布 http&dubbo 协议 - -## 调用 http 协议的微服务体系 -一个典型的应用场景是 Dubbo 调用 Spring Cloud 开发的微服务体系。 - -不同体系的互通,最关键的两点便是地址格式与编码协议的兼容,只要 Dubbo 能自动发现 SpringCloud 体系的地址并能基于 HTTP 协议进行通信即可。Dubbo3 可以做到: -* 支持 SpringCloud 体系的服务发现地址格式 -* 支持 HTTP+JSON 的数据传输格式 - -![img](/imgs/v3/tasks/protocol/http-usecase-1.png) - -基于以上分析,当我们需要调用 Spring Cloud 体系的服务时,只需要在 Dubbo 侧编写标准的 Dubbo Reference 服务引用就可以。同时,为了简化开发工作,**Dubbo 支持标准的 Spring Web 注解**,因此,如果你可以直接在 Dubbo 中复用 Spring Cloud 中的接口定义: - -Spring Cloud 侧的服务定义: -```java -interface SpringCloudRestService { - //xxx -} -``` - -在 Dubbo 侧唯一要做的工作就是定义 Dubbo Reference: - -```java -@DubboReference -private SpringCloudRestService restService; -``` - -## 发布 http 协议的服务 - - -## 多协议发布 - -![img](/imgs/v3/tasks/protocol/http-usecase-1.png) diff --git a/content/zh-cn/overview/tasks/rate-limit/_index.md b/content/zh-cn/overview/tasks/rate-limit/_index.md deleted file mode 100755 index dffcfb97fb5b..000000000000 --- a/content/zh-cn/overview/tasks/rate-limit/_index.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -aliases: - - /zh/overview/tasks/protocols/ -description: 演示 Dubbo 熔断、限流、降级等场景工作方式 -hide: true -linkTitle: 限流降级 -no_list: true -title: 限流降级 -type: docs -weight: 6 ---- - -{{< blocks/section color="white" height="auto">}} - - -{{< /blocks/section >}} diff --git a/content/zh-cn/overview/tasks/rate-limit/hystrix.md b/content/zh-cn/overview/tasks/rate-limit/hystrix.md deleted file mode 100644 index 019523cd5970..000000000000 --- a/content/zh-cn/overview/tasks/rate-limit/hystrix.md +++ /dev/null @@ -1,173 +0,0 @@ ---- -aliases: - - /zh-cn/overview/what/ecosystem/rate-limit/hystrix/ -description: "使用 Hystrix 对 Dubbo 服务进行熔断限流保护" -linkTitle: Hystrix 熔断降级 -title: Hystrix 熔断降级 -type: docs -weight: 2 ---- - -## 背景 - -Hystrix 旨在通过控制那些访问远程系统、服务和第三方库的节点,从而对延迟和故障提供更强大的容错能力。Hystrix具备拥有回退机制和断路器功能的线程和信号隔离,请求缓存和请求打包,以及监控和配置等功能。 - -本文介绍在spring应用里,怎么把 Dubbo 和 Hystrix 结合起来使用。 - -- -- - -## Spring Boot应用 - -Demo 地址: - -### 生成dubbo集成spring boot的应用 - -对于不熟悉dubbo 集成spring boot应用的同学,可以在这里直接生成dubbo + spring boot的工程: - -### 配置spring-cloud-starter-netflix-hystrix - -spring boot官方提供了对hystrix的集成,直接在pom.xml里加入依赖: - -```xml - - org.springframework.cloud - spring-cloud-starter-netflix-hystrix - 1.4.4.RELEASE - -``` - -然后在Application类上增加`@EnableHystrix`来启用hystrix starter: - -```java -@SpringBootApplication -@EnableHystrix -public class ProviderApplication { -``` -### 配置Provider端 -在Dubbo的Provider上增加`@HystrixCommand`配置,这样子调用就会经过Hystrix代理。 -```java -@Service(version = "1.0.0") -public class HelloServiceImpl implements HelloService { - @HystrixCommand(commandProperties = { - @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"), - @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "2000") }) - @Override - public String sayHello(String name) { - // System.out.println("async provider received: " + name); - // return "annotation: hello, " + name; - throw new RuntimeException("Exception to show hystrix enabled."); - } -} -``` -### 配置Consumer端 -对于Consumer端,则可以增加一层method调用,并在method上配置`@HystrixCommand`。当调用出错时,会走到`fallbackMethod = "reliable"`的调用里。 -```java - @Reference(version = "1.0.0") - private HelloService demoService; - @HystrixCommand(fallbackMethod = "reliable") - public String doSayHello(String name) { - return demoService.sayHello(name); - } - public String reliable(String name) { - return "hystrix fallback value"; - } -``` -通过上面的配置,很简单地就完成了Spring Boot里Dubbo + Hystrix的集成。 -## 传统Spring Annotation应用 -Demo地址: -传统spring annotation应用的配置其实也很简单,和spring boot应用不同的是: -1. 显式配置Spring AOP支持:`@EnableAspectJAutoProxy` -2. 显式通过`@Configuration`配置`HystrixCommandAspect` Bean。 -```java - @Configuration - @EnableDubbo(scanBasePackages = "com.alibaba.dubbo.samples.annotation.action") - @PropertySource("classpath:/spring/dubbo-consumer.properties") - @ComponentScan(value = {"com.alibaba.dubbo.samples.annotation.action"}) - @EnableAspectJAutoProxy - static public class ConsumerConfiguration { - @Bean - public HystrixCommandAspect hystrixCommandAspect() { - return new HystrixCommandAspect(); - } - } -``` -## Hystrix集成Spring AOP原理 -在上面的例子里可以看到,Hystrix对Spring的集成是通过Spring AOP来实现的。下面简单分析下实现。 -```java -@Aspect -public class HystrixCommandAspect { - @Pointcut("@annotation(com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand)") - public void hystrixCommandAnnotationPointcut() { - } - @Pointcut("@annotation(com.netflix.hystrix.contrib.javanica.annotation.HystrixCollapser)") - public void hystrixCollapserAnnotationPointcut() { - } - @Around("hystrixCommandAnnotationPointcut() || hystrixCollapserAnnotationPointcut()") - public Object methodsAnnotatedWithHystrixCommand(final ProceedingJoinPoint joinPoint) throws Throwable { - Method method = getMethodFromTarget(joinPoint); - Validate.notNull(method, "failed to get method from joinPoint: %s", joinPoint); - if (method.isAnnotationPresent(HystrixCommand.class) && method.isAnnotationPresent(HystrixCollapser.class)) { - throw new IllegalStateException("method cannot be annotated with HystrixCommand and HystrixCollapser " + - "annotations at the same time"); - } - MetaHolderFactory metaHolderFactory = META_HOLDER_FACTORY_MAP.get(HystrixPointcutType.of(method)); - MetaHolder metaHolder = metaHolderFactory.create(joinPoint); - HystrixInvokable invokable = HystrixCommandFactory.getInstance().create(metaHolder); - ExecutionType executionType = metaHolder.isCollapserAnnotationPresent() ? - metaHolder.getCollapserExecutionType() : metaHolder.getExecutionType(); - Object result; - try { - if (!metaHolder.isObservable()) { - result = CommandExecutor.execute(invokable, executionType, metaHolder); - } else { - result = executeObservable(invokable, executionType, metaHolder); - } - } catch (HystrixBadRequestException e) { - throw e.getCause() != null ? e.getCause() : e; - } catch (HystrixRuntimeException e) { - throw hystrixRuntimeExceptionToThrowable(metaHolder, e); - } - return result; - } -``` -1. `HystrixCommandAspect`里定义了两个注解的AspectJ Pointcut:`@HystrixCommand`, `@HystrixCollapser`。所有带这两个注解的spring bean都会经过AOP处理 -2. 在`@Around` AOP处理函数里,可以看到Hystrix会创建出`HystrixInvokable`,再通过`CommandExecutor`来执行 -## spring-cloud-starter-netflix-hystrix的代码分析 -1. `@EnableHystrix` 引入了`@EnableCircuitBreaker`,`@EnableCircuitBreaker`引入了`EnableCircuitBreakerImportSelector` - ```java - @EnableCircuitBreaker - public @interface EnableHystrix { - } - - @Import(EnableCircuitBreakerImportSelector.class) - public @interface EnableCircuitBreaker { - } - ``` -2. `EnableCircuitBreakerImportSelector`继承了`SpringFactoryImportSelector`,使spring加载`META-INF/spring.factories`里的`EnableCircuitBreaker`声明的配置 - 在`META-INF/spring.factories`里可以找到下面的配置,也就是引入了`HystrixCircuitBreakerConfiguration`。 - ```properties - org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker=\ - org.springframework.cloud.netflix.hystrix.HystrixCircuitBreakerConfiguration - ``` -3. 在`HystrixCircuitBreakerConfiguration`里可以发现创建了`HystrixCommandAspect` - ```java - @Configuration - public class HystrixCircuitBreakerConfiguration { - - @Bean - public HystrixCommandAspect hystrixCommandAspect() { - return new HystrixCommandAspect(); - } - ``` -可见`spring-cloud-starter-netflix-hystrix`实际上也是创建了`HystrixCommandAspect`来集成Hystrix。 -另外`spring-cloud-starter-netflix-hystrix`里还有metrics, health, dashboard等集成。 -## 总结 -- 对于dubbo provider的`@Service`是一个spring bean,直接在上面配置`@HystrixCommand`即可 -- 对于dubbo consumer的`@Reference`,可以通过加一层简单的spring method包装,配置`@HystrixCommand`即可 -- Hystrix本身提供`HystrixCommandAspect`来集成Spring AOP,配置了`@HystrixCommand`和`@HystrixCollapser`的spring method都会被Hystrix处理 -## 链接 -- -- -- -- \ No newline at end of file diff --git a/content/zh-cn/overview/tasks/rate-limit/resilience4j.md b/content/zh-cn/overview/tasks/rate-limit/resilience4j.md deleted file mode 100644 index 5570a80a7e72..000000000000 --- a/content/zh-cn/overview/tasks/rate-limit/resilience4j.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -description: "使用 Resilience4j 断路器、限流器、重试、隔离机制保护 Dubbo 应用" -linkTitle: Resilience4j -title: Resilience4j -type: docs -weight: 3 ---- - -Resilience4j 提供了一组高阶函数(装饰器),包括断路器,限流器,重试,隔离,可以对任何的函数式接口,lambda表达式,或方法的引用进行增强,并且这些装饰器可以进行叠加。这样做的好处是,你可以根据需要选择特定的装饰器进行组合。 - -关于 Resilience4j 与 Dubbo 集成的使用示例请参见 [dubbo-samples-resilience4j](https://github.com/apache/dubbo-samples/tree/master/3-extensions/protocol/dubbo-samples-resilience4j) \ No newline at end of file diff --git a/content/zh-cn/overview/tasks/rate-limit/sentinel.md b/content/zh-cn/overview/tasks/rate-limit/sentinel.md deleted file mode 100644 index b84190692baa..000000000000 --- a/content/zh-cn/overview/tasks/rate-limit/sentinel.md +++ /dev/null @@ -1,101 +0,0 @@ ---- -aliases: - - /zh-cn/overview/tasks/ecosystem/rate-limit/ - - /zh-cn/overview/what/ecosystem/rate-limit/ - - /zh-cn/overview/what/ecosystem/rate-limit/sentinel/ -description: "使用 Sentinel 保护您的应用,防止应用因个别服务的突发流量过载而出现稳定性问题。" -linkTitle: Sentinel 限流 -title: Sentinel 限流 -type: docs -weight: 1 ---- - -## Sentinel 是什么 - -随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件,主要以流量为切入点,从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开发者保障微服务的稳定性。 - -## 一、示例架构说明 - -完整示例项目地址 dubbo-samples-sentinel - -接口定义: - -```java -public interface FooService { - - String sayHello(String name); -} -``` - -接口实现: - -```java -@DubboService(timeout = 3000) -public class FooServiceImpl implements FooService { - - @Override - public String sayHello(String name) { - return String.format("Hello, %s at %s", name, LocalDateTime.now()); - } -} -``` - -限流配置: - -```java -FlowRule flowRule = new FlowRule(FooService.class.getName()) - .setCount(10) - .setGrade(RuleConstant.FLOW_GRADE_QPS); -FlowRuleManager.loadRules(Collections.singletonList(flowRule)); -``` - -## 二、快速启动示例 - -### Step 1: 下载源码 - -```shell script -git clone -b master https://github.com/apache/dubbo-samples.git -cd ./dubbo-samples-sentinel/ -``` - -### Step 2: 构建用例 - -执行 maven 命令,打包 demo 工程 - -```bash -mvn clean package -``` - -### Step 3: 启动 Provider - -```java -java -classpath ./target/dubbo-samples-sentinel-1.0-SNAPSHOT.jar org.apache.samples.sentinel.FooProviderBootstrap -``` - -### Step 4: 启动 OrderService - -```java -java -classpath ./target/dubbo-samples-sentinel-1.0-SNAPSHOT.jar org.apache.samples.sentinel.FooConsumerBootstrap -``` - -可以看到控制台输出中,`Blocked` 代表已经开始拦截。 - -``` -Success: Hello, dubbo at 2022-08-08T15:42:40.809 -Success: Hello, dubbo at 2022-08-08T15:42:40.812 -Success: Hello, dubbo at 2022-08-08T15:42:40.815 -Success: Hello, dubbo at 2022-08-08T15:42:40.818 -Success: Hello, dubbo at 2022-08-08T15:42:40.821 -Success: Hello, dubbo at 2022-08-08T15:42:40.823 -Success: Hello, dubbo at 2022-08-08T15:42:40.826 -Success: Hello, dubbo at 2022-08-08T15:42:40.828 -Success: Hello, dubbo at 2022-08-08T15:42:40.830 -Success: Hello, dubbo at 2022-08-08T15:42:40.834 -Blocked -Blocked -Blocked -Blocked -Blocked -``` - -> 关于 Sentinel 的更多使用方式可以参考:[Sentinel 为 Dubbo 服务保驾护航]({{< relref "../../../../blog/integration/sentinel-introduction-for-dubbo" >}}),[Sentinel 官网](https://sentinelguard.io/zh-cn/index.html) \ No newline at end of file diff --git a/content/zh-cn/overview/tasks/traffic-management/_index.md b/content/zh-cn/overview/tasks/traffic-management/_index.md deleted file mode 100755 index 4c82de14e9ed..000000000000 --- a/content/zh-cn/overview/tasks/traffic-management/_index.md +++ /dev/null @@ -1,198 +0,0 @@ ---- -aliases: - - /zh/overview/tasks/traffic-management/ -description: 演示 Dubbo 流量治理特性的使用方式。 -linkTitle: 流量管控 -no_list: true -title: 流量管控 -type: docs -weight: 3 ---- - - - -此任务基于一个简单的线上商城微服务系统演示了 Dubbo 的流量管控能力。 - -线上商城的架构图如下: - -![shop-arc](/imgs/v3/traffic/shop-arc.png) - -系统由 5 个微服务应用组成: -* `Frontend 商城主页`,作为与用户交互的 web 界面,通过调用 `User`、`Detail`、`Order` 等提供用户登录、商品展示和订单管理等服务。 -* `User 用户服务`,负责用户数据管理、身份校验等。 -* `Order 订单服务`,提供订订单创建、订单查询等服务,依赖 `Detail` 服务校验商品库存等信息。 -* `Detail 商品详情服务`,展示商品详情信息,调用 `Comment` 服务展示用户对商品的评论记录。 -* `Comment 评论服务`,管理用户对商品的评论数据。 - -## 部署商场系统 - -为方便起见,我们将整个系统部署在 Kubernetes 集群,执行以下命令即可完成商城项目部署,项目源码示例在 [dubbo-samples/task](https://github.com/apache/dubbo-samples/tree/master/10-task/dubbo-samples-shop)。 - -```sh -kubectl apply -f https://raw.githubusercontent.com/apache/dubbo-samples/master/10-task/dubbo-samples-shop/deploy/All.yml -``` - -完整的部署架构图如下: - -![shop-arc](/imgs/v3/traffic/shop-arc-deploy2.png) - -`Order 订单服务`有两个版本 `v1` 和 `v2`,`v2` 是订单服务优化后发布的新版本。 -* 版本 v1 只是简单的创建订单,不展示订单详情 -* 版本 v2 在订单创建成功后会展示订单的收货地址详情 - -`Detail` 和 `Comment` 服务也分别有两个版本 `v1` 和 `v2`,我们通过多个版本来演示流量导流后的效果。 -* 版本 `v1` 默认为所有请求提供服务 -* 版本 `v2` 模拟被部署在特定的区域的服务,因此 `v2` 实例会带有特定的标签 - -执行以下命令,确定所有服务、Pod都已正常运行: -```sh -$ kubectl get services -n dubbo-demo - -``` - -```sh -$ kubectl get pods -n dubbo-demo - -``` - -为了保障系统完整性,除了商城相关的几个微服务应用,示例还在后台拉起了 Nacos 注册配置中心、Dubbo Admin 控制台 和 Skywalking 全链路追踪系统。 - -```sh -$ kubectl get services -n dubbo-system - -``` - -```sh -$ kubectl get pods -n dubbo-system - -``` - -## 获得访问地址 -执行以下命令,将集群端口映射到本地端口: - -```sh -kubectl port-forward -n dubbo-demo deployment/shop-frontend 8080:8080 -``` - -```sh -kubectl port-forward -n dubbo-system service/dubbo-admin 38080:38080 -``` - -```sh -kubectl port-forward -n dubbo-system service/skywalking-oap-dashboard 8082:8082 -``` - -此时,打开浏览器,即可通过以下地址访问: -* 商城首页 `http://localhost:8080` -* Dubbo Admin 控制台 `http://localhost:38080` -* Skywalking 控制台 `http://localhost:8082` - -## 任务项 -接下来,试着通过如下任务项给商城增加一些流量管控规则吧。 - -{{< blocks/section color="white" height="auto">}} -
-
-
-
-
-

- 调整超时时间 -

-

通过在运行期动态的调整服务超时时间,可以有效的应对超时设置不合理、系统突发情况等导致的服务频繁超时、服务阻塞等问题,提升系统稳定性。

-
-
-
-
-
-
-

- 增加重试次数 -

-

在服务初次调用失败后,通过重试能有效的提升总体调用成功率。

-
-
-
-
-
-
-

- 访问日志 -

-

访问日志可以很好的记录某台机器在某段时间内处理的所有服务请求信息,运行态动态的开启访问日志对于排查问题非常有帮助。 -

-
-
-
-
-
-
-

- 同机房/区域优先 -

-

同机房/区域优先是指应用调用服务时,优先调用同机房/区域的服务提供者,避免了跨区域带来的网络延时,从而减少了调用的响应时间。 -

-
-
-
-
-
-
-

- 环境隔离 -

-

通过为集群中的某一个或多个应用划分逻辑隔离环境,可用于灰度环境或多套测试环境搭建。 -

-
-
-
-
-
-
-

- 参数路由 -

-

如基于用户 ID 路由流量,将一小部分用户请求转发到最新发布的产品版本,以验证新版本的稳定性、获取用户的产品体验反馈等。 -

-
-
-
-
-
-
-

- 权重比例 -

-

通过规则动态调整单个或一组机器的权重,可以在运行态改变请求流量的分布,实现动态的按比例的流量路由。 -

-
-
-
-
-
-
-

- 服务降级 -

-

服务降级的核心目标就是针对这些弱依赖项,在弱依赖不可用或调用失败时,通过返回降级结果尽可能的维持功能完整。 -

-
-
-
-
-
-
-

- 固定机器导流 -

-

通过将请求固定的转发某一台提供者机器,帮助快速复现开发或线上问题。 -

-
-
-
-
-
-
- -{{< /blocks/section >}} diff --git a/content/zh-cn/overview/tasks/traffic-management/accesslog.md b/content/zh-cn/overview/tasks/traffic-management/accesslog.md deleted file mode 100644 index 776778eb2800..000000000000 --- a/content/zh-cn/overview/tasks/traffic-management/accesslog.md +++ /dev/null @@ -1,85 +0,0 @@ ---- -aliases: - - /zh/overview/tasks/traffic-management/accesslog/ -description: "" -linkTitle: 访问日志 -title: 通过动态开启访问日志跟踪服务调用情况 -type: docs -weight: 3 ---- - - - -访问日志可以很好的记录某台机器在某段时间内处理的所有服务请求信息,包括请求接收时间、远端 IP、请求参数、响应结果等,运行态动态的开启访问日志对于排查问题非常有帮助。 - -## 开始之前 -* [部署 Shop 商城项目](../#部署商场系统) -* 部署并打开 [Dubbo Admin](../.././../reference/admin/architecture/) - -## 任务详情 - -商城的所有用户服务都由 `User` 应用的 UserService 提供,通过这个任务,我们为 `User` 应用的某一台或几台机器开启访问日志,以便观察用户服务的整体访问情况。 - -### 动态开启访问日志 - -Dubbo 通过 `accesslog` 标记识别访问日志的开启状态,我们可以指定日志文件的输出位置,也可以单独打开某台机器的访问日志。 - -![accesslog.png](/imgs/v3/tasks/accesslog/accesslog1.png) - -#### 操作步骤 -1. 打开 Dubbo Admin 控制台 -2. 在左侧导航栏选择【服务治理】>【动态配置】 -3. 点击 "创建",输入应用名 `shop-user` 并勾选 "开启访问日志"(此时访问日志将和普通日志打印在一起)。 - -![Admin 访问日志设置截图](/imgs/v3/tasks/accesslog/accesslog_admin.png) - -再次访问登录页面,登录到 `User` 应用的任意一台机器,可以看到如下格式的访问日志。 - -```text -[2022-12-30 12:36:31.15900] -> [2022-12-30 12:36:31.16000] 192.168.0.103:60943 -> 192.168.0.103:20884 - org.apache.dubbo.samples.UserService login(java.lang.String,java.lang.String) ["test",""], dubbo version: 3.2.0-beta.4-SNAPSHOT, current host: 192.168.0.103 -[2022-12-30 12:36:33.95900] -> [2022-12-30 12:36:33.95900] 192.168.0.103:60943 -> 192.168.0.103:20884 - org.apache.dubbo.samples.UserService getInfo(java.lang.String) ["test"], dubbo version: 3.2.0-beta.4-SNAPSHOT, current host: 192.168.0.103 -[2022-12-30 12:36:31.93500] -> [2022-12-30 12:36:34.93600] 192.168.0.103:60943 -> 192.168.0.103:20884 - org.apache.dubbo.samples.UserService getInfo(java.lang.String) ["test"], dubbo version: 3.2.0-beta.4-SNAPSHOT, current host: 192.168.0.103 -``` - -#### 规则详解 - -**规则 key :** shop-user - -**规则体** - -```yaml -configVersion: v3.0 -enabled: true -configs: - - side: provider - parameters: - accesslog: true -``` - -以下是开启访问日志的关键配置 - -```yaml -parameters: - accesslog: true -``` - -accesslog 的有效值如下: -* `true` 或 `default` 时,访问日志将随业务 logger 一同输出,此时可以在应用内提前配置 `dubbo.accesslog` appender 调整日志的输出位置和格式 -* 具体的文件路径如 `/home/admin/demo/dubbo-access.log`,这样访问日志将打印到指定的文件内 - -在 Admin 界面,还可以单独指定开启某一台机器的访问日志,以方便精准排查问题,对应的后台规则如下: - -```yaml -configVersion: v3.0 -enabled: true -configs: - - match - address: - oneof: - - wildcard: "{ip}:*" - side: provider - parameters: - accesslog: true -``` - -其中,`{ip}` 替换为具体的机器地址即可。 \ No newline at end of file diff --git a/content/zh-cn/overview/tasks/traffic-management/mock.md b/content/zh-cn/overview/tasks/traffic-management/mock.md deleted file mode 100644 index af15637566c3..000000000000 --- a/content/zh-cn/overview/tasks/traffic-management/mock.md +++ /dev/null @@ -1,71 +0,0 @@ ---- -aliases: - - /zh/overview/tasks/traffic-management/mock/ -description: "" -linkTitle: 服务降级 -title: 在大促之前对弱依赖调用进行服务降级 -type: docs -weight: 8 ---- - - - -由于微服务系统的分布式特性,一个服务往往需要依赖非常多的外部服务来实现某一项功能,因此,一个服务的稳定性不但取决于其自身,同时还取决于所有外部依赖的稳定性。我们可以根据这些依赖的重要程度将它们划分为强依赖和弱依赖:强依赖是指那些无论如何都要保证稳定性的服务,如果它们不可用则当前服务也就不可用;弱依赖项指当它们不可用之后当前服务仍能正常工作的依赖项,弱依赖不可用只是影响功能的部分完整性。 - -服务降级的核心目标就是针对这些弱依赖项。在弱依赖不可用或调用失败时,通过返回降级结果尽可能的维持功能完整性;另外,我们有时也会主动的屏蔽一些非关键弱依赖项的调用,比如在大促流量洪峰之前,通过预先设置一些有效的降级策略来短路部分依赖调用,来有效的提升流量高峰时期系统的整体效率和稳定性。 - -## 开始之前 - -* [部署 Shop 商城项目](../#部署商场系统) -* 部署并打开 [Dubbo Admin](../.././../reference/admin/architecture/) - -## 任务详情 - -正常情况下,商品详情页会展示来自顾客的商品评论信息。 - -![mock1.png](/imgs/v3/tasks/mock/mock1.png) - -评论信息的缺失在很多时候并不会影响用户浏览和购买商品,因此,我们定义评论信息属于商品详情页面的弱依赖。接下来,我们就模拟在大促前夕常用的一个策略,通过服务降级提前关闭商品详情页对于评论服务的调用(返回一些本地预先准备好的历史评论数据),来降低集群整体负载水位并提高响应速度。 - -![mock0.png](/imgs/v3/tasks/mock/mock0.png) - -### 通过降级规则短路 Comment 评论服务调用 - -评论数据由 Comment 应用的 `org.apache.dubbo.samples.CommentService` 服务提供,接下来我们就为 `CommentService` 配置降级规则。 - -#### 操作步骤 -1. 打开 Dubbo Admin 控制台 -2. 在左侧导航栏选择【流量管控】>【服务降级】 -3. 点击 "创建",输入服务 `org.apache.dubbo.samples.CommentService` 和降级规则。 - -![Admin 服务降级规则配置截图](/imgs/v3/tasks/mock/mock_admin.png) - -等待降级规则推送完成之后,刷新商品详情页面,发现商品评论信息已经变为我们预先设置的 "Mock Comment",因为商品详情页的 Comment 服务调用已经在本地短路,并没有真正的发送到后端服务提供者机器上。 - -![mock2.png](/imgs/v3/tasks/mock/mock2.png) - -再次刷新页面 - -#### 规则详解 - -**规则 key** :`org.apache.dubbo.samples.CommentService` - -**规则体** - -```yaml -configVersion: v3.0 -enabled: true -configs: - - side: consumer - parameters: - mock: force:return Mock Comment -``` - -## 清理 -为了不影响其他任务效果,通过 Admin 删除或者禁用刚刚配置的降级规则。 - -## 其他事项 - -服务降级功能也可以用于开发测试环境,由于微服务分布式的特点,不同的服务或应用之间都有相互依赖关系,因此,一个服务或应用很难不依赖其他服务而独立部署工作。但测试环境下并不是所有服务都是随时就绪的状态,这对于微服务强调的服务独立演进是一个很大的障碍,通过服务降级这个功能,我们可以模拟或短路应用对其他服务的依赖,从而可以让应用按照自己预期的行为 Mock 外部服务调用的返回结果。具体可参见 [Dubbo Admin 服务 Mock](../.././../reference/admin/mock/) 特性的使用方式。 - -Dubbo 的降级规则用来设置发生降级时的行为和返回值,而对于何时应该执行限流降级动作,即限流降级时机的判断并没有过多涉猎,这一点 Dubbo 通过集成更专业的限流降级产品如 Sentinel 进行了补全,可以配合 Dubbo 降级规则一起使用,具体可参见 [限流降级](/zh-cn/overview/core-features/traffic/circuit-breaking/) 文档。 diff --git a/content/zh-cn/overview/tasks/traffic-management/retry.md b/content/zh-cn/overview/tasks/traffic-management/retry.md deleted file mode 100644 index b4fe5aa6b425..000000000000 --- a/content/zh-cn/overview/tasks/traffic-management/retry.md +++ /dev/null @@ -1,74 +0,0 @@ ---- -aliases: - - /zh/overview/tasks/traffic-management/retry/ -description: "" -linkTitle: 服务重试 -title: 通过重试提高服务调用成功率 -type: docs -weight: 2 ---- - - - -在服务初次调用失败后,通过重试能有效的提升总体调用成功率。但也要注意重试可能带来的响应时间增长,系统负载升高等,另外,重试一般适用于只读服务,或者具有幂等性保证的写服务。 - -## 开始之前 -* [部署 Shop 商城项目](../#部署商场系统) -* 部署并打开 [Dubbo Admin](../.././../reference/admin/architecture/) - -## 任务详情 - -成功登录商城项目后,商城会默认在首页展示当前登录用户的详细信息。 - -![retry1.png](/imgs/v3/tasks/retry/retry1.png) - -但有些时候,提供用户详情的 Dubbo 服务也会由于网络不稳定等各种原因变的不稳定,比如我们提供用户详情的 User 服务就很大概率会调用失败,导致用户无法看到账户的详细信息。 - -![retry2.png](/imgs/v3/tasks/retry/retry2.png) - -用户账户详情查询失败后的系统界面如下: - -![retry2.png](/imgs/v3/tasks/retry/retry4.png) - -商城为了获得带来更好的使用体验,用户信息的加载过程是异步的,因此用户信息加载失败并不会影响对整个商城页面的正常访问,但如果能始终展示完整的用户信息总能给使用者留下更好的印象。 -### 增加重试提高成功率 - -考虑到访问用户详情的过程是异步的(隐藏在页面加载背后),只要最终数据能加载出来,适当的增加等待时间并不是大的问题。因此,我们可以考虑通过对每次用户访问增加重试次数的方式,提高服务详情服务的整体访问成功率。 - -![retry3.png](/imgs/v3/tasks/retry/retry3.png) - -#### 操作步骤 -1. 打开 Dubbo Admin 控制台 -2. 在左侧导航栏选择【服务治理】>【动态配置】 -3. 点击 "创建",输入服务 `org.apache.dubbo.samples.UserService` 和失败重试次数如 `4` 即可。 - -![Admin 重试次数设置截图](/imgs/v3/tasks/retry/retry_admin.png) - -保存后,尝试多次刷新页面,发现用户详情数据总是能正常显示,虽然有时由于重试的缘故加载时间会明显变长。 - -#### 规则详解 - -**规则 key** :`org.apache.dubbo.samples.UserService` - -**规则体** - -```yaml -configVersion: v3.0 -enabled: true -configs: - - side: consumer - parameters: - retries: 5 -``` - -从 `UserService` 服务消费者视角(即 Frontend 应用)增加了调用失败后的重试次数。 - -```yaml -parameters: - retries: 5 -``` - -`side: consumer` 配置会将规则发送到服务消费方实例,所有 `UserService` 服务实例会基于新的 timeout 值进行重新发布,并通过注册中心通知给所有消费方。 - -## 清理 -为了不影响其他任务效果,通过 Admin 删除或者禁用刚刚配置的重试规则。 diff --git a/content/zh-cn/overview/tasks/traffic-management/timeout.md b/content/zh-cn/overview/tasks/traffic-management/timeout.md deleted file mode 100644 index 10e91a53d44e..000000000000 --- a/content/zh-cn/overview/tasks/traffic-management/timeout.md +++ /dev/null @@ -1,73 +0,0 @@ ---- -aliases: - - /zh/overview/tasks/traffic-management/timeout/ -description: 在 Dubbo-Admin 动态调整服务超时时间 -linkTitle: 调整超时时间 -title: 动态调整服务超时时间 -type: docs -weight: 1 ---- - - - -Dubbo 提供动态调整服务超时时间的能力,在无需重启应用的情况下调整服务的超时时间,这对于临时解决一些服务上下游依赖不稳定而导致的调用失败问题非常有效。 - -## 开始之前 -* [部署 Shop 商城项目](../#部署商场系统) -* 部署并打开 [Dubbo Admin](../.././../reference/admin/architecture/) - -## 任务详情 - -商城项目通过 `org.apache.dubbo.samples.UserService` 提供用户信息管理服务,访问 `http://localhost:8080/` 打开商城并输入任意账号密码,点击 `Login` 即可以正常登录到系统。 - -![timeout1.png](/imgs/v3/tasks/timeout/timeout1.png) - -有些场景下,User 服务的运行速度会变慢,比如存储用户数据的数据库负载过高导致查询变慢,这时就会出现 `UserService` 访问超时的情况,导致登录失败。 - -![timeout2.png](/imgs/v3/tasks/timeout/timeout2.png) - -在示例系统中,可通过下图 `Timeout Login` 模拟突发的 `UserService` 访问超时异常 - -![timeout4.png](/imgs/v3/tasks/timeout/timeout4.png) - -### 通过规则动态调整超时时间 - -为了解决突发的登录超时问题,我们只需要适当增加 `UserService` 服务调用的等待时间即可。 - -![timeout3.png](/imgs/v3/tasks/timeout/timeout3.png) - -#### 操作步骤 -1. 打开 Dubbo Admin 控制台 -2. 在左侧导航栏选择【服务治理】>【动态配置】 -3. 点击 "创建",输入服务 `org.apache.dubbo.samples.UserService` 和新的超时时间如 `2000` 即可。 - -![Admin 超时时间设置截图](/imgs/v3/tasks/timeout/timeout_admin.png) - -保存后,再次点击 `Timeout Login`,此时在经过短暂的等待后系统可以正常登录。 - -#### 规则详解 - -**规则 key** :`org.apache.dubbo.samples.UserService` - -**规则体** - -```yaml -configVersion: v3.0 -enabled: true -configs: - - side: provider - parameters: - timeout: 2000 -``` - -从 `UserService` 服务提供者视角,将超时时间总体调整为 2s。 - -```yaml -parameters: - timeout: 2000 -``` - -`side: provider` 配置会将规则发送到服务提供方实例,所有 `UserService` 服务实例会基于新的 timeout 值进行重新发布,并通过注册中心通知给所有消费方。 - -## 清理 -为了不影响其他任务效果,通过 Admin 删除或者禁用刚刚配置的超时规则。 \ No newline at end of file diff --git a/content/zh-cn/overview/tasks/troubleshoot/_index.md b/content/zh-cn/overview/tasks/troubleshoot/_index.md deleted file mode 100755 index 7e624b0b90eb..000000000000 --- a/content/zh-cn/overview/tasks/troubleshoot/_index.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -aliases: - - /zh/overview/tasks/troubleshoot/ -description: 对常见的 Dubbo 异常场景进行排查的思路 -linkTitle: 故障排查 -title: 故障排查 -type: docs -weight: 8 ---- diff --git a/content/zh-cn/overview/what/_index.md b/content/zh-cn/overview/what/_index.md index 322eef5b8cab..fe233661ecf8 100644 --- a/content/zh-cn/overview/what/_index.md +++ b/content/zh-cn/overview/what/_index.md @@ -7,7 +7,7 @@ linkTitle: 介绍 no_list: true title: Dubbo 介绍 type: docs -weight: 3 +weight: 2 --- diff --git a/content/zh-cn/overview/what/core-features/_index.md b/content/zh-cn/overview/what/core-features/_index.md new file mode 100755 index 000000000000..39fca832de3b --- /dev/null +++ b/content/zh-cn/overview/what/core-features/_index.md @@ -0,0 +1,10 @@ +--- +aliases: + - /zh/overview/core-features/ + - /zh-cn/overview/core-features/ +description: Dubbo 核心特性 +linkTitle: 功能 +title: Dubbo 核心特性 +type: docs +weight: 4 +--- diff --git a/content/zh-cn/overview/core-features/ecosystem.md b/content/zh-cn/overview/what/core-features/ecosystem.md similarity index 98% rename from content/zh-cn/overview/core-features/ecosystem.md rename to content/zh-cn/overview/what/core-features/ecosystem.md index bbc0e7f8dbd7..dec12eb049c9 100644 --- a/content/zh-cn/overview/core-features/ecosystem.md +++ b/content/zh-cn/overview/what/core-features/ecosystem.md @@ -1,6 +1,7 @@ --- aliases: - /zh-cn/overview/what/ecosystem/ + - /zh-cn/overview/core-features/ecosystem/ description: 微服务生态 feature: description: | diff --git a/content/zh-cn/overview/core-features/extensibility.md b/content/zh-cn/overview/what/core-features/extensibility.md similarity index 99% rename from content/zh-cn/overview/core-features/extensibility.md rename to content/zh-cn/overview/what/core-features/extensibility.md index dd13e4cda213..38c1b3b9a5aa 100644 --- a/content/zh-cn/overview/core-features/extensibility.md +++ b/content/zh-cn/overview/what/core-features/extensibility.md @@ -1,6 +1,7 @@ --- aliases: - /zh/overview/core-features/extensibility/ + - /zh-cn/overview/core-features/extensibility/ description: 扩展适配 feature: description: | diff --git a/content/zh-cn/overview/core-features/load-balance.md b/content/zh-cn/overview/what/core-features/load-balance.md similarity index 99% rename from content/zh-cn/overview/core-features/load-balance.md rename to content/zh-cn/overview/what/core-features/load-balance.md index 5392d2eb5aa8..fb888d68931c 100644 --- a/content/zh-cn/overview/core-features/load-balance.md +++ b/content/zh-cn/overview/what/core-features/load-balance.md @@ -1,6 +1,7 @@ --- aliases: - /zh/overview/core-features/load-balance/ + - /zh-cn/overview/core-features/load-balance/ description: 负载均衡 linkTitle: 负载均衡 title: 负载均衡 diff --git a/content/zh-cn/overview/core-features/more.md b/content/zh-cn/overview/what/core-features/more.md similarity index 97% rename from content/zh-cn/overview/core-features/more.md rename to content/zh-cn/overview/what/core-features/more.md index b1bb6cfc01fa..17f44509b4e3 100644 --- a/content/zh-cn/overview/core-features/more.md +++ b/content/zh-cn/overview/what/core-features/more.md @@ -1,6 +1,7 @@ --- aliases: - /zh/overview/core-features/more/ + - /zh-cn/overview/core-features/more/ description: 高级功能指南 linkTitle: 更多高级功能 title: 更多高级功能 diff --git a/content/zh-cn/overview/core-features/observability.md b/content/zh-cn/overview/what/core-features/observability.md similarity index 98% rename from content/zh-cn/overview/core-features/observability.md rename to content/zh-cn/overview/what/core-features/observability.md index c61cfe430ca9..230bae6d754e 100644 --- a/content/zh-cn/overview/core-features/observability.md +++ b/content/zh-cn/overview/what/core-features/observability.md @@ -1,6 +1,7 @@ --- aliases: - /zh/overview/core-features/observability/ + - /zh-cn/overview/core-features/observability/ description: 观测服务 feature: description: | diff --git a/content/zh-cn/overview/core-features/protocols.md b/content/zh-cn/overview/what/core-features/protocols.md similarity index 99% rename from content/zh-cn/overview/core-features/protocols.md rename to content/zh-cn/overview/what/core-features/protocols.md index 2e8384612c18..befc5b87b2c1 100644 --- a/content/zh-cn/overview/core-features/protocols.md +++ b/content/zh-cn/overview/what/core-features/protocols.md @@ -1,6 +1,7 @@ --- aliases: - /zh/overview/core-features/protocols/ + - /zh-cn/overview/core-features/protocols/ description: 通信协议 feature: description: | diff --git a/content/zh-cn/overview/core-features/security.md b/content/zh-cn/overview/what/core-features/security.md similarity index 99% rename from content/zh-cn/overview/core-features/security.md rename to content/zh-cn/overview/what/core-features/security.md index dbc8052372e9..cc133bf260de 100644 --- a/content/zh-cn/overview/core-features/security.md +++ b/content/zh-cn/overview/what/core-features/security.md @@ -1,6 +1,7 @@ --- aliases: - /zh/overview/core-features/security/ + - /zh-cn/overview/core-features/security/ description: 认证鉴权 feature: description: | diff --git a/content/zh-cn/overview/core-features/service-definition.md b/content/zh-cn/overview/what/core-features/service-definition.md similarity index 98% rename from content/zh-cn/overview/core-features/service-definition.md rename to content/zh-cn/overview/what/core-features/service-definition.md index 9de24816ae92..907564b35f0e 100644 --- a/content/zh-cn/overview/core-features/service-definition.md +++ b/content/zh-cn/overview/what/core-features/service-definition.md @@ -1,6 +1,7 @@ --- aliases: - /zh/overview/core-features/service-definition/ + - /zh-cn/overview/core-features/service-definition/ description: 微服务开发 linkTitle: 微服务开发 title: 微服务开发 diff --git a/content/zh-cn/overview/core-features/service-definition.md.bak b/content/zh-cn/overview/what/core-features/service-definition.md.bak similarity index 100% rename from content/zh-cn/overview/core-features/service-definition.md.bak rename to content/zh-cn/overview/what/core-features/service-definition.md.bak diff --git a/content/zh-cn/overview/what/core-features/service-discovery.md b/content/zh-cn/overview/what/core-features/service-discovery.md new file mode 100644 index 000000000000..c077de55e061 --- /dev/null +++ b/content/zh-cn/overview/what/core-features/service-discovery.md @@ -0,0 +1,73 @@ +--- +aliases: + - /zh/overview/core-features/service-discovery/ + - /zh-cn/overview/mannual/java-sdk/concepts-and-architecture/service-discovery/ + - /zh-cn/overview/core-features/service-discovery/ +description: 服务发现 +feature: + description: | + Dubbo 提供了高性能、可伸缩的服务发现机制,面向百万集群实例规模设计,默认提供 Nacos、Zookeeper 等注册中心适配并支持自定义扩展。 + title: 服务发现 +linkTitle: 服务发现 +title: 服务发现 +type: docs +weight: 2 +--- + + +Dubbo 提供的是一种 Client-Based 的服务发现机制,依赖第三方注册中心组件来协调服务发现过程,支持常用的注册中心如 Nacos、Consul、Zookeeper 等。 + +以下是 Dubbo 服务发现机制的基本工作原理图: + +![service-discovery](/imgs/v3/feature/service-discovery/arc.png) + +服务发现包含提供者、消费者和注册中心三个参与角色,其中,Dubbo 提供者实例注册 URL 地址到注册中心,注册中心负责对数据进行聚合,Dubbo 消费者从注册中心读取地址列表并订阅变更,每当地址列表发生变化,注册中心将最新的列表通知到所有订阅的消费者实例。 + +## 面向百万实例集群的服务发现机制 +区别于其他很多微服务框架的是,**Dubbo3 的服务发现机制诞生于阿里巴巴超大规模微服务电商集群实践场景,因此,其在性能、可伸缩性、易用性等方面的表现大幅领先于业界大多数主流开源产品**。是企业面向未来构建可伸缩的微服务集群的最佳选择。 + +![service-discovery](/imgs/v3/feature/service-discovery/arc2.png) + +* 首先,Dubbo 注册中心以应用粒度聚合实例数据,消费者按消费需求精准订阅,避免了大多数开源框架如 Istio、Spring Cloud 等全量订阅带来的性能瓶颈。 +* 其次,Dubbo SDK 在实现上对消费端地址列表处理过程做了大量优化,地址通知增加了异步、缓存、bitmap 等多种解析优化,避免了地址更新常出现的消费端进程资源波动。 +* 最后,在功能丰富度和易用性上,服务发现除了同步 ip、port 等端点基本信息到消费者外,Dubbo 还将服务端的 RPC/HTTP 服务及其配置的元数据信息同步到消费端,这让消费者、提供者两端的更细粒度的协作成为可能,Dubbo 基于此机制提供了很多差异化的治理能力。 + +### 高效地址推送实现 + +从注册中心视角来看,它负责以应用名 (dubbo.application.name) 对整个集群的实例地址进行聚合,每个对外提供服务的实例将自身的应用名、实例ip:port 地址信息 (通常还包含少量的实例元数据,如机器所在区域、环境等) 注册到注册中心。 + +> Dubbo2 版本注册中心以服务粒度聚合实例地址,比应用粒度更细,也就意味着传输的数据量更大,因此在大规模集群下也遇到一些性能问题。 +> 针对 Dubbo2 与 Dubbo3 跨版本数据模型不统一的问题,Dubbo3 给出了[平滑迁移方案](/zh-cn/overview/mannual/java-sdk/upgrades-and-compatibility/service-discovery/migration-service-discovery/),可做到模型变更对用户无感。 + +![service-discovery](/imgs/v3/feature/service-discovery/registry-data.png) + +
+每个消费服务的实例从注册中心订阅实例地址列表,相比于一些产品直接将注册中心的全量数据 (应用 + 实例地址) 加载到本地进程,Dubbo 实现了按需精准订阅地址信息。比如一个消费者应用依赖 app1、app2,则只会订阅 app1、app2 的地址列表更新,大幅减轻了冗余数据推送和解析的负担。 + +

+
+ +![service-discovery](/imgs/v3/feature/service-discovery/subscription2.png) + +### 丰富元数据配置 +除了与注册中心的交互,Dubbo3 的完整地址发现过程还有一条额外的元数据通路,我们称之为元数据服务 (MetadataService),实例地址与元数据共同组成了消费者端有效的地址列表。 + +![service-discovery](/imgs/v3/feature/service-discovery/metadata.png) + +完整工作流程如上图所示,首先,消费者从注册中心接收到地址 (ip:port) 信息,然后与提供者建立连接并通过元数据服务读取到对端的元数据配置信息,两部分信息共同组装成 Dubbo 消费端有效的面向服务的地址列表。以上两个步骤都是在实际的 RPC 服务调用发生之前。 + +> 关于 MetadataService 的定义及完整服务发现流程分析,请查看 [应用级服务发现详解]({{< relref "../../../blog/proposals/service-discovery/" >}})。 + +> 对于微服务间服务发现模型的数据同步,REST 定义了一套非常有意思的成熟度模型,感兴趣的朋友可以参考这里的链接 https://www.martinfowler.com/articles/richardsonMaturityModel.html, 按照文章中的 4 级成熟度定义,Dubbo 当前基于接口粒度的模型可以对应到最高的 L4 级别。 + +## 配置方式 +Dubbo 服务发现扩展了多种注册中心组件支持,如 Nacos、Zookeeper、Consul、Redis、kubernetes 等,可以通过配置切换不同实现,同时还支持鉴权、命名空间隔离等配置。具体配置方式请查看 SDK 文档 + +* [Java](../../mannual/java-sdk/reference-manual/registry) +* [Golang](../../mannual/golang-sdk/tutorial/develop/registry) +* [Rust](../../mannual/rust-sdk/) + +Dubbo 还支持一个应用内配置多注册中心的情形如双注册、双订阅等,这对于实现不同集群地址数据互通、集群迁移等场景非常有用处,我们将在未来文档中添加 `最佳实践` 对这部分内容进行示例说明。 + +## 自定义扩展 +注册中心适配支持自定义扩展实现,具体请参见 [Dubbo 可扩展性](../extensibility) diff --git a/content/zh-cn/overview/core-features/service-mesh.md b/content/zh-cn/overview/what/core-features/service-mesh.md similarity index 99% rename from content/zh-cn/overview/core-features/service-mesh.md rename to content/zh-cn/overview/what/core-features/service-mesh.md index d92e94b4a1e7..a122d05b81ee 100644 --- a/content/zh-cn/overview/core-features/service-mesh.md +++ b/content/zh-cn/overview/what/core-features/service-mesh.md @@ -2,6 +2,7 @@ aliases: - /zh/overview/core-features/service-mesh/ - /zh-cn/overview/mannual/java-sdk/concepts-and-architecture/mesh/ + - /zh-cn/overview/core-features/service-mesh/ description: 服务网格 feature: description: | diff --git a/content/zh-cn/overview/what/core-features/traffic/_index.md b/content/zh-cn/overview/what/core-features/traffic/_index.md new file mode 100755 index 000000000000..a0c241b679ce --- /dev/null +++ b/content/zh-cn/overview/what/core-features/traffic/_index.md @@ -0,0 +1,275 @@ +--- +aliases: + - /zh/overview/core-features/traffic/ + - /zh-cn/overview/core-features/traffic/ +description: 流量管控 +feature: + description: | + Dubbo 提供的基于路由规则的流量管控策略,可以帮助实现全链路灰度、金丝雀发布、按比例流量转发、动态调整调试时间、设置重试次数等服务治理能力。 + title: 流量管控 +linkTitle: 流量管控 +no_list: true +title: 流量管控 +type: docs +weight: 4 +--- + + + +Dubbo 提供了丰富的流量管控策略 +* **地址发现与负载均衡**,地址发现支持服务实例动态上下线,负载均衡确保流量均匀的分布到每个实例上。 +* **基于路由规则的流量管控**,路由规则对每次请求进行条件匹配,并将符合条件的请求路由到特定的地址子集。 + +服务发现保证调用方看到最新的提供方实例地址,服务发现机制依赖注册中心 (Zookeeper、Nacos、Istio 等) 实现。在消费端,Dubbo 提供了多种负载均衡策略,如随机负载均衡策略、一致性哈希负载、基于权重的轮询、最小活跃度优先、P2C 等。 + +Dubbo 的流量管控规则可以基于应用、服务、方法、参数等粒度精准的控制流量走向,根据请求的目标服务、方法以及请求体中的其他附加参数进行匹配,符合匹配条件的流量会进一步的按照特定规则转发到一个地址子集。流量管控规则有以下几种: +* 条件路由规则 +* 标签路由规则 +* 脚本路由规则 +* 动态配置规则 + +如果底层用的是基于 HTTP 的 RPC 协议 (如 REST、gRPC、Triple 等),则服务和方法等就统一映射为 HTTP 路径 (path),此时 Dubbo 路由规则相当于是基于 HTTP path 和 headers 的流量分发机制。 + +> Dubbo 中有应用、服务和方法的概念,一个应用可以发布多个服务,一个服务包含多个可被调用的方法,从抽象的视角来看,一次 Dubbo 调用就是某个消费方应用发起了对某个提供方应用内的某个服务特定方法的调用,Dubbo 的流量管控规则可以基于应用、服务、方法、参数等粒度精准的控制流量走向。 + +## 工作原理 + +以下是 Dubbo 单个路由器的工作过程,路由器接收一个服务的实例地址集合作为输入,基于请求上下文 (Request Context) 和 (Router Rule) 实际的路由规则定义对输入地址进行匹配,所有匹配成功的实例组成一个地址子集,最终地址子集作为输出结果继续交给下一个路由器或者负载均衡组件处理。 + +![Router](/imgs/v3/feature/traffic/router1.png) + +通常,在 Dubbo 中,多个路由器组成一条路由链共同协作,前一个路由器的输出作为另一个路由器的输入,经过层层路由规则筛选后,最终生成有效的地址集合。 +* Dubbo 中的每个服务都有一条完全独立的路由链,每个服务的路由链组成可能不同,处理的规则各异,各个服务间互不影响。 +* 对单条路由链而言,即使每次输入的地址集合相同,根据每次请求上下文的不同,生成的地址子集结果也可能不同。 + +![Router](/imgs/v3/feature/traffic/router2.png) + +## 路由规则分类 +### 标签路由规则 + +标签路由通过将某一个服务的实例划分到不同的分组,约束具有特定标签的流量只能在指定分组中流转,不同分组为不同的流量场景服务,从而实现流量隔离的目的。标签路由可以作为蓝绿发布、灰度发布等场景能力的基础。 + +标签路由规则是一个非此即彼的流量隔离方案,也就是匹配`标签`的请求会 100% 转发到有相同`标签`的实例,没有匹配`标签`的请求会 100% 转发到其余未匹配的实例。如果您需要按比例的流量调度方案,请参考示例 [基于权重的按比例流量路由](../../tasks/traffic-management/weight/)。 + +`标签`主要是指对 Provider 端应用实例的分组,目前有两种方式可以完成实例分组,分别是`动态规则打标`和`静态规则打标`。`动态规则打标` 可以在运行时动态的圈住一组机器实例,而 `静态规则打标` 则需要实例重启后才能生效,其中,动态规则相较于静态规则优先级更高,而当两种规则同时存在且出现冲突时,将以动态规则为准。 + +#### 标签规则示例 - 静态打标 + +静态打标需要在服务提供者实例启动前确定,并且必须通过特定的参数 `tag` 指定。 + +##### Provider + +在 Dubbo 实例启动前,指定当前实例的标签,如部署在杭州区域的实例,指定 `tag=gray`。 + +```xml + +``` + +or + +```xml + +``` + +or + +```properties +java -jar xxx-provider.jar -Ddubbo.provider.tag=gray +``` + +##### Consumer + +发起调用的一方,在每次请求前通过 `tag` 设置流量标签,确保流量被调度到带有同样标签的服务提供方。 + +```java +RpcContext.getContext().setAttachment(Constants.TAG_KEY, "gray"); +``` + +#### 标签规则示例 - 动态打标 + +相比于静态打标只能通过 `tag` 属性设置,且在启动阶段就已经固定下来,动态标签可以匹配任意多个属性,根据指定的匹配条件将 Provider 实例动态的划分到不同的流量分组中。 + +##### Provider + +以下规则对 `shop-detail` 应用进行了动态归组,匹配 `env: gray` 的实例被划分到 `gray` 分组,其余不匹配 `env: gray` 继续留在默认分组 (无 tag)。 + +```yaml +configVersion: v3.0 +force: true +enabled: true +key: shop-detail +tags: + - name: gray + match: + - key: env + value: + exact: gray +``` + +> 这里牵涉到如何给您的实例打各种原始 label 的问题,即上面示例中的 `env`,一种方式是直接写在配置文件中,如上面静态规则实例 provider 部分的配置所示,另一种方式是通过预设环境变量指定,关于这点请参考下文的 [如何给实例打标](#如何给实例打标) 一节。 + +##### Consumer + +服务发起方的设置方式和之前静态打标规则保持一致,只需要在每次请求前通过 `tag` 设置流量标签,确保流量被调度到带有同样标签的服务提供方。 + +```java +RpcContext.getContext().setAttachment(Constants.TAG_KEY, "Hangzhou"); +``` + +设置了以上标签的流量,将全部导流到 `hangzhou-region` 划分的实例上。 + +> 请求标签的作用域仅为一次点对点的 RPC 请求。比如,在一个 A -> B -> C 调用链路上,如果 A -> B 调用通过 `setAttachment` 设置了 `tag` 参数,则该参数不会在 B -> C 的调用中生效,同样的,在完成了 A -> B -> C 的整个调用同时 A 收到调用结果后,如果想要相同的 `tag` 参数,则在发起其他调用前仍需要单独设置 `setAttachment`。可以参考 [示例任务 - 环境隔离](../../tasks/traffic-management/isolation/) 了解更多 `tag` 全链路传递解决方案。 + +### 条件路由规则 + +条件路由与标签路由的工作模式非常相似,也是首先对请求中的参数进行匹配,符合匹配条件的请求将被转发到包含特定实例地址列表的子集。相比于标签路由,条件路由的匹配方式更灵活: + +* 在标签路由中,一旦给某一台或几台机器实例打了标签,则这部分实例就会被立马从通用流量集合中移除,不同标签之间不会再有交集。有点类似下图,地址集合在输入阶段就已经划分明确。 + +![tag-condition-compare](/imgs/v3/feature/traffic/tag-condition-compare1.png) + +* 而从条件路由的视角,所有的实例都是一致的,路由过程中不存在分组隔离的问题,每次路由过滤都是基于全量地址中执行 + +![tag-condition-compare](/imgs/v3/feature/traffic/tag-condition-compare2.png) + +条件路由规则的主体 `conditions` 主要包含两部分内容: + +* => 之前的为请求参数匹配条件,指定的 `匹配条件指定的参数` 将与 `消费者的请求上下文 (URL)、甚至方法参数` 进行对比,当消费者满足匹配条件时,对该消费者执行后面的地址子集过滤规则。 +* => 之后的为地址子集过滤条件,指定的 `过滤条件指定的参数` 将与 `提供者实例地址 (URL)` 进行对比,消费者最终只能拿到符合过滤条件的实例列表,从而确保流量只会发送到符合条件的地址子集。 + * 如果匹配条件为空,表示对所有请求生效,如:`=> status != staging` + * 如果过滤条件为空,表示禁止来自相应请求的访问,如:`application = product =>` + + +#### 条件路由规则示例 + +基于以下示例规则,所有 `org.apache.dubbo.demo.CommentService` 服务调用都将被转发到与当前消费端机器具有相同 `region` 标记的地址子集。`$region` 是特殊引用符号,执行过程中将读取消费端机器的实际的 `region` 值替代。 + +```yaml +configVersion: v3.0 +enabled: true +force: false +key: org.apache.dubbo.samples.CommentService +conditions: + - '=> region = $region' +``` + +> 针对条件路由,我们通常推荐配置 `scope: service` 的规则,因为它可以跨消费端应用对所有消费特定服务 (service) 的应用生效。关于 Dubbo 规则中的 `scope` 以及 `service`、`application` 的说明请阅读 [条件路由规则手册](./condition-rule)。 + +条件路由规则还支持设置具体的机器地址如 ip 或 port,这种情况下使用条件路由可以处理一些开发或线上机器的临时状况,实现**黑名单、白名单、实例临时摘除**等运维效果,如以下规则可以将机器 `172.22.3.91` 从服务的可用列表中排除。 + +```yaml +=> host != 172.22.3.91 +``` + +条件路由还支持基于请求参数的匹配,示例如下: + +```yaml +conditions: + - method=getDetail&arguments[0]=dubbo => port=20880 +``` + +### 动态配置规则 +通过 Dubbo 提供的动态配置规则,您可以动态的修改 Dubbo 服务进程的运行时行为,整个过程不需要重启,配置参数实时生效。基于这个强大的功能,基本上所有运行期参数都可以动态调整,比如超时时间、临时开启 Access Log、修改 Tracing 采样率、调整限流降级参数、负载均衡、线程池配置、日志等级、给机器实例动态打标签等。与上文讲到的流量管控规则类似,动态配置规则支持应用、服务两个粒度,也就是说您一次可以选择只调整应用中的某一个或几个服务的参数配置。 + +当然,出于系统稳定性、安全性的考量,有些特定的参数是不允许动态修改的,但除此之外,基本上所有参数都允许动态修改,很多强大的运行态能力都可以通过这个规则实现,您可以找个示例应用去尝试一下。通常 URL 地址中的参数均可以修改,这在每个语言实现的参考手册里也记录了一些更详细的说明。 + +#### 动态配置规则示例 - 修改超时时间 + +以下示例将 `org.apache.dubbo.samples.UserService` 服务的超时参数调整为 2000ms + +```yaml +configVersion: v3.0 +scope: service +key: org.apache.dubbo.samples.UserService +enabled: true +configs: + - side: provider + parameters: + timeout: 2000 +``` + +以下部分指定这个配置是服务粒度,具体变更的服务名为 `org.apache.dubbo.samples.UserService`。`scope` 支持 `service`、`application` 两个可选值,如果 `scope: service`,则 `key` 应该配置为 `version/service:group` 格式。 + +```yaml +scope: service +key: org.apache.dubbo.samples.UserService +``` + +> 关于 Dubbo 规则中的 `scope` 以及 `service`、`application` 的说明请参考 [动态配置参考手册](./configuration-rule/) 或 [动态配置示例](../../tasks/traffic-management/timeout/)。 + +`parameters` 参数指定了新的修改值,这里将通过 `timeout: 2000` 将超时时间设置为 2000ms。 + +```yaml +parameters: + timeout: 2000 +``` + +### 脚本路由规则 +脚本路由是最直观的路由方式,同时它也是当前最灵活的路由规则,因为你可以在脚本中定义任意的地址筛选规则。如果我们为某个服务定义一条脚本规则,则后续所有请求都会先执行一遍这个脚本,脚本过滤出来的地址即为请求允许发送到的、有效的地址集合。 + +```yaml +configVersion: v3.0 +key: demo-provider +type: javascript +enabled: true +script: | + (function route(invokers,invocation,context) { + var result = new java.util.ArrayList(invokers.size()); + for (i = 0; i < invokers.size(); i ++) { + if ("10.20.3.3".equals(invokers.get(i).getUrl().getHost())) { + result.add(invokers.get(i)); + } + } + return result; + } (invokers, invocation, context)); // 表示立即执行方法 +``` + +## 如何给实例打标 + +当前,有两种方式可以在启动阶段为 Dubbo 实例指定标签,一种是之前提到的应用内配置的方式,如在 xml 文件中设置 ``,应用打包部署后即自动被打标。 + +还有一种更灵活的方式,那就是通过读取所部署机器上的环境信息给应用打标,这样应用的标签就可以跟随实例动态的自动填充,避免每次更换部署环境就重新打包应用镜像的问题。当前 Dubbo 能自动读取以下环境变量配置: + +```yaml +spec: + containers: + - name: detail + image: apache/demo-detail:latest + env: + - name: DUBBO_LABELS + value: "region=hangzhou; env=gray" +``` + +```yaml +spec: + containers: + - name: detail + image: apache/demo-detail:latest + env: + - name: DUBBO_ENV_KEYS + value: "REGION, ENV" + - name: REGION + value: "hangzhou" + - name: ENV + value: "gray" +``` + +如果您有不同的实例环境保存机制,可以通过扩展 `InfraAdapter 扩展点` 来自定义自己的标签加载方式。如果您的应用是部署在 Kubernetes 环境下,并且已经接入了服务网格体系,则也可以使用标准 deployment 标签的方式打标,具体请跟随 [服务网格任务示例](../../tasks/mesh/) 学习。 + +## 如何配置流量规则 +Dubbo 提供了控制台 Dubbo Admin,帮助您可视化的下发流量管控规则,并实时监控规则生效情况。 + +![Admin](/imgs/v3/what/admin.png) + +Dubbo 还提供了 `dubboctl` 命令行工具,需要有 Dubbo Admin 提前部署就绪,因为 dubboctl 是通过与 Admin 进行 http 通信完成规则下发的。 + +如果您使用的是如 Istio 的服务网格架构,还可以使用 Istioctl、kubectl 等下发 Istio 标准规则。 + +## 接入服务网格 + +以上介绍的都是 Dubbo 体系内的流量治理规则,如果您对服务网格架构感兴趣,则可以将 Dubbo 服务接入服务网格体系,这样,您就可以使用服务网格提供的流量治理能力,如 Istio 体系的 VirtualService 等。 + +具体请参见 [Dubbo 中的服务网格架构](../service-mesh)。 + +## 跟随示例学习 +我们搭建了一个 [线上商城系统](../../tasks/traffic-management/) 供您学习流量规则的具体使用。 diff --git a/content/zh-cn/overview/core-features/traffic/circuit-breaking.md b/content/zh-cn/overview/what/core-features/traffic/circuit-breaking.md similarity index 98% rename from content/zh-cn/overview/core-features/traffic/circuit-breaking.md rename to content/zh-cn/overview/what/core-features/traffic/circuit-breaking.md index 4b1444cd9955..24d0af733f62 100644 --- a/content/zh-cn/overview/core-features/traffic/circuit-breaking.md +++ b/content/zh-cn/overview/what/core-features/traffic/circuit-breaking.md @@ -1,4 +1,6 @@ --- +aliases: + - /zh-cn/overview/core-features/traffic/circuit-breaking/ description: "" linkTitle: 限流 & 熔断 title: 限流 & 熔断 diff --git a/content/zh-cn/overview/core-features/traffic/condition-rule.md b/content/zh-cn/overview/what/core-features/traffic/condition-rule.md similarity index 98% rename from content/zh-cn/overview/core-features/traffic/condition-rule.md rename to content/zh-cn/overview/what/core-features/traffic/condition-rule.md index 8fb8e7865d4d..5c9898444a6e 100644 --- a/content/zh-cn/overview/core-features/traffic/condition-rule.md +++ b/content/zh-cn/overview/what/core-features/traffic/condition-rule.md @@ -1,6 +1,7 @@ --- aliases: - /zh/overview/core-features/traffic/condition-rule/ + - /zh-cn/overview/core-features/traffic/condition-rule/ description: "" linkTitle: 条件路由 title: 条件路由规则 diff --git a/content/zh-cn/overview/core-features/traffic/configuration-rule.md b/content/zh-cn/overview/what/core-features/traffic/configuration-rule.md similarity index 98% rename from content/zh-cn/overview/core-features/traffic/configuration-rule.md rename to content/zh-cn/overview/what/core-features/traffic/configuration-rule.md index dd58e2911b5a..0eec2d23e523 100644 --- a/content/zh-cn/overview/core-features/traffic/configuration-rule.md +++ b/content/zh-cn/overview/what/core-features/traffic/configuration-rule.md @@ -1,6 +1,7 @@ --- aliases: - /zh/overview/core-features/traffic/configuration-rule/ + - /zh-cn/overview/core-features/traffic/configuration-rule/ description: "" linkTitle: 动态配置 title: 动态配置规则 diff --git a/content/zh-cn/overview/what/core-features/traffic/introduction.md b/content/zh-cn/overview/what/core-features/traffic/introduction.md new file mode 100644 index 000000000000..dd1ed1108222 --- /dev/null +++ b/content/zh-cn/overview/what/core-features/traffic/introduction.md @@ -0,0 +1,268 @@ +--- +aliases: + - /zh/overview/core-features/traffic/ + - /zh-cn/overview/core-features/traffic/ +description: "Dubbo 的流量管控规则可以基于应用、服务、方法、参数等粒度精准的控制流量走向,根据请求的目标服务、方法以及请求体中的其他附加参数进行匹配,符合匹配条件的流量会进一步的按照特定规则转发到一个地址子集" +linkTitle: 路由机制介绍 +title: Dubbo 路由(router)机制及其如何实现流量管控介绍 +type: docs +weight: 1 +--- + +Dubbo 提供了丰富的流量管控策略 +* **地址发现与负载均衡**,地址发现支持服务实例动态上下线,负载均衡确保流量均匀的分布到每个实例上。 +* **基于路由规则的流量管控**,路由规则对每次请求进行条件匹配,并将符合条件的请求路由到特定的地址子集。 + +服务发现保证调用方看到最新的提供方实例地址,服务发现机制依赖注册中心 (Zookeeper、Nacos、Istio 等) 实现。在消费端,Dubbo 提供了多种负载均衡策略,如随机负载均衡策略、一致性哈希负载、基于权重的轮询、最小活跃度优先、P2C 等。 + +Dubbo 的流量管控规则可以基于应用、服务、方法、参数等粒度精准的控制流量走向,根据请求的目标服务、方法以及请求体中的其他附加参数进行匹配,符合匹配条件的流量会进一步的按照特定规则转发到一个地址子集。流量管控规则有以下几种: +* 条件路由规则 +* 标签路由规则 +* 脚本路由规则 +* 动态配置规则 + +如果底层用的是基于 HTTP 的 RPC 协议 (如 REST、gRPC、Triple 等),则服务和方法等就统一映射为 HTTP 路径 (path),此时 Dubbo 路由规则相当于是基于 HTTP path 和 headers 的流量分发机制。 + +> Dubbo 中有应用、服务和方法的概念,一个应用可以发布多个服务,一个服务包含多个可被调用的方法,从抽象的视角来看,一次 Dubbo 调用就是某个消费方应用发起了对某个提供方应用内的某个服务特定方法的调用,Dubbo 的流量管控规则可以基于应用、服务、方法、参数等粒度精准的控制流量走向。 + +## Router工作原理 + +以下是 Dubbo 单个路由器的工作过程,路由器接收一个服务的实例地址集合作为输入,基于请求上下文 (Request Context) 和 (Router Rule) 实际的路由规则定义对输入地址进行匹配,所有匹配成功的实例组成一个地址子集,最终地址子集作为输出结果继续交给下一个路由器或者负载均衡组件处理。 + +![Router](/imgs/v3/feature/traffic/router1.png) + +通常,在 Dubbo 中,多个路由器组成一条路由链共同协作,前一个路由器的输出作为另一个路由器的输入,经过层层路由规则筛选后,最终生成有效的地址集合。 +* Dubbo 中的每个服务都有一条完全独立的路由链,每个服务的路由链组成可能不通,处理的规则各异,各个服务间互不影响。 +* 对单条路由链而言,即使每次输入的地址集合相同,根据每次请求上下文的不同,生成的地址子集结果也可能不同。 + +![Router](/imgs/v3/feature/traffic/router2.png) + +## 路由规则分类 +### 标签路由规则 + +标签路由通过将某一个服务的实例划分到不同的分组,约束具有特定标签的流量只能在指定分组中流转,不同分组为不同的流量场景服务,从而实现流量隔离的目的。标签路由可以作为蓝绿发布、灰度发布等场景能力的基础。 + +标签路由规则是一个非此即彼的流量隔离方案,也就是匹配`标签`的请求会 100% 转发到有相同`标签`的实例,没有匹配`标签`的请求会 100% 转发到其余未匹配的实例。如果您需要按比例的流量调度方案,请参考示例 [基于权重的按比例流量路由](../../tasks/traffic-management/weight/)。 + +`标签`主要是指对 Provider 端应用实例的分组,目前有两种方式可以完成实例分组,分别是`动态规则打标`和`静态规则打标`。`动态规则打标` 可以在运行时动态的圈住一组机器实例,而 `静态规则打标` 则需要实例重启后才能生效,其中,动态规则相较于静态规则优先级更高,而当两种规则同时存在且出现冲突时,将以动态规则为准。 + +#### 标签规则示例 - 静态打标 + +静态打标需要在服务提供者实例启动前确定,并且必须通过特定的参数 `tag` 指定。 + +##### Provider + +在 Dubbo 实例启动前,指定当前实例的标签,如部署在杭州区域的实例,指定 `tag=gray`。 + +```xml + +``` + +or + +```xml + +``` + +or + +```properties +java -jar xxx-provider.jar -Ddubbo.provider.tag=gray +``` + +##### Consumer + +发起调用的一方,在每次请求前通过 `tag` 设置流量标签,确保流量被调度到带有同样标签的服务提供方。 + +```java +RpcContext.getContext().setAttachment(Constants.TAG_KEY, "gray"); +``` + +#### 标签规则示例 - 动态打标 + +相比于静态打标只能通过 `tag` 属性设置,且在启动阶段就已经固定下来,动态标签可以匹配任意多个属性,根据指定的匹配条件将 Provider 实例动态的划分到不同的流量分组中。 + +##### Provider + +以下规则对 `shop-detail` 应用进行了动态归组,匹配 `env: gray` 的实例被划分到 `gray` 分组,其余不匹配 `env: gray` 继续留在默认分组 (无 tag)。 + +```yaml +configVersion: v3.0 +force: true +enabled: true +key: shop-detail +tags: + - name: gray + match: + - key: env + value: + exact: gray +``` + +> 这里牵涉到如何给您的实例打各种原始 label 的问题,即上面示例中的 `env`,一种方式是直接写在配置文件中,如上面静态规则实例 provider 部分的配置所示,另一种方式是通过预设环境变量指定,关于这点请参考下文的 [如何给实例打标](#如何给实例打标) 一节。 + +##### Consumer + +服务发起方的设置方式和之前静态打标规则保持一致,只需要在每次请求前通过 `tag` 设置流量标签,确保流量被调度到带有同样标签的服务提供方。 + +```java +RpcContext.getContext().setAttachment(Constants.TAG_KEY, "Hangzhou"); +``` + +设置了以上标签的流量,将全部导流到 `hangzhou-region` 划分的实例上。 + +> 请求标签的作用域仅为一次点对点的 RPC 请求。比如,在一个 A -> B -> C 调用链路上,如果 A -> B 调用通过 `setAttachment` 设置了 `tag` 参数,则该参数不会在 B -> C 的调用中生效,同样的,在完成了 A -> B -> C 的整个调用同时 A 收到调用结果后,如果想要相同的 `tag` 参数,则在发起其他调用前仍需要单独设置 `setAttachment`。可以参考 [示例任务 - 环境隔离](../../tasks/traffic-management/isolation/) 了解更多 `tag` 全链路传递解决方案。 + +### 条件路由规则 + +条件路由与标签路由的工作模式非常相似,也是首先对请求中的参数进行匹配,符合匹配条件的请求将被转发到包含特定实例地址列表的子集。相比于标签路由,条件路由的匹配方式更灵活: + +* 在标签路由中,一旦给某一台或几台机器实例打了标签,则这部分实例就会被立马从通用流量集合中移除,不同标签之间不会再有交集。有点类似下图,地址集合在输入阶段就已经划分明确。 + +![tag-condition-compare](/imgs/v3/feature/traffic/tag-condition-compare1.png) + +* 而从条件路由的视角,所有的实例都是一致的,路由过程中不存在分组隔离的问题,每次路由过滤都是基于全量地址中执行 + +![tag-condition-compare](/imgs/v3/feature/traffic/tag-condition-compare2.png) + +条件路由规则的主体 `conditions` 主要包含两部分内容: + +* => 之前的为请求参数匹配条件,指定的 `匹配条件指定的参数` 将与 `消费者的请求上下文 (URL)、甚至方法参数` 进行对比,当消费者满足匹配条件时,对该消费者执行后面的地址子集过滤规则。 +* => 之后的为地址子集过滤条件,指定的 `过滤条件指定的参数` 将与 `提供者实例地址 (URL)` 进行对比,消费者最终只能拿到符合过滤条件的实例列表,从而确保流量只会发送到符合条件的地址子集。 + * 如果匹配条件为空,表示对所有请求生效,如:`=> status != staging` + * 如果过滤条件为空,表示禁止来自相应请求的访问,如:`application = product =>` + + +#### 条件路由规则示例 + +基于以下示例规则,所有 `org.apache.dubbo.demo.CommentService` 服务调用都将被转发到与当前消费端机器具有相同 `region` 标记的地址子集。`$region` 是特殊引用符号,执行过程中将读取消费端机器的实际的 `region` 值替代。 + +```yaml +configVersion: v3.0 +enabled: true +force: false +key: org.apache.dubbo.samples.CommentService +conditions: + - '=> region = $region' +``` + +> 针对条件路由,我们通常推荐配置 `scope: service` 的规则,因为它可以跨消费端应用对所有消费特定服务 (service) 的应用生效。关于 Dubbo 规则中的 `scope` 以及 `service`、`application` 的说明请阅读 [条件路由规则手册](./condition-rule)。 + +条件路由规则还支持设置具体的机器地址如 ip 或 port,这种情况下使用条件路由可以处理一些开发或线上机器的临时状况,实现**黑名单、白名单、实例临时摘除**等运维效果,如以下规则可以将机器 `172.22.3.91` 从服务的可用列表中排除。 + +```yaml +=> host != 172.22.3.91 +``` + +条件路由还支持基于请求参数的匹配,示例如下: + +```yaml +conditions: + - method=getDetail&arguments[0]=dubbo => port=20880 +``` + +### 动态配置规则 +通过 Dubbo 提供的动态配置规则,您可以动态的修改 Dubbo 服务进程的运行时行为,整个过程不需要重启,配置参数实时生效。基于这个强大的功能,基本上所有运行期参数都可以动态调整,比如超时时间、临时开启 Access Log、修改 Tracing 采样率、调整限流降级参数、负载均衡、线程池配置、日志等级、给机器实例动态打标签等。与上文讲到的流量管控规则类似,动态配置规则支持应用、服务两个粒度,也就是说您一次可以选择只调整应用中的某一个或几个服务的参数配置。 + +当然,出于系统稳定性、安全性的考量,有些特定的参数是不允许动态修改的,但除此之外,基本上所有参数都允许动态修改,很多强大的运行态能力都可以通过这个规则实现,您可以找个示例应用去尝试一下。通常 URL 地址中的参数均可以修改,这在每个语言实现的参考手册里也记录了一些更详细的说明。 + +#### 动态配置规则示例 - 修改超时时间 + +以下示例将 `org.apache.dubbo.samples.UserService` 服务的超时参数调整为 2000ms + +```yaml +configVersion: v3.0 +scope: service +key: org.apache.dubbo.samples.UserService +enabled: true +configs: + - side: provider + parameters: + timeout: 2000 +``` + +以下部分指定这个配置是服务粒度,具体变更的服务名为 `org.apache.dubbo.samples.UserService`。`scope` 支持 `service`、`application` 两个可选值,如果 `scope: service`,则 `key` 应该配置为 `version/service:group` 格式。 + +```yaml +scope: service +key: org.apache.dubbo.samples.UserService +``` + +> 关于 Dubbo 规则中的 `scope` 以及 `service`、`application` 的说明请参考 [动态配置参考手册](./configuration-rule/) 或 [动态配置示例](../../tasks/traffic-management/timeout/)。 + +`parameters` 参数指定了新的修改值,这里将通过 `timeout: 2000` 将超时时间设置为 2000ms。 + +```yaml +parameters: + timeout: 2000 +``` + +### 脚本路由规则 +脚本路由是最直观的路由方式,同时它也是当前最灵活的路由规则,因为你可以在脚本中定义任意的地址筛选规则。如果我们为某个服务定义一条脚本规则,则后续所有请求都会先执行一遍这个脚本,脚本过滤出来的地址即为请求允许发送到的、有效的地址集合。 + +```yaml +configVersion: v3.0 +key: demo-provider +type: javascript +enabled: true +script: | + (function route(invokers,invocation,context) { + var result = new java.util.ArrayList(invokers.size()); + for (i = 0; i < invokers.size(); i ++) { + if ("10.20.3.3".equals(invokers.get(i).getUrl().getHost())) { + result.add(invokers.get(i)); + } + } + return result; + } (invokers, invocation, context)); // 表示立即执行方法 +``` + +## 如何给实例打标 + +当前,有两种方式可以在启动阶段为 Dubbo 实例指定标签,一种是之前提到的应用内配置的方式,如在 xml 文件中设置 ``,应用打包部署后即自动被打标。 + +还有一种更灵活的方式,那就是通过读取所部署机器上的环境信息给应用打标,这样应用的标签就可以跟随实例动态的自动填充,避免每次更换部署环境就重新打包应用镜像的问题。当前 Dubbo 能自动读取以下环境变量配置: + +```yaml +spec: + containers: + - name: detail + image: apache/demo-detail:latest + env: + - name: DUBBO_LABELS + value: "region=hangzhou; env=gray" +``` + +```yaml +spec: + containers: + - name: detail + image: apache/demo-detail:latest + env: + - name: DUBBO_ENV_KEYS + value: "REGION, ENV" + - name: REGION + value: "hangzhou" + - name: ENV + value: "gray" +``` + +如果您有不同的实例环境保存机制,可以通过扩展 `InfraAdapter 扩展点` 来自定义自己的标签加载方式。如果您的应用是部署在 Kubernetes 环境下,并且已经接入了服务网格体系,则也可以使用标准 deployment 标签的方式打标,具体请跟随 [服务网格任务示例](../../tasks/mesh/) 学习。 + +## 如何配置流量规则 +Dubbo 提供了控制台 Dubbo Admin,帮助您可视化的下发流量管控规则,并实时监控规则生效情况。 + +![Admin](/imgs/v3/what/admin.png) + +Dubbo 还提供了 `dubboctl` 命令行工具,需要有 Dubbo Admin 提前部署就绪,因为 dubboctl 是通过与 Admin 进行 http 通信完成规则下发的。 + +如果您使用的是如 Istio 的服务网格架构,还可以使用 Istioctl、kubectl 等下发 Istio 标准规则。 + +## 接入服务网格 + +以上介绍的都是 Dubbo 体系内的流量治理规则,如果您对服务网格架构感兴趣,则可以将 Dubbo 服务接入服务网格体系,这样,您就可以使用服务网格提供的流量治理能力,如 Istio 体系的 VirtualService 等。 + +具体请参见 [Dubbo 中的服务网格架构](../service-mesh)。 + +## 跟随示例学习 +我们搭建了一个 [线上商城系统](../../tasks/traffic-management/) 供您学习流量规则的具体使用。 diff --git a/content/zh-cn/overview/what/core-features/traffic/mesh-rule.md b/content/zh-cn/overview/what/core-features/traffic/mesh-rule.md new file mode 100644 index 000000000000..924167bcae09 --- /dev/null +++ b/content/zh-cn/overview/what/core-features/traffic/mesh-rule.md @@ -0,0 +1,373 @@ +--- +type: docs +title: "Mesh 路由规则" +linkTitle: "Mesh 路由" +weight: 50 +description: "" +--- + +Dubbo Mesh 路由规则是基于 Istio 的 VirtualService、DestinationRule 改造而来,总体思路和格式可以参考 Istio 流量管控规则参考手册:[Istio VirtualService](https://istio.io/latest/docs/reference/config/networking/virtual-service/) 和 [Istio DestinationRule](https://istio.io/latest/docs/reference/config/networking/destination-rule/) + +本文描述了 Dubbo Mesh 路由规则的设计原理,以及它和 Istio 规则的差异等。参考链接:https://www.yuque.com/docs/share/c132d5db-0dcb-487f-8833-7c7732964bd4?#。 + + +### 基本思想 +基于路由链,采用Pipeline的处理方式,如下图所示: + +![route-rule1.png](/imgs/user/route-rule1.png) + + +可以把路由链的逻辑简单的理解为 target = rn(...r3(r2(r1(src))))。对于每一个 router 内部的逻辑,可以抽象为输入地址 addrs-in 与 router 中按全量地址 addrs-all 实现切分好的 n 个互不相交的地址池 addrs-pool-1 ... addrs-pool-n 按实现定义好的规则取交集作为输出 addrs-out。以此类推,完成整个路由链的计算。 + +![route-rule2.png](/imgs/user/route-rule2.png) + +另外一方面,如果 router(n) 需要执行 fallback 逻辑的时候,那么需要经过 router(n) 就应该决定好 fallback 逻辑 + + +### fallback 处理原则 + +由于多个 router 之间多个条件组件之后,很容易出现地址被筛选为空的情况,那么我们需要针对这情况进行 fallback 处理,保证业务在正确性的前提下,能够顺利找到有效地址。 + +首先我们看一下以下规则 + +```yaml +apiVersion: service.dubbo.apache.org/v1alpha1 +kind: VirtualService +metadata: + name: demo-route +spec: + hosts: + - demo // 统一定义为应用名 + dubbo: + - service: + - exact: com.taobao.hsf.demoService:1.0.0 + - exact: com.taobao.hsf.demoService:2.0.0 + routedetail: + - name: sayHello-String-method-route + match: + - method: + name_match: + exact: "sayHello" + ..... + argp: + - string + route: + - destination: + host: demo + subset: v1 + fallback: + destination: + host: demo + subset: v2 + fallback: + destination: + host: demo + subset: v3 + + - name: sayHello-method-route + match: + - method: + name_match: + exact: "s-method" + route: + - destination: + host: demo + subset: v2 + fallback: + destination: + host: demo + subset: v3 + + - name: interface-route + route: + - destination: + host: demo + subset: v3 + + - service: + + .... +--- +apiVersion: service.dubbo.apache.org/v1alpha1 +kind: DestinationRule +metadata: + name: demo-route +spec: + host: demo + subsets: + - name: v1 + labels: + sigma.ali/mg: v1-host + + - name: v2 + labels: + sigma.ali/mg: v2-host + + - name: v3 + labels: + sigma.ali/mg: v3-host + +``` + +我们以脚本路由为例,这个脚本路由的匹配条件是遵循一个原则的,就是匹配的范围是从精确到广泛的一个过程,在这个示例来说,就是 sayHello(string)参数 -> sayHello 方法 -> 接口级路由 的一个匹配查找过程。 + +那么如果我们已经满足某个条件,但是选到的 subset 地址为空,我们将如何进行 fallback 处理呢? + +以匹配 sayHello(string)参数 条件为例,我们选择到的是 v1 subset,如果是空,我们可以向上一级是寻找地址,也就是方法级去寻找地址,具体的配置为下 + +```yaml + - name: sayHello-String-method-route + match: + - method: + name_match: + exact: "sayHello" + ..... + argp: + - string + route: + - destination: + host: demo + subset: v1 + fallback: + destination: + host: demo + subset: v2 + fallback: + destination: + host: demo + subset: v3 +``` + +此时我们选到的地址是 v2 方法级地址,如果 v2 还是没有地址,根据规则的定义,我们是可以 fallback 到 v3 接口级。 + +假设我们有一个方法匹配时,如果没有地址,需要不进行 fallback,直接报错,我们可以这样配置 + + +```yaml +apiVersion: service.dubbo.apache.org/v1alpha1 +kind: VirtualService +metadata: + name: demo-route +spec: + hosts: + - demo // 统一定义为应用名 + dubbo: + - service: + - exact: com.taobao.hsf.demoService:1.0.0 + - exact: com.taobao.hsf.demoService:2.0.0 + routedetail: + - name: sayHello-String-method-route + match: + - method: + name_match: + exact: "sayHello" + ..... + argp: + - string + route: + - destination: + host: demo + subset: v1 + fallback: + destination: + host: demo + subset: v2 + fallback: + destination: + host: demo + subset: v3 + + - name: sayHello-method-route + match: + - method: + name_match: + exact: "s-method" + route: + - destination: + host: demo + subset: v2 + fallback: + destination: + host: demo + subset: v3 + - name: some-method-route + match: + - method: + name_match: + exact: "some-method" + route: + - destination: + host: demo + subset: v4 + + - name: interface-route + route: + - destination: + host: demo + subset: v3 + + - service: + + .... +--- +apiVersion: service.dubbo.apache.org/v1alpha1 +kind: DestinationRule +metadata: + name: demo-route +spec: + host: demo + subsets: + - name: v1 + labels: + sigma.ali/mg: v1-host + + - name: v2 + labels: + sigma.ali/mg: v2-host + + - name: v3 + labels: + sigma.ali/mg: v3-host +``` + +从这个规则我们看出来匹配到 some-method 条件时对应的是 v4 subset,那么 v4 为空时,因为没有配置 fallback ,此时会直接报错 + +#### fallback 处理原则总结 + +- 我们应该在 VirtualService route 中配置好 Destination 的 fallback 处理逻辑 +- 在 fallback subset 时,如果对应的 subset 也配置有 fallback subset 时,也应递归处理;fallback subset 之间的关系也应该是从具体到广泛 +- 我们在编写匹配条件时,应该遵循从 具体条件到广泛条件 的原则 + +### RouteChain 的组装模式 (目前未实现) + +![route-rule3.png](/imgs/user/route-rule3.png) + + +我们看到上面的图,在路由的过程当中,我们是 Pipeline 的处理方式,Pipeline 的 Router 节点存在顺序,并且每个 Router 都有一个唯一对应的 VirtualService 和 **多个** 相应的 DestinationRule 进行描述。 + +以 Nacos 上存着的路由规则配置为例,配置的格式如下: + +```yaml +DataId: Demo.rule.yaml +GROUP: HSF + +content: + +VirtualService A +--- +DestinationRule A1 +--- +DestinationRule A2 +--- +VirtualService B +--- +DestinationRule B +--- +VirtualService C +--- +DestinationRule C +--- +... +``` + +`VirtualService A` 与 `DestinationRule A1` 、`DestinationRule A2` 组成一个 Router A,`VirtualService B` 与 `DestinationRule B` 组成 Router B,以此类推,完成整个 router 链的组装。 + +### 示例:按比例流量路由规则 + +> 注意,虽然接下来的规则和 Istio 的 VirtualService、DestinationRule 很像,但工作过程和具体规则和 Istio 还是有一些差异,Dubbo 只是参考了 Istio 的设计。如果您想接入原生的 Istio 服务网格治理体系,请参考下文 [接入服务网格流量治理](#接入服务网格流量治理)。 + +在一些场景下,我们需要将相同属性的流量按比例的分发到不同的实例分组。一个典型的示例场景是 A/B 测试,比如我们需要将 20% 流量转发到服务新版本 v2 的实例,以验证新版本的稳定性,或者是将公司内部的一部分用户导流到新版本 v2 的实例进行测试验证。另一个应用场景是实现服务的金丝雀发布,通过逐步调整流量分配比例值,使得新版本的流量逐步提升并最终将全部流量完全迁移到新版本之上。 + +#### 按比例流量规则示例 + +以下示例会将访问服务 `org.apache.dubbo.demo.DetailService` 特定方法 `getDetail` 的所有请求按比例进行转发。 + +```yaml +... +apiVersion: service.dubbo.apache.org/v1alpha1 +kind: VirtualService +metadata: + name: details +spec: + dubbo: + - name: detail-service-traffic-split + match: + - name: + services: + - exact: "org.apache.dubbo.demo.DetailService" + method: + name_match: + exact: "getDetail" + route: + - destination: + subset: details-v1 + weight: 60 + - destination: + subset: details-v2 + weight: 40 +--- +... +apiVersion: service.dubbo.apache.org/v1alpha1 +kind: DestinationRule +metadata: + name: reviews-route +spec: + subsets: + - name: details-v1 + labels: + detail_version: v1 # 'version' is a reserved key in Dubbo, so must not be used. + - name: details-v2 + labels: + detail_version: v2 # 'version' is a reserved key in Dubbo, so must not be used. +--- +``` + +##### Dubbo VirtualService + +> 此部分完全可参考 Istio VirtualService 语义,两者几乎完全相同,Dubbo 增加了 `dubbo` 协议标签(对应 http 协议位置)并对 `match` 条件进行了丰富。 + +`match` 条件设置了流量规则只对访问服务 "org.apache.dubbo.demo.DetailService" 的 `getDetail` 方法的请求有效。 + +```yaml +match: + - name: + services: + - exact: "org.apache.dubbo.demo.DetailService" + method: + name_match: + exact: "getDetail" +``` + +以下 `route` 指定匹配后流量的目标实例子集,实例子集 `details-v1` `details-v2` 是通过下面的 DestinationRule 定义的。对于没有匹配的流量,则默认可以访问任何实例,不会做任何过滤。 + +```yaml +route: + - destination: + subset: details-v1 + weight: 60 + - destination: + subset: details-v2 + weight: 40 +``` + +##### Dubbo DestinationRule + +> 此部分完全可参考 Istio DestinationRule 语义,两者完全相同。 + +以下规则通过匹配 `detail_version` 值将应用 details 划分为两个部署版本 `v1` 和 `v2`,分别命名为 `deatils-v1` 和 `details-v2`,同时 `deatils-v1` 和 `details-v2` 将成为 Dubbo VirtualService 的流量转发目标对象。 + +```yaml +subsets: + - name: details-v1 + labels: + detail_version: v1 # 'version' is a reserved key in Dubbo, so must not be used. + - name: details-v2 + labels: + detail_version: v2 # 'version' is a reserved key in Dubbo, so must not be used. +``` + +> 和标签路由类似,这里牵涉到如何给您的实例打标(这里是 `detail_version`)的问题,请参考下文的 [如何给实例打标](#如何给实例打标) 一节。 + +除了以上介绍的与 Istio 流量规则很相似的功能之外,Dubbo 的 VirtualService、DestinationRule 还可以实现方法参数路由等 Istio 规则不能做到的事情,具体查看 [参考手册]()。 + + diff --git a/content/zh-cn/overview/core-features/traffic/script-rule.md b/content/zh-cn/overview/what/core-features/traffic/script-rule.md similarity index 97% rename from content/zh-cn/overview/core-features/traffic/script-rule.md rename to content/zh-cn/overview/what/core-features/traffic/script-rule.md index 63c43b48ccf7..96cf57f40340 100644 --- a/content/zh-cn/overview/core-features/traffic/script-rule.md +++ b/content/zh-cn/overview/what/core-features/traffic/script-rule.md @@ -1,6 +1,7 @@ --- aliases: - /zh/overview/core-features/traffic/script-rule/ + - /zh-cn/overview/core-features/traffic/script-rule/ description: "" linkTitle: 脚本路由 title: 脚本路由规则 diff --git a/content/zh-cn/overview/core-features/traffic/tag-rule.md b/content/zh-cn/overview/what/core-features/traffic/tag-rule.md similarity index 98% rename from content/zh-cn/overview/core-features/traffic/tag-rule.md rename to content/zh-cn/overview/what/core-features/traffic/tag-rule.md index 8d36a5fbaf59..6e382f401106 100644 --- a/content/zh-cn/overview/core-features/traffic/tag-rule.md +++ b/content/zh-cn/overview/what/core-features/traffic/tag-rule.md @@ -1,6 +1,7 @@ --- aliases: - /zh/overview/core-features/traffic/tag-rule/ + - /zh-cn/overview/core-features/traffic/tag-rule/ description: "" linkTitle: 标签路由 title: 标签路由规则 diff --git a/data/announcements/zh/scheduled.yaml b/data/announcements/zh/scheduled.yaml index 845d11e3a517..3469c2bb6719 100644 --- a/data/announcements/zh/scheduled.yaml +++ b/data/announcements/zh/scheduled.yaml @@ -1,4 +1,15 @@ announcements: + - name: 3.2 Release + startTime: 2024-09-11T00:00:00 + endTime: 2024-12-31T18:00:00 + style: >- + background-image: linear-gradient(90deg, rgb(0, 150, 255) 0%, rgb(51, 190, 255) 100%); + title: | + announcement-apache-dubbo + Apache Dubbo 3.3 全新版本 正式上线! + message: | + 在 Apache Dubbo 突破 4w Star 之际,Apache Dubbo 团队正式宣布,Dubbo 3.3 正式发布!作为全球领先的开源微服务框架,Dubbo 一直致力于为开发者提供高性能、可扩展且灵活的分布式服务解决方案。此次发布的 Dubbo 3.3,通过 Triple X 的全新升级,突破了以往局限,实现了对南北向与东西向流量的全面支持,并提升了对云原生架构的友好性。

+ 欢迎扫描右侧二维码关注 Apache Dubbo 微信公众号! - name: Brandnew Website startTime: 2023-02-21T00:00:00 endTime: 2023-04-20T18:00:00 diff --git a/data/download/en/1javaReleases.yaml b/data/download/en/1javaReleases.yaml index 36cb4729cd68..24057b8939cc 100644 --- a/data/download/en/1javaReleases.yaml +++ b/data/download/en/1javaReleases.yaml @@ -3,20 +3,20 @@ type: java extra_message: extra_link: list: - - name: 3.3.0-beta.5 + - name: 3.3.0 description: > The latest feature version of Dubbo 3 includes JDK 21 Project Loom, the new Triple protocol, etc. - changelog: https://github.com/apache/dubbo/releases/tag/dubbo-3.3.0-beta.5 - archive: https://www.apache.org/dyn/closer.lua/dubbo/3.3.0-beta.5/apache-dubbo-3.3.0-beta.5-src.zip - hash: https://www.apache.org/dyn/closer.lua/dubbo/3.3.0-beta.5/apache-dubbo-3.3.0-beta.5-src.zip.sha512 - signature: https://www.apache.org/dyn/closer.lua/dubbo/3.3.0-beta.5/apache-dubbo-3.3.0-beta.5-src.zip.asc - - name: 3.2.15 + changelog: https://github.com/apache/dubbo/releases/tag/dubbo-3.3.0 + archive: https://www.apache.org/dyn/closer.lua/dubbo/3.3.0/apache-dubbo-3.3.0-src.zip + hash: https://www.apache.org/dyn/closer.lua/dubbo/3.3.0/apache-dubbo-3.3.0-src.zip.sha512 + signature: https://www.apache.org/dyn/closer.lua/dubbo/3.3.0/apache-dubbo-3.3.0-src.zip.asc + - name: 3.2.16 description: > Dubbo 3 is the latest stable version. It is recommended that all 3.x users upgrade to this version. - changelog: https://github.com/apache/dubbo/releases/tag/dubbo-3.2.15 - archive: https://www.apache.org/dyn/closer.lua/dubbo/3.2.15/apache-dubbo-3.2.15-src.zip - hash: https://www.apache.org/dyn/closer.lua/dubbo/3.2.15/apache-dubbo-3.2.15-src.zip.sha512 - signature: https://www.apache.org/dyn/closer.lua/dubbo/3.2.15/apache-dubbo-3.2.15-src.zip.asc + changelog: https://github.com/apache/dubbo/releases/tag/dubbo-3.2.16 + archive: https://www.apache.org/dyn/closer.lua/dubbo/3.2.16/apache-dubbo-3.2.16-src.zip + hash: https://www.apache.org/dyn/closer.lua/dubbo/3.2.16/apache-dubbo-3.2.16-src.zip.sha512 + signature: https://www.apache.org/dyn/closer.lua/dubbo/3.2.16/apache-dubbo-3.2.16-src.zip.asc - name: 3.1.11 description: > Dubbo 3.1.x is currently only undergoing security maintenance. It is recommended that all 3.x users upgrade to version 3.2.x. diff --git a/data/download/zh/1javaReleases.yaml b/data/download/zh/1javaReleases.yaml index b0921d1161fc..3b4929a0cb9c 100644 --- a/data/download/zh/1javaReleases.yaml +++ b/data/download/zh/1javaReleases.yaml @@ -3,20 +3,20 @@ type: java extra_message: extra_link: list: - - name: 3.3.0-beta.5 + - name: 3.3.0 description: > Dubbo 3 最新特性版本,包含了如 JDK 21 Project Loom、全新 Triple 协议等。 - changelog: https://github.com/apache/dubbo/releases/tag/dubbo-3.3.0-beta.5 - archive: https://www.apache.org/dyn/closer.lua/dubbo/3.3.0-beta.5/apache-dubbo-3.3.0-beta.5-src.zip - hash: https://www.apache.org/dyn/closer.lua/dubbo/3.3.0-beta.5/apache-dubbo-3.3.0-beta.5-src.zip.sha512 - signature: https://www.apache.org/dyn/closer.lua/dubbo/3.3.0-beta.5/apache-dubbo-3.3.0-beta.5-src.zip.asc - - name: 3.2.15 + changelog: https://github.com/apache/dubbo/releases/tag/dubbo-3.3.0 + archive: https://www.apache.org/dyn/closer.lua/dubbo/3.3.0/apache-dubbo-3.3.0-src.zip + hash: https://www.apache.org/dyn/closer.lua/dubbo/3.3.0/apache-dubbo-3.3.0-src.zip.sha512 + signature: https://www.apache.org/dyn/closer.lua/dubbo/3.3.0/apache-dubbo-3.3.0-src.zip.asc + - name: 3.2.16 description: > Dubbo 3 最新稳定版本,建议所有的 3.x 用户都升级到该版本。 - changelog: https://github.com/apache/dubbo/releases/tag/dubbo-3.2.15 - archive: https://www.apache.org/dyn/closer.lua/dubbo/3.2.15/apache-dubbo-3.2.15-src.zip - hash: https://www.apache.org/dyn/closer.lua/dubbo/3.2.15/apache-dubbo-3.2.15-src.zip.sha512 - signature: https://www.apache.org/dyn/closer.lua/dubbo/3.2.15/apache-dubbo-3.2.15-src.zip.asc + changelog: https://github.com/apache/dubbo/releases/tag/dubbo-3.2.16 + archive: https://www.apache.org/dyn/closer.lua/dubbo/3.2.16/apache-dubbo-3.2.16-src.zip + hash: https://www.apache.org/dyn/closer.lua/dubbo/3.2.16/apache-dubbo-3.2.16-src.zip.sha512 + signature: https://www.apache.org/dyn/closer.lua/dubbo/3.2.16/apache-dubbo-3.2.16-src.zip.asc - name: 3.1.11 description: > Dubbo 3.1.x 目前仅进行安全维护,建议所有的 3.x 用户都升级到 3.2.x 版本。 diff --git a/go.mod b/go.mod index 71595e81a7d6..af4add7e3309 100644 --- a/go.mod +++ b/go.mod @@ -2,4 +2,7 @@ module github.com/apache/dubbo-website go 1.18 -require github.com/google/docsy v0.6.0 // indirect +require ( + github.com/google/docsy v0.10.0 // indirect + github.com/google/docsy/dependencies v0.7.2 // indirect +) diff --git a/go.sum b/go.sum index 785c595dcaaf..93dc7afc38e2 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,8 @@ -github.com/FortAwesome/Font-Awesome v0.0.0-20220831210243-d3a7818c253f/go.mod h1:IUgezN/MFpCDIlFezw3L8j83oeiIuYoj28Miwr/KUYo= -github.com/google/docsy v0.6.0 h1:43bVF18t2JihAamelQjjGzx1vO2ljCilVrBgetCA8oI= -github.com/google/docsy v0.6.0/go.mod h1:VKKLqD8PQ7AglJc98yBorATfW7GrNVsn0kGXVYF6G+M= -github.com/google/docsy/dependencies v0.6.0/go.mod h1:EDGc2znMbGUw0RW5kWwy2oGgLt0iVXBmoq4UOqstuNE= -github.com/twbs/bootstrap v4.6.2+incompatible/go.mod h1:fZTSrkpSf0/HkL0IIJzvVspTt1r9zuf7XlZau8kpcY0= +github.com/FortAwesome/Font-Awesome v0.0.0-20230327165841-0698449d50f2/go.mod h1:IUgezN/MFpCDIlFezw3L8j83oeiIuYoj28Miwr/KUYo= +github.com/FortAwesome/Font-Awesome v0.0.0-20240402185447-c0f460dca7f7/go.mod h1:IUgezN/MFpCDIlFezw3L8j83oeiIuYoj28Miwr/KUYo= +github.com/google/docsy v0.10.0 h1:6tMDacPwAyRWNCfvsn/9qGOZDQ8b0aRzjRZvnZPY5dg= +github.com/google/docsy v0.10.0/go.mod h1:c0nIAqmRTOuJ01F85U/wJPQtc3Zj9N58Kea9bOT2AJc= +github.com/google/docsy/dependencies v0.7.2 h1:+t5ufoADQAj4XneFphz4A+UU0ICAxmNaRHVWtMYXPSI= +github.com/google/docsy/dependencies v0.7.2/go.mod h1:gihhs5gmgeO+wuoay4FwOzob+jYJVyQbNaQOh788lD4= +github.com/twbs/bootstrap v5.2.3+incompatible/go.mod h1:fZTSrkpSf0/HkL0IIJzvVspTt1r9zuf7XlZau8kpcY0= +github.com/twbs/bootstrap v5.3.3+incompatible/go.mod h1:fZTSrkpSf0/HkL0IIJzvVspTt1r9zuf7XlZau8kpcY0= diff --git a/i18n/en.toml b/i18n/en.toml index 666b6f2eec3a..b7ce7b808864 100755 --- a/i18n/en.toml +++ b/i18n/en.toml @@ -246,17 +246,67 @@ other = "Warning:" other = "What's next" [homepage_slogan] -other = "Building Enterprise Microservices with Dubbo!" +other = "A Cloud-Native Microservice Framework" [homepage_description_paragraph1] -other = "Apache Dubbo is an easy-to-use, high-performance WEB and RPC framework with builtin service discovery, traffic management, observability, security features, tools and best practices for building enterprise-level microservices." +other = "Build apps with built-in rpc, traffic management, security, observability support that can deploy on kubernetes and vm." [homepage_description_paragraph2] other = "\"Dubbo was invented in Alibaba and has been successfully supporting billions of services for years!\"" [homepage_button_1] -other = "Learn More" +other = "Get A Demo" [homepage_button_2] other = "Quick Start" +[homepage_language_tip] +other = "Choose your favourite language and dive in" + +[footer_left_title] +other = "Follow us" + +[footer_left_notice] +other = "Subscribe to one or more of the following channels to receive project updates, keep connection with community developers." + +[footer_left_wechat] +other = "WECHAT CHANNEL" + +[footer_left_ding] +other = "DINGTALK CHANNEL" + +[footer_bottom_tip] +other = "All Rights Reserved" + +[footer_right_title1] +other = "DOCUMENTATION" + + + +[footer_right_overview] +other = "Overview" + +[footer_right_link_overview] +other = "/en/overview/" + +[footer_right_quickstart] +other = "Quick Start" + +[footer_right_link_quickstart] +other = "/en/overview/quickstart/" + +[footer_right_developer] +other = "Developer guide" + +[footer_right_link_developer] +other = "/zh-cn/contact/contributor/software-donation-guide_dev/" + +[footer_right_title2] +other = "RESOURCES" + +[footer_right_community] +other = "Community" + +[footer_right_link_community] +other = "/zh-cn/contact/" + diff --git a/i18n/zh-cn.toml b/i18n/zh-cn.toml index 0c00ce81fb8c..ccba2f83bc21 100755 --- a/i18n/zh-cn.toml +++ b/i18n/zh-cn.toml @@ -258,18 +258,64 @@ other = "警告:" other = "接下来" [homepage_slogan] -other = "为构建企业级微服务提供框架、通信、服务治理能力" +other = "一款云原生微服务开发框架" [homepage_description_paragraph1] -other = "Apache Dubbo 是一款易用、高性能的 WEB 和 RPC 框架,同时为构建企业级微服务提供服务发现、流量治理、可观测、认证鉴权等能力、工具与最佳实践。" +other = "构建具备内置 RPC、流量管控、安全、可观测能力的应用,支持Kubernetes和VM部署环境。" [homepage_description_paragraph2] other = "\"Dubbo3 已在阿里巴巴内部微服务集群全面落地,用于升级运行多年的 HSF2 框架。\"" [homepage_button_1] -other = "什么是 Dubbo" +other = "商城 Demo" [homepage_button_2] other = "快速开始" +[homepage_language_tip] +other = "选择您喜欢的语言并快速体验" +[footer_left_title] +other = "关注我们" + +[footer_left_notice] +other = "请通过以下任一或多个渠道关注社区动态,与社区开发者保持密切沟通。" + +[footer_left_wechat] +other = "微信" + +[footer_left_ding] +other = "钉钉" + +[footer_bottom_tip] +other = "保留所有权利" + +[footer_right_title1] +other = "文档" + +[footer_right_overview] +other = "概览" + +[footer_right_link_overview] +other = "/zh-cn/overview/home/" + +[footer_right_quickstart] +other = "快速开始" + +[footer_right_link_quickstart] +other = "/zh-cn/overview/quickstart/" + +[footer_right_developer] +other = "开发者指南" + +[footer_right_link_developer] +other = "/zh-cn/contact/contributor/software-donation-guide_dev/" + +[footer_right_title2] +other = "资源" + +[footer_right_community] +other = "社区" + +[footer_right_link_community] +other = "/zh-cn/contact/" \ No newline at end of file diff --git a/layouts/_default/baseof.html b/layouts/_default/baseof.html index 089ddf3cafa0..08cf4201f9eb 100644 --- a/layouts/_default/baseof.html +++ b/layouts/_default/baseof.html @@ -3,7 +3,7 @@ {{- if eq hugo.Environment "preview" -}} {{- end -}} - + {{ partial "head.html" . }} diff --git a/layouts/partials/footer.html b/layouts/partials/footer.html index 7183bee24bc5..12b86bcd9799 100755 --- a/layouts/partials/footer.html +++ b/layouts/partials/footer.html @@ -1,60 +1,201 @@ -{{ $links := .Site.Params.links }} -
-
-
-
- {{ with $links }} - {{ with index . "user"}} - {{ template "footer-links-block" . }} - {{ end }} - {{ end }} + -
+ + + + + \ No newline at end of file diff --git a/layouts/partials/navbar-collapse-commuity.html b/layouts/partials/navbar-collapse-commuity.html new file mode 100644 index 000000000000..4656940cd853 --- /dev/null +++ b/layouts/partials/navbar-collapse-commuity.html @@ -0,0 +1,16 @@ + +
+
+ {{ range .Site.Params.COMMUNITY.navOptions.items }} + {{ .name }} + {{ end }} +
+
\ No newline at end of file diff --git a/layouts/partials/navbar-collapse-ecosystem.html b/layouts/partials/navbar-collapse-ecosystem.html new file mode 100644 index 000000000000..fcc891fa95c0 --- /dev/null +++ b/layouts/partials/navbar-collapse-ecosystem.html @@ -0,0 +1,17 @@ + + +
+
+ {{ range .Site.Params.Ecosystem.navOptions.items }} + {{ .name }} + {{ end }} +
+
\ No newline at end of file diff --git a/layouts/partials/navbar-community-selector.html b/layouts/partials/navbar-community-selector.html new file mode 100755 index 000000000000..8a9ad579d7af --- /dev/null +++ b/layouts/partials/navbar-community-selector.html @@ -0,0 +1,9 @@ + + \ No newline at end of file diff --git a/layouts/partials/navbar-ecosystem-selector.html b/layouts/partials/navbar-ecosystem-selector.html new file mode 100755 index 000000000000..c7988b42c18a --- /dev/null +++ b/layouts/partials/navbar-ecosystem-selector.html @@ -0,0 +1,9 @@ + + \ No newline at end of file diff --git a/layouts/partials/navbar-lang-selector.html b/layouts/partials/navbar-lang-selector.html index 6f8bfc42f461..f36f348ffba9 100755 --- a/layouts/partials/navbar-lang-selector.html +++ b/layouts/partials/navbar-lang-selector.html @@ -1,10 +1,51 @@ {{/* Link directly to documentation etc., if possible. */}} +{{ $languages := (dict "中文" "/zh-cn/" "EN" "/en/") }} {{ $langPage := cond (gt (len .Translations) 0) . .Site.Home }} - -