Compare commits
109 Commits
3.2
...
dubbo-3.3.
| Author | SHA1 | Date |
|---|---|---|
|
|
0c9d5e2f73 | |
|
|
bcd5caf7df | |
|
|
0b2b9f735a | |
|
|
a0e7ebc735 | |
|
|
7246fad6b5 | |
|
|
c96a8f3719 | |
|
|
660d5a2ecd | |
|
|
4f32e0aba3 | |
|
|
fb0911de97 | |
|
|
0fd51b1ca0 | |
|
|
54da4da033 | |
|
|
cff9bfd1d2 | |
|
|
9eb49e24c3 | |
|
|
0f61286a78 | |
|
|
abb2d3834d | |
|
|
4b5c186076 | |
|
|
3ed2dacbef | |
|
|
99ba6e3037 | |
|
|
8009c72030 | |
|
|
dad3b070cd | |
|
|
fd04ef711b | |
|
|
d596eeb151 | |
|
|
fe2af7e354 | |
|
|
cfd0be3a3a | |
|
|
7e6a32ba68 | |
|
|
059b75c533 | |
|
|
36a80e4db7 | |
|
|
bf3d4f4ca3 | |
|
|
8e55dae8f9 | |
|
|
f91246ab09 | |
|
|
186ec674bf | |
|
|
98d6a853a9 | |
|
|
679ce4496c | |
|
|
4e9a0a41fc | |
|
|
7a4ec6c525 | |
|
|
ae150c01e5 | |
|
|
56de12127b | |
|
|
629bee3987 | |
|
|
5ae875d951 | |
|
|
04f3fe7d2b | |
|
|
8bfdf1e38c | |
|
|
059fdf2613 | |
|
|
7c971ca1bd | |
|
|
b18eeb7077 | |
|
|
6c5a876f31 | |
|
|
ce65317207 | |
|
|
046898bbc8 | |
|
|
29d9c070d4 | |
|
|
8fefd95a98 | |
|
|
2973426b2a | |
|
|
70605f4dd0 | |
|
|
d1719c5358 | |
|
|
0e17f4f168 | |
|
|
72e5d20ce9 | |
|
|
0db8605974 | |
|
|
80d496c5b1 | |
|
|
093fb7c208 | |
|
|
f78b4f5dea | |
|
|
1f8a0fa5ec | |
|
|
f2ec217f54 | |
|
|
c7d411c3cb | |
|
|
8bb17b85f2 | |
|
|
4b62513dff | |
|
|
9bbf7625a8 | |
|
|
0d4e8304bc | |
|
|
33a8063309 | |
|
|
d4c2852caf | |
|
|
48cc5b24de | |
|
|
37f150263a | |
|
|
95207b9079 | |
|
|
da8d0cd994 | |
|
|
27e6838c3b | |
|
|
1c65617fb1 | |
|
|
cf2a63580e | |
|
|
d6776e4008 | |
|
|
b14201f393 | |
|
|
c96a06eba1 | |
|
|
1e59ab524a | |
|
|
fd14e7b76f | |
|
|
642f741dba | |
|
|
85bc6ea472 | |
|
|
391d3cdb35 | |
|
|
2031a4c531 | |
|
|
e642e72ce8 | |
|
|
4604b8074a | |
|
|
30daba2d74 | |
|
|
1f39543632 | |
|
|
71046bdd6f | |
|
|
ae4899a462 | |
|
|
7661cab6f5 | |
|
|
d798e7c3be | |
|
|
34eb252178 | |
|
|
59758f4b58 | |
|
|
52e4e4e301 | |
|
|
71cc51bf69 | |
|
|
a80ad7f505 | |
|
|
9f0e1589a5 | |
|
|
471f44b52d | |
|
|
992abd2d34 | |
|
|
9d9df82194 | |
|
|
6c8f79c889 | |
|
|
2997fa6a2e | |
|
|
13558a8e6a | |
|
|
59832d45d4 | |
|
|
fe55491d4a | |
|
|
b23bae38cc | |
|
|
0b6f2e4a8d | |
|
|
414785c05b | |
|
|
52611099ab |
43
.artifacts
43
.artifacts
|
|
@ -19,8 +19,8 @@
|
|||
dubbo
|
||||
dubbo-auth
|
||||
dubbo-apache-release
|
||||
dubbo-all-shaded
|
||||
dubbo-bom
|
||||
dubbo-build-tools
|
||||
dubbo-cluster
|
||||
dubbo-common
|
||||
dubbo-compatible
|
||||
|
|
@ -28,7 +28,9 @@ dubbo-compiler
|
|||
dubbo-config
|
||||
dubbo-config-api
|
||||
dubbo-config-spring
|
||||
dubbo-config-spring6
|
||||
dubbo-configcenter
|
||||
dubbo-configcenter-file
|
||||
dubbo-configcenter-apollo
|
||||
dubbo-configcenter-nacos
|
||||
dubbo-configcenter-zookeeper
|
||||
|
|
@ -49,6 +51,7 @@ dubbo-kubernetes
|
|||
dubbo-maven-plugin
|
||||
dubbo-metadata
|
||||
dubbo-metadata-api
|
||||
dubbo-metadata-rest
|
||||
dubbo-metadata-definition-protobuf
|
||||
dubbo-metadata-processor
|
||||
dubbo-metadata-report-nacos
|
||||
|
|
@ -61,11 +64,13 @@ dubbo-metrics-metadata
|
|||
dubbo-metrics-prometheus
|
||||
dubbo-metrics-registry
|
||||
dubbo-metrics-config-center
|
||||
dubbo-metrics-netty
|
||||
dubbo-metrics-event
|
||||
dubbo-monitor
|
||||
dubbo-monitor-api
|
||||
dubbo-monitor-common
|
||||
dubbo-monitor-default
|
||||
dubbo-native
|
||||
dubbo-native-plugin
|
||||
dubbo-parent
|
||||
dubbo-plugin
|
||||
dubbo-qos
|
||||
|
|
@ -80,8 +85,10 @@ dubbo-registry-zookeeper
|
|||
dubbo-remoting
|
||||
dubbo-remoting-api
|
||||
dubbo-remoting-http
|
||||
dubbo-remoting-http12
|
||||
dubbo-remoting-netty
|
||||
dubbo-remoting-netty4
|
||||
dubbo-remoting-zookeeper-api
|
||||
dubbo-remoting-zookeeper
|
||||
dubbo-remoting-zookeeper-curator5
|
||||
dubbo-rpc
|
||||
|
|
@ -102,16 +109,36 @@ dubbo-spring-boot-actuator-compatible
|
|||
dubbo-spring-boot-autoconfigure
|
||||
dubbo-spring-boot-autoconfigure-compatible
|
||||
dubbo-spring-boot-compatible
|
||||
dubbo-spring-boot-observability-starters
|
||||
dubbo-spring-boot-observability-autoconfigure
|
||||
dubbo-spring-boot-tracing-brave-zipkin-starter
|
||||
dubbo-spring-boot-tracing-otel-zipkin-starter
|
||||
dubbo-spring-boot-tracing-otel-otlp-starter
|
||||
dubbo-spring-boot-observability-starter
|
||||
dubbo-observability-spring-boot-starters
|
||||
dubbo-observability-spring-boot-autoconfigure
|
||||
dubbo-tracing-brave-zipkin-spring-boot-starter
|
||||
dubbo-tracing-otel-zipkin-spring-boot-starter
|
||||
dubbo-tracing-otel-otlp-spring-boot-starter
|
||||
dubbo-observability-spring-boot-starter
|
||||
dubbo-spring-boot-starter
|
||||
dubbo-spring-boot-starters
|
||||
dubbo-spring-boot-interceptor
|
||||
dubbo-nacos-spring-boot-starter
|
||||
dubbo-zookeeper-spring-boot-starter
|
||||
dubbo-zookeeper-curator5-spring-boot-starter
|
||||
dubbo-sentinel-spring-boot-starter
|
||||
dubbo-seata-spring-boot-starter
|
||||
dubbo-spring-security
|
||||
dubbo-tracing
|
||||
dubbo-xds
|
||||
dubbo-plugin-cluster-mergeable
|
||||
dubbo-plugin-mock
|
||||
dubbo-plugin-router-script
|
||||
dubbo-plugin-router-mesh
|
||||
dubbo-plugin-router-condition
|
||||
dubbo-plugin-router-tag
|
||||
dubbo-plugin-loadbalance-adaptive
|
||||
dubbo-plugin-access-log
|
||||
dubbo-plugin-tps
|
||||
dubbo-plugin-token
|
||||
dubbo-plugin-generic-invoke
|
||||
dubbo-plugin-context
|
||||
dubbo-plugin-classloader-filter
|
||||
dubbo-plugin-proxy-bytebuddy
|
||||
dubbo-plugin-qos-trace
|
||||
dubbo-plugin-loom
|
||||
|
|
|
|||
|
|
@ -19,55 +19,13 @@
|
|||
# top-most EditorConfig file
|
||||
root = true
|
||||
|
||||
# Unix-style newlines with a newline ending every file
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_size = 4
|
||||
indent_style = space
|
||||
tab_width = 4
|
||||
max_line_length = 120
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.java]
|
||||
ij_java_continuation_indent_size = 8
|
||||
ij_java_keep_control_statement_in_one_line = false
|
||||
ij_java_for_brace_force = always
|
||||
ij_java_if_brace_force = always
|
||||
ij_java_keep_first_column_comment = false
|
||||
ij_java_keep_line_breaks = false
|
||||
ij_java_keep_simple_blocks_in_one_line = true
|
||||
ij_java_keep_simple_classes_in_one_line = true
|
||||
ij_java_keep_simple_lambdas_in_one_line = true
|
||||
ij_java_keep_simple_methods_in_one_line = true
|
||||
ij_java_keep_blank_lines_in_code = 1
|
||||
ij_java_keep_blank_lines_in_declarations = 1
|
||||
ij_java_class_count_to_use_import_on_demand = 999
|
||||
ij_java_names_count_to_use_import_on_demand = 999
|
||||
ij_java_imports_layout = org.apache.dubbo.**, |, javax.**, |, java.**, |, *, |, $*
|
||||
ij_java_insert_inner_class_imports = true
|
||||
ij_java_space_before_array_initializer_left_brace = true
|
||||
ij_java_method_parameters_new_line_after_left_paren = true
|
||||
ij_java_wrap_comments = true
|
||||
ij_java_wrap_long_lines = true
|
||||
ij_java_enum_constants_wrap = split_into_lines
|
||||
ij_java_method_call_chain_wrap = split_into_lines
|
||||
ij_java_method_parameters_wrap = on_every_item
|
||||
ij_java_extends_list_wrap = on_every_item
|
||||
ij_java_extends_keyword_wrap = normal
|
||||
ij_java_binary_operation_wrap = normal
|
||||
ij_java_binary_operation_sign_on_next_line = true
|
||||
|
||||
[*.json]
|
||||
tab_width = 2
|
||||
|
||||
[*.{yml,yaml}]
|
||||
indent_size = 2
|
||||
|
||||
[*.xml]
|
||||
ij_xml_attribute_wrap = off
|
||||
ij_xml_text_wrap = off
|
||||
ij_xml_keep_blank_lines = 1
|
||||
|
||||
[pom.xml]
|
||||
indent_size = 2
|
||||
# 4 space indentation
|
||||
[*.{java,xml}]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
|
|
|||
|
|
@ -1,88 +0,0 @@
|
|||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
title: "[General][Java SDK (Component)] xxx"
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
<img src="https://dubbo.apache.org/imgs/nav_logo2.png" alt="Dubbo logo" height="90px" align="right" />
|
||||
|
||||
Thank you for finding the time to share your idea! We really appreciate the community efforts to improve Dubbo.
|
||||
|
||||
If you need to report a security issue, please visit [our security policy](https://github.com/apache/dubbo/security/policy).
|
||||
|
||||
**Dubbo is open for world wide collaboration, please make sure that all the content you provide is in English.**
|
||||
Remember that non-English idea is quite not friendly for everyone, and might unable to get the response!
|
||||
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Pre-check
|
||||
options:
|
||||
- label: >
|
||||
I am sure that all the content I provide is in English.
|
||||
required: true
|
||||
|
||||
- type: dropdown
|
||||
attributes:
|
||||
label: Apache Dubbo Component
|
||||
description: |
|
||||
What Apache Dubbo component are you using? Apache Dubbo has many subprojects, please make sure
|
||||
to choose the component that you want to ask questions about.
|
||||
multiple: false
|
||||
options:
|
||||
- "Java SDK (apache/dubbo)"
|
||||
- "Java Samples (apache/dubbo-samples)"
|
||||
- "Java Integration Cases (apache/dubbo-integration-cases)"
|
||||
- "Java SPI Extensions (apache/dubbo-spi-extensions)"
|
||||
- "Java Benchmark (apache/dubbo-benchmark)"
|
||||
- "Go SDK (apache/dubbo-go)"
|
||||
- "Go Samples (apache/dubbo-go-samples)"
|
||||
- "Rust SDK (apache/dubbo-rust)"
|
||||
- "Node.js SDK (apache/dubbo-js)"
|
||||
- "Python SDK (apache/dubbo-python)"
|
||||
- "Kubernetes Integration (apache/dubbo-kubernetes)"
|
||||
- "Pixiu Gateway (apache/dubbo-go-pixiu)"
|
||||
- "Pixiu Gateway Samples (apache/dubbo-go-pixiu-samples)"
|
||||
- "Admin (apache/dubbo-admin)"
|
||||
- "Website (apache/dubbo-website)"
|
||||
- "Awesome (apache/dubbo-awesome)"
|
||||
- "Initializer (apache/dubbo-intializer)"
|
||||
- "Others (apache/dubbo-xxx)"
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Details
|
||||
description: Anything you want to ask?
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Code of Conduct
|
||||
description: The Code of Conduct helps create a safe space for everyone. We require that everyone agrees to it.
|
||||
options:
|
||||
- label: >
|
||||
I agree to follow this project's
|
||||
[Code of Conduct](https://www.apache.org/foundation/policies/conduct)
|
||||
required: true
|
||||
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: "Thanks for completing our form!"
|
||||
|
|
@ -1,88 +0,0 @@
|
|||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
title: "[Q/A][Java SDK (Component)] xxx"
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
<img src="https://dubbo.apache.org/imgs/nav_logo2.png" alt="Dubbo logo" height="90px" align="right" />
|
||||
|
||||
Thank you for finding the time to report the question! We really appreciate the community efforts to improve Dubbo.
|
||||
|
||||
If you need to report a security issue, please visit [our security policy](https://github.com/apache/dubbo/security/policy).
|
||||
|
||||
**Dubbo is open for world wide collaboration, please make sure that all the content you provide is in English.**
|
||||
Remember that non-English question is quite not friendly for everyone, and might unable to get the response!
|
||||
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Pre-check
|
||||
options:
|
||||
- label: >
|
||||
I am sure that all the content I provide is in English.
|
||||
required: true
|
||||
|
||||
- type: dropdown
|
||||
attributes:
|
||||
label: Apache Dubbo Component
|
||||
description: |
|
||||
What Apache Dubbo component are you using? Apache Dubbo has many subprojects, please make sure
|
||||
to choose the component that you want to ask questions about.
|
||||
multiple: false
|
||||
options:
|
||||
- "Java SDK (apache/dubbo)"
|
||||
- "Java Samples (apache/dubbo-samples)"
|
||||
- "Java Integration Cases (apache/dubbo-integration-cases)"
|
||||
- "Java SPI Extensions (apache/dubbo-spi-extensions)"
|
||||
- "Java Benchmark (apache/dubbo-benchmark)"
|
||||
- "Go SDK (apache/dubbo-go)"
|
||||
- "Go Samples (apache/dubbo-go-samples)"
|
||||
- "Rust SDK (apache/dubbo-rust)"
|
||||
- "Node.js SDK (apache/dubbo-js)"
|
||||
- "Python SDK (apache/dubbo-python)"
|
||||
- "Kubernetes Integration (apache/dubbo-kubernetes)"
|
||||
- "Pixiu Gateway (apache/dubbo-go-pixiu)"
|
||||
- "Pixiu Gateway Samples (apache/dubbo-go-pixiu-samples)"
|
||||
- "Admin (apache/dubbo-admin)"
|
||||
- "Website (apache/dubbo-website)"
|
||||
- "Awesome (apache/dubbo-awesome)"
|
||||
- "Initializer (apache/dubbo-intializer)"
|
||||
- "Others (apache/dubbo-xxx)"
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Details
|
||||
description: Anything you want to know?
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Code of Conduct
|
||||
description: The Code of Conduct helps create a safe space for everyone. We require that everyone agrees to it.
|
||||
options:
|
||||
- label: >
|
||||
I agree to follow this project's
|
||||
[Code of Conduct](https://www.apache.org/foundation/policies/conduct)
|
||||
required: true
|
||||
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: "Thanks for completing our form!"
|
||||
|
|
@ -1,142 +0,0 @@
|
|||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
name: Bug Report
|
||||
description: File a bug report
|
||||
title: "[Bug] "
|
||||
labels: ["type/need-triage", "component/need-triage"]
|
||||
projects: ["apache/337"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
<img src="https://dubbo.apache.org/imgs/nav_logo2.png" alt="Dubbo logo" height="90px" align="right" />
|
||||
|
||||
Thank you for finding the time to report the problem! We really appreciate the community efforts to improve Dubbo.
|
||||
|
||||
Please make sure what you are reporting is indeed a bug with reproducible steps, if you want to ask questions
|
||||
or share ideas, please [subscribe to our mailing list](mailto:dev-subscribe@dubbo.apache.org) and sent
|
||||
emails to [our mailing list](mailto:dev@dubbo.apache.org), you can also head to our
|
||||
[Discussion](https://github.com/apache/dubbo/discussions) tab.
|
||||
|
||||
If you need to report a security issue, please visit [our security policy](https://github.com/apache/dubbo/security/policy).
|
||||
|
||||
**Dubbo is open for world wide collaboration, please make sure that all the content you provide is in English.**
|
||||
Remember that non-English issues is quite not friendly for everyone, and might unable to get the response!
|
||||
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Pre-check
|
||||
options:
|
||||
- label: >
|
||||
I am sure that all the content I provide is in English.
|
||||
required: true
|
||||
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Search before asking
|
||||
description: >
|
||||
Please make sure to search in the [issues](https://github.com/apache/dubbo/issues?q=is%3Aissue) first to see
|
||||
whether the same issue was reported already.
|
||||
options:
|
||||
- label: >
|
||||
I had searched in the [issues](https://github.com/apache/dubbo/issues?q=is%3Aissue) and found no similar
|
||||
issues.
|
||||
required: true
|
||||
|
||||
- type: dropdown
|
||||
attributes:
|
||||
label: Apache Dubbo Component
|
||||
description: |
|
||||
What Apache Dubbo component are you using? Apache Dubbo has many subprojects, please make sure
|
||||
to choose the component that you want to ask questions about.
|
||||
multiple: false
|
||||
options:
|
||||
- "Java SDK (apache/dubbo)"
|
||||
- "Java Samples (apache/dubbo-samples)"
|
||||
- "Java Integration Cases (apache/dubbo-integration-cases)"
|
||||
- "Java SPI Extensions (apache/dubbo-spi-extensions)"
|
||||
- "Java Benchmark (apache/dubbo-benchmark)"
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Dubbo Version
|
||||
description: "Which Dubbo version, JDK version and operating system did you use?"
|
||||
placeholder: "Example: Dubbo Java 3.2.12, OpenJDK 1.8, Ubuntu 20.04"
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Steps to reproduce this issue
|
||||
description: >
|
||||
Describe how to reproduce this issue.If you are not able to provide a reproducible case,
|
||||
please open a [Discussion](https://github.com/apache/dubbo/discussions) instead.
|
||||
placeholder: >
|
||||
Please provide the context in which the problem occurred and explain what happened.
|
||||
A [GitHub address] would be helpful for maintainers to reproduce the problem.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: What you expected to happen
|
||||
description: What do you think went wrong?
|
||||
placeholder: >
|
||||
Please explain why you think the behaviour is erroneous. It is extremely helpful if you copy and paste
|
||||
the fragment of logs showing the exact error messages or wrong behaviour and screenshots for
|
||||
UI problems. You can include files by dragging and dropping them here.
|
||||
|
||||
**NOTE**: please copy and paste texts instead of taking screenshots of them for easy future search.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Anything else
|
||||
description: Anything else we need to know?
|
||||
placeholder: >
|
||||
How often does this problem occur? (Once? Every time? Only when certain conditions are met?)
|
||||
Any relevant logs to include? Put them here inside fenced
|
||||
``` ``` blocks or inside a collapsable details tag if it's too long:
|
||||
<details><summary>x.log</summary> lots of stuff </details>
|
||||
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Are you willing to submit a pull request to fix on your own?
|
||||
description: >
|
||||
This is absolutely not required, but we are happy to guide you in the contribution process
|
||||
especially if you already have a good understanding of how to implement the fix.
|
||||
Dubbo is a totally community-driven project and we love to bring new contributors in.
|
||||
options:
|
||||
- label: Yes I am willing to submit a pull request on my own!
|
||||
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Code of Conduct
|
||||
description: The Code of Conduct helps create a safe space for everyone. We require that everyone agrees to it.
|
||||
options:
|
||||
- label: >
|
||||
I agree to follow this project's
|
||||
[Code of Conduct](https://www.apache.org/foundation/policies/conduct)
|
||||
required: true
|
||||
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: "Thanks for completing our form!"
|
||||
|
|
@ -1,106 +0,0 @@
|
|||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
name: Feature Request
|
||||
description: Create a Feature Request for Dubbo
|
||||
title: "[Feature] "
|
||||
labels: ["type/need-triage", "component/need-triage"]
|
||||
projects: ["apache/337"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
<img src="https://dubbo.apache.org/imgs/nav_logo2.png" alt="Dubbo logo" height="90px" align="right" />
|
||||
|
||||
Thank you for finding the time to propose new feature!
|
||||
|
||||
We really appreciate the community efforts to improve Dubbo.
|
||||
|
||||
**Dubbo is open for world wide collaboration, please make sure that all the content you provide is in English.**
|
||||
Remember that non-English issues is quite not friendly for everyone, and might unable to get the response!
|
||||
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Pre-check
|
||||
options:
|
||||
- label: >
|
||||
I am sure that all the content I provide is in English.
|
||||
required: true
|
||||
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Search before asking
|
||||
description: >
|
||||
Please make sure to search in the [issues](https://github.com/apache/dubbo/issues?q=is%3Aissue) first to see
|
||||
whether the same feature was requested already.
|
||||
options:
|
||||
- label: >
|
||||
I had searched in the [issues](https://github.com/apache/dubbo/issues?q=is%3Aissue) and found no similar
|
||||
feature requirement.
|
||||
required: true
|
||||
|
||||
- type: dropdown
|
||||
attributes:
|
||||
label: Apache Dubbo Component
|
||||
description: |
|
||||
What Apache Dubbo component are you using? Apache Dubbo has many subprojects, please make sure
|
||||
to choose the component that you want to ask questions about.
|
||||
multiple: false
|
||||
options:
|
||||
- "Java SDK (apache/dubbo)"
|
||||
- "Java Samples (apache/dubbo-samples)"
|
||||
- "Java Integration Cases (apache/dubbo-integration-cases)"
|
||||
- "Java SPI Extensions (apache/dubbo-spi-extensions)"
|
||||
- "Java Benchmark (apache/dubbo-benchmark)"
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Descriptions
|
||||
description: A short description of your feature
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Related issues
|
||||
description: Is there currently another issue associated with this?
|
||||
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Are you willing to submit a pull request to fix on your own?
|
||||
description: >
|
||||
This is absolutely not required, but we are happy to guide you in the contribution process
|
||||
especially if you already have a good understanding of how to implement the feature.
|
||||
Dubbo is a totally community-driven project and we love to bring new contributors in.
|
||||
options:
|
||||
- label: Yes I am willing to submit a pull request on my own!
|
||||
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Code of Conduct
|
||||
description: The Code of Conduct helps create a safe space for everyone. We require that everyone agrees to it.
|
||||
options:
|
||||
- label: >
|
||||
I agree to follow this project's
|
||||
[Code of Conduct](https://www.apache.org/foundation/policies/conduct)
|
||||
required: true
|
||||
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: "Thanks for completing our form!"
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
---
|
||||
name: Bug Report
|
||||
about: Report a bug in Dubbo
|
||||
title: ''
|
||||
labels: type/bug
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
<!-- If you need to report a security issue please visit https://github.com/apache/dubbo/security/policy -->
|
||||
|
||||
- [ ] I have searched the [issues](https://github.com/apache/dubbo/issues) of this repository and believe that this is not a duplicate.
|
||||
|
||||
### Environment
|
||||
|
||||
* Dubbo version: xxx
|
||||
* Operating System version: xxx
|
||||
* Java version: xxx
|
||||
|
||||
### Steps to reproduce this issue
|
||||
|
||||
1. xxx
|
||||
2. xxx
|
||||
3. xxx
|
||||
|
||||
Pls. provide [GitHub address] to reproduce this issue.
|
||||
|
||||
### Expected Behavior
|
||||
|
||||
<!-- What do you expect from the above steps?-->
|
||||
|
||||
### Actual Behavior
|
||||
|
||||
<!-- What actually happens? -->
|
||||
|
||||
If there is an exception, please attach the exception trace:
|
||||
|
||||
```
|
||||
Just put your stack trace here!
|
||||
```
|
||||
|
|
@ -1,22 +1,8 @@
|
|||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
blank_issues_enabled: false
|
||||
blank_issues_enabled: true
|
||||
contact_links:
|
||||
- name: Question & FAQ & Proposal
|
||||
url: https://github.com/apache/dubbo/discussions/
|
||||
about: Ask a question, request support or submit a proposal for Apache Dubbo.
|
||||
- name: Dubbo Community Repo
|
||||
url: https://github.com/apache/dubbo-website
|
||||
about: Please see our community docs here.
|
||||
- name: Report a security issue
|
||||
url: https://github.com/apache/dubbo/security/policy
|
||||
about: Please report security vulnerabilities using these instructions.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
---
|
||||
name: Discussion
|
||||
about: Start a discussion for Dubbo
|
||||
title: ''
|
||||
labels: type/discussion
|
||||
assignees: ''
|
||||
---
|
||||
|
||||
<!-- If you need to report a security issue please visit https://github.com/apache/dubbo/security/policy -->
|
||||
|
||||
<!-- For all design discussions please continue. -->
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
---
|
||||
name: Feature Request
|
||||
about: Create a Feature Request for Dubbo
|
||||
title: ''
|
||||
labels: type/feature
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
<!-- If you need to report a security issue please visit https://github.com/apache/dubbo/security/policy -->
|
||||
|
||||
- [ ] I have searched the [issues](https://github.com/apache/dubbo/issues) of this repository and believe that this is not a duplicate.
|
||||
- [ ] I have searched the [release notes](https://github.com/apache/dubbo/releases) of this repository and believe that this is not a duplicate.
|
||||
|
||||
## Describe the feature
|
||||
<!-- Please also discuss possible business value -->
|
||||
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
---
|
||||
name: Proposal
|
||||
about: Create a technical proposal for Dubbo
|
||||
title: ''
|
||||
labels: type/proposal
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
<!-- If you need to report a security issue please visit https://github.com/apache/dubbo/security/policy -->
|
||||
|
||||
- [ ] I have searched the [issues](https://github.com/apache/dubbo/issues) of this repository and believe that this is not a duplicate.
|
||||
|
||||
## Describe the proposal
|
||||
<!-- Please use this for a concrete design proposal for functionality. -->
|
||||
<!-- If you just want to request a new feature and discuss the possible business value, create a Feature Request. -->
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
---
|
||||
name: Question
|
||||
about: Ask a question about Dubbo
|
||||
title: ''
|
||||
labels: type/question
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
<!-- If you need to report a security issue please visit https://github.com/apache/dubbo/security/policy -->
|
||||
|
||||
- [ ] I have searched the [issues](https://github.com/apache/dubbo/issues) of this repository and believe that this is not a duplicate.
|
||||
|
||||
## Ask your question here
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
## What is the purpose of the change
|
||||
|
||||
|
||||
|
||||
## Brief changelog
|
||||
|
||||
|
||||
## Verifying this change
|
||||
|
||||
|
||||
<!-- Follow this checklist to help us incorporate your contribution quickly and easily: -->
|
||||
|
||||
## Checklist
|
||||
- [x] Make sure there is a [GitHub_issue](https://github.com/apache/dubbo/issues) field for the change (usually before you start working on it). Trivial changes like typos do not require a GitHub issue. Your pull request should address just this issue, without pulling in other changes - one PR resolves one issue.
|
||||
- [ ] Each commit in the pull request should have a meaningful subject line and body.
|
||||
- [ ] Write a pull request description that is detailed enough to understand what the pull request does, how, and why.
|
||||
- [ ] Check if is necessary to patch to Dubbo 3 if you are work on Dubbo 2.7
|
||||
- [ ] Write necessary unit-test to verify your logic correction, more mock a little better when cross module dependency exist. If the new feature or significant change is committed, please remember to add sample in [dubbo samples](https://github.com/apache/dubbo-samples) project.
|
||||
- [ ] Add some description to [dubbo-website](https://github.com/apache/dubbo-website) project if you are requesting to add a feature.
|
||||
- [ ] GitHub Actions works fine on your own branch.
|
||||
- [ ] If this contribution is large, please follow the [Software Donation Guide](https://github.com/apache/dubbo/wiki/Software-donation-guide).
|
||||
|
|
@ -13,54 +13,13 @@ env:
|
|||
VERSIONS_LIMIT: 4
|
||||
JACOCO_ENABLE: true
|
||||
CANDIDATE_VERSIONS: '
|
||||
spring.version:5.3.24;
|
||||
spring-boot.version:2.7.6;
|
||||
spring.version:4.3.30.RELEASE;
|
||||
spring-boot.version:1.5.22.RELEASE;
|
||||
spring-boot.version:2.4.1;
|
||||
'
|
||||
|
||||
jobs:
|
||||
check-format:
|
||||
name: Check if code needs formatting
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Setup Maven
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: 21
|
||||
distribution: zulu
|
||||
- name: Check if code aligns with code style
|
||||
id: check
|
||||
run: mvn --log-file mvn.log spotless:check
|
||||
continue-on-error: true
|
||||
- name: Upload checkstyle result
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: checkstyle-result
|
||||
path: mvn.log
|
||||
- name: Generate Summary for successful run
|
||||
if: ${{ steps.check.outcome == 'success' }}
|
||||
run: |
|
||||
echo ":ballot_box_with_check: Kudos! No formatting issues found!" >> $GITHUB_STEP_SUMMARY
|
||||
- name: Generate Summary for failed run
|
||||
if: ${{ steps.check.outcome == 'failure' }}
|
||||
run: |
|
||||
echo "## :negative_squared_cross_mark: Formatting issues found!" >> $GITHUB_STEP_SUMMARY
|
||||
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
|
||||
cat mvn.log | grep "ERROR" | sed 's/Check if code needs formatting Check if code aligns with code style [0-9A-Z:.-]\+//' | sed 's/\[ERROR] //' | head -n -11 >> $GITHUB_STEP_SUMMARY
|
||||
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
|
||||
echo "Please run \`mvn spotless:apply\` to fix the formatting issues." >> $GITHUB_STEP_SUMMARY
|
||||
- name: Fail if code needs formatting
|
||||
if: ${{ steps.check.outcome == 'failure' }}
|
||||
uses: actions/github-script@v7.0.1
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
script: |
|
||||
core.setFailed("Formatting issues found!")
|
||||
|
||||
license:
|
||||
name: "Check License"
|
||||
needs: check-format
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
|
@ -68,11 +27,11 @@ jobs:
|
|||
uses: apache/skywalking-eyes@e1a02359b239bd28de3f6d35fdc870250fa513d5
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: "Set up JDK 21"
|
||||
- name: "Set up JDK 17"
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: 'zulu'
|
||||
java-version: 21
|
||||
java-version: 17
|
||||
- name: "Compile Dubbo (Linux)"
|
||||
run: |
|
||||
./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast -T 2C clean install -DskipTests=true -DskipIntegrationTests=true -Dcheckstyle.skip=true -Dcheckstyle_unix.skip=true -Drat.skip=true -Dmaven.javadoc.skip=true
|
||||
|
|
@ -85,8 +44,6 @@ jobs:
|
|||
mode: check
|
||||
|
||||
build-source:
|
||||
name: "Build Dubbo"
|
||||
needs: check-format
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
version: ${{ steps.dubbo-version.outputs.version }}
|
||||
|
|
@ -97,7 +54,7 @@ jobs:
|
|||
- uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: 'zulu'
|
||||
java-version: 8
|
||||
java-version: 17
|
||||
- uses: actions/cache@v3
|
||||
name: "Cache local Maven repository"
|
||||
with:
|
||||
|
|
@ -142,7 +99,6 @@ jobs:
|
|||
|
||||
unit-test-prepare:
|
||||
name: "Preparation for Unit Test"
|
||||
needs: check-format
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
|
|
@ -191,7 +147,7 @@ jobs:
|
|||
echo "--- End Print Rsa Public Key"
|
||||
|
||||
unit-test:
|
||||
needs: [check-format, build-source, unit-test-prepare]
|
||||
needs: [build-source, unit-test-prepare]
|
||||
name: "Unit Test On ubuntu-latest"
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
|
|
@ -208,7 +164,7 @@ jobs:
|
|||
uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: 'zulu'
|
||||
java-version: 21
|
||||
java-version: 17
|
||||
- uses: actions/cache@v3
|
||||
name: "Cache local Maven repository"
|
||||
with:
|
||||
|
|
@ -256,120 +212,15 @@ jobs:
|
|||
name: coverage-result
|
||||
path: "**/target/site/**/jacoco.xml"
|
||||
|
||||
samples-test-prepare:
|
||||
needs: check-format
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
JOB_COUNT: 3
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
repository: 'apache/dubbo-samples'
|
||||
ref: master
|
||||
- name: "Prepare test list"
|
||||
run: |
|
||||
bash ./test/scripts/prepare-test.sh
|
||||
- name: "Upload test list"
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: samples-test-list
|
||||
path: test/jobs
|
||||
samples-test-job:
|
||||
needs: [check-format, build-source, samples-test-prepare]
|
||||
name: "Samples Test on ubuntu-latest (JobId: ${{matrix.job_id}})"
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 90
|
||||
env:
|
||||
JAVA_VER: 8
|
||||
TEST_CASE_FILE: jobs/testjob_${{matrix.job_id}}.txt
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
job_id: [1, 2, 3]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
repository: 'apache/dubbo-samples'
|
||||
ref: master
|
||||
- name: "Cache local Maven repository"
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.m2/repository
|
||||
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}-${{ github.run_id }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
|
||||
${{ runner.os }}-maven-
|
||||
- name: "Restore Dubbo cache"
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.m2/repository/org/apache/dubbo
|
||||
key: ${{ runner.os }}-dubbo-snapshot-${{ github.sha }}-${{ github.run_id }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-dubbo-snapshot-${{ github.sha }}
|
||||
${{ runner.os }}-dubbo-snapshot-
|
||||
- name: "Download test list"
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: samples-test-list
|
||||
path: test/jobs/
|
||||
- name: "Set up JDK 8"
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: 'zulu'
|
||||
java-version: 8
|
||||
- name: "Init Candidate Versions"
|
||||
run: |
|
||||
DUBBO_VERSION="${{needs.build-source.outputs.version}}"
|
||||
CANDIDATE_VERSIONS="dubbo.version:$DUBBO_VERSION;compiler.version:$DUBBO_VERSION;$CANDIDATE_VERSIONS;dubbo.compiler.version:$DUBBO_VERSION"
|
||||
echo "CANDIDATE_VERSIONS=$CANDIDATE_VERSIONS" >> $GITHUB_ENV
|
||||
- name: "Build test image"
|
||||
run: |
|
||||
cd test && bash ./build-test-image.sh
|
||||
- name: "Run tests"
|
||||
run: cd test && bash ./run-tests.sh
|
||||
- name: "merge jacoco resule"
|
||||
run: |
|
||||
cd test/dubbo-test-jacoco-merger && mvn clean compile exec:java -Dexec.mainClass="org.apache.dubbo.test.JacocoMerge" -Dexec.args="${{github.workspace}}"
|
||||
- name: "Upload jacoco"
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: samples-jacoco-result
|
||||
path: target/jacoco*.exec
|
||||
- name: "Upload test result"
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: samples-test-result
|
||||
path: test/jobs/*-result*
|
||||
samples-test-result:
|
||||
needs: [check-format, samples-test-job]
|
||||
if: always()
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
JAVA_VER: 8
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
repository: 'apache/dubbo-samples'
|
||||
ref: master
|
||||
- name: "Download test result"
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: samples-test-result
|
||||
path: test/jobs/
|
||||
- name: "Merge test result"
|
||||
run: ./test/scripts/merge-test-results.sh
|
||||
|
||||
integration-test-prepare:
|
||||
needs: check-format
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
JOB_COUNT: 3
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
repository: 'apache/dubbo-integration-cases'
|
||||
ref: main
|
||||
repository: 'apache/dubbo-samples'
|
||||
ref: master
|
||||
- name: "Prepare test list"
|
||||
run: |
|
||||
bash ./test/scripts/prepare-test.sh
|
||||
|
|
@ -378,8 +229,9 @@ jobs:
|
|||
with:
|
||||
name: test-list
|
||||
path: test/jobs
|
||||
|
||||
integration-test-job:
|
||||
needs: [check-format, build-source, integration-test-prepare]
|
||||
needs: [build-source, integration-test-prepare]
|
||||
name: "Integration Test on ubuntu-latest (JobId: ${{matrix.job_id}})"
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 90
|
||||
|
|
@ -393,8 +245,8 @@ jobs:
|
|||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
repository: 'apache/dubbo-integration-cases'
|
||||
ref: main
|
||||
repository: 'apache/dubbo-samples'
|
||||
ref: master
|
||||
- name: "Cache local Maven repository"
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
|
|
@ -445,8 +297,9 @@ jobs:
|
|||
with:
|
||||
name: test-result
|
||||
path: test/jobs/*-result*
|
||||
|
||||
integration-test-result:
|
||||
needs: [check-format, integration-test-job]
|
||||
needs: [integration-test-job]
|
||||
if: always()
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
|
|
@ -454,8 +307,8 @@ jobs:
|
|||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
repository: 'apache/dubbo-integration-cases'
|
||||
ref: main
|
||||
repository: 'apache/dubbo-samples'
|
||||
ref: master
|
||||
- name: "Download test result"
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
|
|
@ -466,7 +319,7 @@ jobs:
|
|||
|
||||
jacoco-result-merge:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [check-format, integration-test-result, samples-test-result, unit-test]
|
||||
needs: [integration-test-result, unit-test]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
|
|
@ -475,15 +328,11 @@ jobs:
|
|||
with:
|
||||
repository: 'apache/dubbo-samples'
|
||||
path: "./dubbo-samples"
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
repository: 'apache/dubbo-integration-cases'
|
||||
path: "./dubbo-integration-cases"
|
||||
- name: "Set up JDK 21"
|
||||
- name: "Set up JDK 17"
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: 'zulu'
|
||||
java-version: 21
|
||||
java-version: 17
|
||||
- name: "Restore class result"
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
|
|
@ -494,23 +343,14 @@ jobs:
|
|||
cd ${{ github.workspace }}/dubbo
|
||||
unzip -o ${{ github.workspace }}/class.zip
|
||||
- name: "Restore jacoco exec"
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: samples-jacoco-result
|
||||
path: dubbo-samples/target/
|
||||
- name: "Restore integration jacoco exec"
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: jacoco-result
|
||||
path: dubbo-integration-cases/target/
|
||||
path: dubbo-samples/target/
|
||||
- name: "Merge jacoco result"
|
||||
run: |
|
||||
cd ${{ github.workspace }}/dubbo-samples/test/dubbo-test-jacoco-merger
|
||||
mvn clean compile exec:java -Dexec.mainClass="org.apache.dubbo.test.JacocoReport" -Dexec.args="${{github.workspace}}/dubbo-samples ${{github.workspace}}/dubbo"
|
||||
- name: "Merge samples jacoco result"
|
||||
run: |
|
||||
cd ${{ github.workspace }}/dubbo-integration-cases/test/dubbo-test-jacoco-merger
|
||||
mvn clean compile exec:java -Dexec.mainClass="org.apache.dubbo.test.JacocoReport" -Dexec.args="${{github.workspace}}/dubbo-integration-cases ${{github.workspace}}/dubbo"
|
||||
- name: "Restore coverage result"
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
|
|
@ -518,11 +358,8 @@ jobs:
|
|||
path: dubbo/
|
||||
- name: "Upload coverage to Codecov"
|
||||
uses: codecov/codecov-action@v3
|
||||
with:
|
||||
verbose: true
|
||||
|
||||
error-code-inspecting:
|
||||
needs: check-format
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
|
@ -535,11 +372,11 @@ jobs:
|
|||
ref: main
|
||||
path: "./dubbo-test-tools"
|
||||
|
||||
- name: "Set up JDK 21"
|
||||
- name: "Set up JDK 17"
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: 'zulu'
|
||||
java-version: 21
|
||||
java-version: 17
|
||||
|
||||
- name: "Compile Dubbo (Linux)"
|
||||
run: |
|
||||
|
|
@ -561,7 +398,6 @@ jobs:
|
|||
path: ${{ github.workspace }}/dubbo-test-tools/dubbo-error-code-inspector/error-inspection-result.txt
|
||||
|
||||
native-image-inspecting:
|
||||
needs: check-format
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
|
@ -579,10 +415,10 @@ jobs:
|
|||
|
||||
- name: "Setup Zookeeper environment"
|
||||
run: |
|
||||
wget https://dlcdn.apache.org/zookeeper/zookeeper-3.8.4/apache-zookeeper-3.8.4-bin.tar.gz
|
||||
tar -zxvf apache-zookeeper-3.8.4-bin.tar.gz
|
||||
mv apache-zookeeper-3.8.4-bin/conf/zoo_sample.cfg apache-zookeeper-3.8.4-bin/conf/zoo.cfg
|
||||
apache-zookeeper-3.8.4-bin/bin/zkServer.sh start
|
||||
wget https://dlcdn.apache.org/zookeeper/zookeeper-3.7.1/apache-zookeeper-3.7.1-bin.tar.gz
|
||||
tar -zxvf apache-zookeeper-3.7.1-bin.tar.gz
|
||||
mv apache-zookeeper-3.7.1-bin/conf/zoo_sample.cfg apache-zookeeper-3.7.1-bin/conf/zoo.cfg
|
||||
apache-zookeeper-3.7.1-bin/bin/zkServer.sh start
|
||||
|
||||
- name: "Check environment"
|
||||
run: |
|
||||
|
|
|
|||
|
|
@ -0,0 +1,251 @@
|
|||
name: Build and Test Scheduled On 3.0
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 0/6 * * *'
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
FORK_COUNT: 2
|
||||
FAIL_FAST: 0
|
||||
SHOW_ERROR_DETAIL: 1
|
||||
#multi-version size limit
|
||||
VERSIONS_LIMIT: 4
|
||||
CANDIDATE_VERSIONS: '
|
||||
spring.version:4.3.30.RELEASE;
|
||||
spring-boot.version:1.5.22.RELEASE;
|
||||
spring-boot.version:2.4.1;
|
||||
'
|
||||
|
||||
jobs:
|
||||
build-source:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
version: ${{ steps.dubbo-version.outputs.version }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
ref: "3.0"
|
||||
path: dubbo
|
||||
- uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: 'zulu'
|
||||
java-version: 8
|
||||
- uses: actions/cache@v3
|
||||
name: "Cache local Maven repository"
|
||||
with:
|
||||
path: ~/.m2/repository
|
||||
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}-${{ github.run_id }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
|
||||
${{ runner.os }}-maven-
|
||||
- name: "Dubbo cache"
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.m2/repository/org/apache/dubbo
|
||||
key: ${{ runner.os }}-dubbo-snapshot-${{ github.sha }}-${{ github.run_id }}
|
||||
- name: "Build Dubbo with Maven"
|
||||
run: |
|
||||
cd ./dubbo
|
||||
./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean source:jar install -Pjacoco,checkstyle -Dmaven.wagon.httpconnectionManager.ttlSeconds=120 -Dmaven.wagon.http.retryHandler.count=5 -Dmaven.test.skip=true -Dmaven.test.skip.exec=true -DembeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper
|
||||
- name: "Pack checkstyle file if failure"
|
||||
if: failure()
|
||||
run: 7z a ${{ github.workspace }}/checkstyle.zip *checkstyle* -r
|
||||
- name: "Upload checkstyle file if failure"
|
||||
if: failure()
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: "checkstyle-file"
|
||||
path: ${{ github.workspace }}/checkstyle.zip
|
||||
- name: "Calculate Dubbo Version"
|
||||
id: dubbo-version
|
||||
run: |
|
||||
REVISION=`awk '/<revision>[^<]+<\/revision>/{gsub(/<revision>|<\/revision>/,"",$1);print $1;exit;}' ./dubbo/pom.xml`
|
||||
echo "version=$REVISION" >> $GITHUB_OUTPUT
|
||||
echo "dubbo version: $REVISION"
|
||||
|
||||
unit-test-prepare:
|
||||
name: " Preparation for Unit Test On ${{ matrix.os }}"
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ ubuntu-latest, windows-latest ]
|
||||
env:
|
||||
ZOOKEEPER_VERSION: 3.6.3
|
||||
steps:
|
||||
- uses: actions/cache@v3
|
||||
name: "Cache zookeeper binary archive"
|
||||
id: "cache-zookeeper"
|
||||
with:
|
||||
path: ${{ github.workspace }}/.tmp/zookeeper
|
||||
key: zookeeper-${{ runner.os }}-${{ env.ZOOKEEPER_VERSION }}
|
||||
restore-keys: |
|
||||
zookeeper-${{ runner.os }}-${{ env.ZOOKEEPER_VERSION }}
|
||||
- name: "Set up msys2 if necessary"
|
||||
if: ${{ startsWith( matrix.os, 'windows') && steps.cache-zookeeper.outputs.cache-hit != 'true' }}
|
||||
uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
release: false # support cache, see https://github.com/msys2/setup-msys2#context
|
||||
- name: "Download zookeeper binary archive in Linux OS"
|
||||
if: ${{ startsWith( matrix.os, 'ubuntu') && steps.cache-zookeeper.outputs.cache-hit != 'true' }}
|
||||
run: |
|
||||
mkdir -p ${{ github.workspace }}/.tmp/zookeeper
|
||||
wget -c https://archive.apache.org/dist/zookeeper/zookeeper-${{ env.ZOOKEEPER_VERSION }}/apache-zookeeper-${{ env.ZOOKEEPER_VERSION }}-bin.tar.gz -O ${{ github.workspace }}/.tmp/zookeeper/apache-zookeeper-bin.tar.gz ||
|
||||
wget -c https://apache.website-solution.net/zookeeper/zookeeper-${{ env.ZOOKEEPER_VERSION }}/apache-zookeeper-${{ env.ZOOKEEPER_VERSION }}-bin.tar.gz -O ${{ github.workspace }}/.tmp/zookeeper/apache-zookeeper-bin.tar.gz ||
|
||||
wget -c http://apache.stu.edu.tw/zookeeper/zookeeper-${{ env.ZOOKEEPER_VERSION }}/apache-zookeeper-${{ env.ZOOKEEPER_VERSION }}-bin.tar.gz -O ${{ github.workspace }}/.tmp/zookeeper/apache-zookeeper-bin.tar.gz ||
|
||||
wget -c http://ftp.jaist.ac.jp/pub/apache/zookeeper/zookeeper-${{ env.ZOOKEEPER_VERSION }}/apache-zookeeper-${{ env.ZOOKEEPER_VERSION }}-bin.tar.gz -O ${{ github.workspace }}/.tmp/zookeeper/apache-zookeeper-bin.tar.gz ||
|
||||
wget -c http://apache.mirror.cdnetworks.com/zookeeper/zookeeper-${{ env.ZOOKEEPER_VERSION }}/apache-zookeeper-${{ env.ZOOKEEPER_VERSION }}-bin.tar.gz -O ${{ github.workspace }}/.tmp/zookeeper/apache-zookeeper-bin.tar.gz ||
|
||||
wget -c http://mirror.apache-kr.org/apache/zookeeper/zookeeper-${{ env.ZOOKEEPER_VERSION }}/apache-zookeeper-${{ env.ZOOKEEPER_VERSION }}-bin.tar.gz -O ${{ github.workspace }}/.tmp/zookeeper/apache-zookeeper-bin.tar.gz
|
||||
echo "list the downloaded zookeeper binary archive"
|
||||
ls -al ${{ github.workspace }}/.tmp/zookeeper/apache-zookeeper-bin.tar.gz
|
||||
- name: "Download zookeeper binary archive in Windows OS"
|
||||
if: ${{ startsWith( matrix.os, 'windows') && steps.cache-zookeeper.outputs.cache-hit != 'true' }}
|
||||
shell: msys2 {0}
|
||||
run: |
|
||||
mkdir -p ${{ github.workspace }}/.tmp/zookeeper
|
||||
wget -c https://archive.apache.org/dist/zookeeper/zookeeper-${{ env.ZOOKEEPER_VERSION }}/apache-zookeeper-${{ env.ZOOKEEPER_VERSION }}-bin.tar.gz -O ${{ github.workspace }}/.tmp/zookeeper/apache-zookeeper-bin.tar.gz ||
|
||||
wget -c https://apache.website-solution.net/zookeeper/zookeeper-${{ env.ZOOKEEPER_VERSION }}/apache-zookeeper-${{ env.ZOOKEEPER_VERSION }}-bin.tar.gz -O ${{ github.workspace }}/.tmp/zookeeper/apache-zookeeper-bin.tar.gz ||
|
||||
wget -c http://apache.stu.edu.tw/zookeeper/zookeeper-${{ env.ZOOKEEPER_VERSION }}/apache-zookeeper-${{ env.ZOOKEEPER_VERSION }}-bin.tar.gz -O ${{ github.workspace }}/.tmp/zookeeper/apache-zookeeper-bin.tar.gz ||
|
||||
wget -c http://ftp.jaist.ac.jp/pub/apache/zookeeper/zookeeper-${{ env.ZOOKEEPER_VERSION }}/apache-zookeeper-${{ env.ZOOKEEPER_VERSION }}-bin.tar.gz -O ${{ github.workspace }}/.tmp/zookeeper/apache-zookeeper-bin.tar.gz ||
|
||||
wget -c http://apache.mirror.cdnetworks.com/zookeeper/zookeeper-${{ env.ZOOKEEPER_VERSION }}/apache-zookeeper-${{ env.ZOOKEEPER_VERSION }}-bin.tar.gz -O ${{ github.workspace }}/.tmp/zookeeper/apache-zookeeper-bin.tar.gz ||
|
||||
wget -c http://mirror.apache-kr.org/apache/zookeeper/zookeeper-${{ env.ZOOKEEPER_VERSION }}/apache-zookeeper-${{ env.ZOOKEEPER_VERSION }}-bin.tar.gz -O ${{ github.workspace }}/.tmp/zookeeper/apache-zookeeper-bin.tar.gz
|
||||
echo "list the downloaded zookeeper binary archive"
|
||||
ls -al ${{ github.workspace }}/.tmp/zookeeper/apache-zookeeper-bin.tar.gz
|
||||
|
||||
unit-test:
|
||||
needs: [build-source, unit-test-prepare]
|
||||
name: "Unit Test On ${{ matrix.os }} (JDK: ${{ matrix.jdk }})"
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ ubuntu-latest, windows-latest ]
|
||||
jdk: [ 8, 11, 17 ]
|
||||
env:
|
||||
DISABLE_FILE_SYSTEM_TEST: true
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
ref: "3.0"
|
||||
- name: "Set up JDK ${{ matrix.jdk }}"
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: ${{ matrix.jdk }}
|
||||
- uses: actions/cache@v3
|
||||
name: "Cache local Maven repository"
|
||||
with:
|
||||
path: ~/.m2/repository
|
||||
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}-${{ github.run_id }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
|
||||
${{ runner.os }}-maven-
|
||||
- name: "Test with Maven with Integration Tests"
|
||||
timeout-minutes: 70
|
||||
if: ${{ startsWith( matrix.os, 'ubuntu') }}
|
||||
run: ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean test verify -Pjacoco -Dmaven.wagon.httpconnectionManager.ttlSeconds=120 -Dmaven.wagon.http.retryHandler.count=5 -DskipTests=false -DskipIntegrationTests=false -Dcheckstyle.skip=false -Dcheckstyle_unix.skip=false -Drat.skip=false -Dmaven.javadoc.skip=true -DembeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper
|
||||
- name: "Test with Maven without Integration Tests"
|
||||
timeout-minutes: 90
|
||||
if: ${{ startsWith( matrix.os, 'windows') }}
|
||||
run: ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean test verify -Pjacoco -D"http.keepAlive=false" -D"maven.wagon.http.pool=false" -D"maven.wagon.httpconnectionManager.ttlSeconds=120" -D"maven.wagon.http.retryHandler.count=5" -DskipTests=false -DskipIntegrationTests=true -D"checkstyle.skip=false" -D"checkstyle_unix.skip=true" -D"rat.skip=false" -D"maven.javadoc.skip=true" -D"embeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper"
|
||||
- name: "Upload coverage to Codecov"
|
||||
uses: codecov/codecov-action@v3
|
||||
|
||||
integration-test-prepare:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
JOB_COUNT: 3
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
repository: 'apache/dubbo-samples'
|
||||
ref: master
|
||||
- name: "Prepare test list"
|
||||
run: |
|
||||
bash ./test/scripts/prepare-test.sh
|
||||
- name: "Upload test list"
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: test-list
|
||||
path: test/jobs
|
||||
|
||||
integration-test-job:
|
||||
needs: [build-source, integration-test-prepare]
|
||||
name: "Integration Test on ubuntu-latest (JobId: ${{matrix.job_id}})"
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 30
|
||||
env:
|
||||
JAVA_VER: 8
|
||||
TEST_CASE_FILE: jobs/testjob_${{matrix.job_id}}.txt
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
job_id: [1, 2, 3]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
repository: 'apache/dubbo-samples'
|
||||
ref: master
|
||||
- name: "Cache local Maven repository"
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.m2/repository
|
||||
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}-${{ github.run_id }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
|
||||
${{ runner.os }}-maven-
|
||||
- name: "Restore Dubbo cache"
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.m2/repository/org/apache/dubbo
|
||||
key: ${{ runner.os }}-dubbo-snapshot-${{ github.sha }}-${{ github.run_id }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-dubbo-snapshot-${{ github.sha }}
|
||||
${{ runner.os }}-dubbo-snapshot-
|
||||
- name: "Download test list"
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: test-list
|
||||
path: test/jobs/
|
||||
- name: "Set up JDK 8"
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 8
|
||||
- name: "Init Candidate Versions"
|
||||
run: |
|
||||
DUBBO_VERSION="${{needs.build-source.outputs.version}}"
|
||||
CANDIDATE_VERSIONS="dubbo.version:$DUBBO_VERSION;compiler.version:$DUBBO_VERSION;$CANDIDATE_VERSIONS;dubbo.compiler.version:$DUBBO_VERSION"
|
||||
echo "CANDIDATE_VERSIONS=$CANDIDATE_VERSIONS" >> $GITHUB_ENV
|
||||
- name: "Build test image"
|
||||
run: |
|
||||
cd test && bash ./build-test-image.sh
|
||||
- name: "Run tests"
|
||||
run: cd test && bash ./run-tests.sh
|
||||
- name: "Upload test result"
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: test-result
|
||||
path: test/jobs/*-result*
|
||||
|
||||
integration-test-result:
|
||||
needs: [integration-test-job]
|
||||
if: always()
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
JAVA_VER: 8
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
repository: 'apache/dubbo-samples'
|
||||
ref: master
|
||||
- name: "Download test result"
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: test-result
|
||||
path: test/jobs/
|
||||
- name: "Merge test result"
|
||||
run: ./test/scripts/merge-test-results.sh
|
||||
|
|
@ -134,7 +134,7 @@ jobs:
|
|||
fail-fast: false
|
||||
matrix:
|
||||
os: [ ubuntu-latest, windows-latest ]
|
||||
jdk: [ 8, 11, 17, 21 ]
|
||||
jdk: [ 8, 11, 17, 19 ]
|
||||
env:
|
||||
DISABLE_FILE_SYSTEM_TEST: true
|
||||
steps:
|
||||
|
|
@ -169,6 +169,8 @@ jobs:
|
|||
timeout-minutes: 90
|
||||
if: ${{ startsWith( matrix.os, 'windows') }}
|
||||
run: ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean test verify -Pjacoco -D"http.keepAlive=false" -D"maven.wagon.http.pool=false" -D"maven.wagon.httpconnectionManager.ttlSeconds=120" -D"maven.wagon.http.retryHandler.count=5" -DskipTests=false -DskipIntegrationTests=true -D"checkstyle.skip=false" -D"checkstyle_unix.skip=true" -D"rat.skip=false" -D"maven.javadoc.skip=true" -D"embeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper"
|
||||
- name: "Upload coverage to Codecov"
|
||||
uses: codecov/codecov-action@v3
|
||||
|
||||
unit-test-fastjson2:
|
||||
needs: [build-source, unit-test-prepare]
|
||||
|
|
@ -178,17 +180,18 @@ jobs:
|
|||
fail-fast: false
|
||||
matrix:
|
||||
os: [ ubuntu-latest, windows-latest ]
|
||||
jdk: [ 8, 11, 17, 21 ]
|
||||
jdk: [ 8, 11, 17, 19 ]
|
||||
env:
|
||||
DISABLE_FILE_SYSTEM_TEST: true
|
||||
DUBBO_DEFAULT_SERIALIZATION: fastjson2
|
||||
MAVEN_SUREFIRE_ADD_OPENS: true
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: "Set up JDK ${{ matrix.jdk }}"
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: 'zulu'
|
||||
ref: "3.1"
|
||||
- name: "Set up JDK ${{ matrix.jdk }}"
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: ${{ matrix.jdk }}
|
||||
- uses: actions/cache@v3
|
||||
name: "Cache local Maven repository"
|
||||
|
|
@ -206,120 +209,16 @@ jobs:
|
|||
key: zookeeper-${{ runner.os }}-${{ env.ZOOKEEPER_VERSION }}
|
||||
restore-keys: |
|
||||
zookeeper-${{ runner.os }}-
|
||||
- name: "Test with Maven with Integration Tests on JDK 8"
|
||||
timeout-minutes: 70
|
||||
if: ${{ startsWith( matrix.os, 'ubuntu') && matrix.jdk == '8' }}
|
||||
run: ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean test verify -Pjacoco,'!jdk15ge' -Dmaven.wagon.httpconnectionManager.ttlSeconds=120 -Dmaven.wagon.http.retryHandler.count=5 -DskipTests=false -DskipIntegrationTests=false -Dcheckstyle.skip=false -Dcheckstyle_unix.skip=false -Drat.skip=false -Dmaven.javadoc.skip=true -DembeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper
|
||||
- name: "Test with Maven without Integration Tests on JDK 8"
|
||||
timeout-minutes: 90
|
||||
if: ${{ startsWith( matrix.os, 'windows') && matrix.jdk == '8' }}
|
||||
run: ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean test verify -P"jacoco,'!jdk15ge'" -D"http.keepAlive=false" -D"maven.wagon.http.pool=false" -D"maven.wagon.httpconnectionManager.ttlSeconds=120" -D"maven.wagon.http.retryHandler.count=5" -DskipTests=false -DskipIntegrationTests=true -D"checkstyle.skip=false" -D"checkstyle_unix.skip=true" -D"rat.skip=false" -D"maven.javadoc.skip=true" -D"embeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper"
|
||||
- name: "Test with Maven with Integration Tests"
|
||||
timeout-minutes: 70
|
||||
if: ${{ startsWith( matrix.os, 'ubuntu') && matrix.jdk != '8' }}
|
||||
run: ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean test verify -Pjacoco,jdk15ge-simple,'!jdk15ge' -Dmaven.wagon.httpconnectionManager.ttlSeconds=120 -Dmaven.wagon.http.retryHandler.count=5 -DskipTests=false -DskipIntegrationTests=false -Dcheckstyle.skip=false -Dcheckstyle_unix.skip=false -Drat.skip=false -Dmaven.javadoc.skip=true -DembeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper
|
||||
if: ${{ startsWith( matrix.os, 'ubuntu') }}
|
||||
run: ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean test verify -Pjacoco -Dmaven.wagon.httpconnectionManager.ttlSeconds=120 -Dmaven.wagon.http.retryHandler.count=5 -DskipTests=false -DskipIntegrationTests=false -Dcheckstyle.skip=false -Dcheckstyle_unix.skip=false -Drat.skip=false -Dmaven.javadoc.skip=true -DembeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper
|
||||
- name: "Test with Maven without Integration Tests"
|
||||
timeout-minutes: 90
|
||||
if: ${{ startsWith( matrix.os, 'windows') && matrix.jdk != '8' }}
|
||||
run: ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean test verify -P"jacoco,jdk15ge-simple,'!jdk15ge'" -D"http.keepAlive=false" -D"maven.wagon.http.pool=false" -D"maven.wagon.httpconnectionManager.ttlSeconds=120" -D"maven.wagon.http.retryHandler.count=5" -DskipTests=false -DskipIntegrationTests=true -D"checkstyle.skip=false" -D"checkstyle_unix.skip=true" -D"rat.skip=false" -D"maven.javadoc.skip=true" -D"embeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper"
|
||||
|
||||
samples-test-prepare:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
JOB_COUNT: 5
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
repository: 'apache/dubbo-samples'
|
||||
ref: master
|
||||
- name: "Prepare test list"
|
||||
run: |
|
||||
bash ./test/scripts/prepare-test.sh
|
||||
- name: "Upload test list"
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: samples-test-list
|
||||
path: test/jobs
|
||||
samples-test-job:
|
||||
needs: [build-source, samples-test-prepare]
|
||||
name: "Samples Test on ubuntu-latest (JobId: ${{matrix.job_id}} JavaVer: ${{matrix.jdk}})"
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 90
|
||||
env:
|
||||
JAVA_VER: ${{matrix.jdk}}
|
||||
TEST_CASE_FILE: jobs/testjob_${{matrix.job_id}}.txt
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
jdk: [ 8, 11 ]
|
||||
job_id: [1, 2, 3, 4, 5]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
repository: 'apache/dubbo-samples'
|
||||
ref: master
|
||||
- name: "Cache local Maven repository"
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.m2/repository
|
||||
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}-${{ github.run_id }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
|
||||
${{ runner.os }}-maven-
|
||||
- name: "Restore Dubbo cache"
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.m2/repository/org/apache/dubbo
|
||||
key: ${{ runner.os }}-dubbo-snapshot-${{ github.sha }}-${{ github.run_id }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-dubbo-snapshot-${{ github.sha }}
|
||||
${{ runner.os }}-dubbo-snapshot-
|
||||
- name: "Download test list"
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: samples-test-list
|
||||
path: test/jobs/
|
||||
- name: "Set up JDK ${{matrix.jdk}}"
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: ${{matrix.jdk}}
|
||||
- name: "Init Candidate Versions"
|
||||
run: |
|
||||
DUBBO_VERSION="${{needs.build-source.outputs.version}}"
|
||||
CANDIDATE_VERSIONS="dubbo.version:$DUBBO_VERSION;compiler.version:$DUBBO_VERSION;$CANDIDATE_VERSIONS;dubbo.compiler.version:$DUBBO_VERSION"
|
||||
echo "CANDIDATE_VERSIONS=$CANDIDATE_VERSIONS" >> $GITHUB_ENV
|
||||
- name: "Build test image"
|
||||
run: |
|
||||
cd test && bash ./build-test-image.sh
|
||||
- name: "Run tests"
|
||||
run: cd test && bash ./run-tests.sh
|
||||
- name: "Upload test result"
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: samples-test-result-${{matrix.jdk}}
|
||||
path: test/jobs/*-result*
|
||||
samples-test-result:
|
||||
needs: [samples-test-job]
|
||||
if: always()
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
JAVA_VER: ${{matrix.jdk}}
|
||||
strategy:
|
||||
matrix:
|
||||
jdk: [ 8, 11 ]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
repository: 'apache/dubbo-samples'
|
||||
ref: master
|
||||
- name: "Download test result"
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: samples-test-result-${{matrix.jdk}}
|
||||
path: test/jobs/
|
||||
- name: "Merge test result"
|
||||
run: ./test/scripts/merge-test-results.sh
|
||||
if: ${{ startsWith( matrix.os, 'windows') }}
|
||||
run: ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean test verify -Pjacoco -D"http.keepAlive=false" -D"maven.wagon.http.pool=false" -D"maven.wagon.httpconnectionManager.ttlSeconds=120" -D"maven.wagon.http.retryHandler.count=5" -DskipTests=false -DskipIntegrationTests=true -D"checkstyle.skip=false" -D"checkstyle_unix.skip=true" -D"rat.skip=false" -D"maven.javadoc.skip=true" -D"embeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper"
|
||||
- name: "Upload coverage to Codecov"
|
||||
uses: codecov/codecov-action@v3
|
||||
|
||||
integration-test-prepare:
|
||||
runs-on: ubuntu-latest
|
||||
|
|
@ -328,19 +227,20 @@ jobs:
|
|||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
repository: 'apache/dubbo-integration-cases'
|
||||
ref: main
|
||||
repository: 'apache/dubbo-samples'
|
||||
ref: master
|
||||
- name: "Prepare test list"
|
||||
run: |
|
||||
bash ./test/scripts/prepare-test.sh
|
||||
- name: "Upload test list"
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: integration-test-list
|
||||
name: test-list
|
||||
path: test/jobs
|
||||
|
||||
integration-test-job:
|
||||
needs: [build-source, integration-test-prepare]
|
||||
name: "Integration Test on ubuntu-latest (JobId: ${{matrix.job_id}} JavaVer: ${{matrix.jdk}})"
|
||||
name: "Integration Test on ubuntu-latest (JobId: ${{matrix.job_id}})"
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 90
|
||||
env:
|
||||
|
|
@ -354,8 +254,8 @@ jobs:
|
|||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
repository: 'apache/dubbo-integration-cases'
|
||||
ref: main
|
||||
repository: 'apache/dubbo-samples'
|
||||
ref: master
|
||||
- name: "Cache local Maven repository"
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
|
|
@ -375,7 +275,7 @@ jobs:
|
|||
- name: "Download test list"
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: integration-test-list
|
||||
name: test-list
|
||||
path: test/jobs/
|
||||
- name: "Set up JDK ${{matrix.jdk}}"
|
||||
uses: actions/setup-java@v1
|
||||
|
|
@ -395,8 +295,9 @@ jobs:
|
|||
if: always()
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: integration-test-result-${{matrix.jdk}}
|
||||
name: test-result-${{matrix.jdk}}
|
||||
path: test/jobs/*-result*
|
||||
|
||||
integration-test-result:
|
||||
needs: [integration-test-job]
|
||||
if: always()
|
||||
|
|
@ -409,12 +310,12 @@ jobs:
|
|||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
repository: 'apache/dubbo-integration-cases'
|
||||
ref: main
|
||||
repository: 'apache/dubbo-samples'
|
||||
ref: master
|
||||
- name: "Download test result"
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: integration-test-result-${{matrix.jdk}}
|
||||
name: test-result-${{matrix.jdk}}
|
||||
path: test/jobs/
|
||||
- name: "Merge test result"
|
||||
run: ./test/scripts/merge-test-results.sh
|
||||
|
|
@ -433,11 +334,10 @@ jobs:
|
|||
ref: main
|
||||
path: "./dubbo-test-tools"
|
||||
|
||||
- name: "Set up JDK 21"
|
||||
uses: actions/setup-java@v3
|
||||
- name: "Set up JDK 17"
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
distribution: 'zulu'
|
||||
java-version: 21
|
||||
java-version: 17
|
||||
|
||||
- name: "Compile Dubbo (Linux)"
|
||||
run: |
|
||||
|
|
@ -477,10 +377,10 @@ jobs:
|
|||
|
||||
- name: "Setup Zookeeper environment"
|
||||
run: |
|
||||
wget https://dlcdn.apache.org/zookeeper/zookeeper-3.8.4/apache-zookeeper-3.8.4-bin.tar.gz
|
||||
tar -zxvf apache-zookeeper-3.8.4-bin.tar.gz
|
||||
mv apache-zookeeper-3.8.4-bin/conf/zoo_sample.cfg apache-zookeeper-3.8.4-bin/conf/zoo.cfg
|
||||
apache-zookeeper-3.8.4-bin/bin/zkServer.sh start
|
||||
wget https://dlcdn.apache.org/zookeeper/zookeeper-3.7.1/apache-zookeeper-3.7.1-bin.tar.gz
|
||||
tar -zxvf apache-zookeeper-3.7.1-bin.tar.gz
|
||||
mv apache-zookeeper-3.7.1-bin/conf/zoo_sample.cfg apache-zookeeper-3.7.1-bin/conf/zoo.cfg
|
||||
apache-zookeeper-3.7.1-bin/bin/zkServer.sh start
|
||||
|
||||
- name: "Check environment"
|
||||
run: |
|
||||
|
|
@ -496,7 +396,7 @@ jobs:
|
|||
run: |
|
||||
cd ${{ github.workspace }}/dubbo/dubbo-demo/dubbo-demo-native/dubbo-demo-native-provider
|
||||
${{ github.workspace }}/dubbo/mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast -T 2C clean package -P native -Dmaven.test.skip=true native:compile
|
||||
nohup ./target/dubbo-demo-native-provider &
|
||||
nohup ./target/demo-native-provider &
|
||||
cd ${{ github.workspace }}/dubbo/dubbo-demo/dubbo-demo-native/dubbo-demo-native-consumer
|
||||
${{ github.workspace }}/dubbo/mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast -T 2C clean package -P native -Dmaven.test.skip=true native:compile
|
||||
./target/dubbo-demo-native-consumer
|
||||
./target/demo-native-consumer
|
||||
|
|
|
|||
|
|
@ -134,7 +134,7 @@ jobs:
|
|||
fail-fast: false
|
||||
matrix:
|
||||
os: [ ubuntu-latest, windows-latest ]
|
||||
jdk: [ 8, 11, 17, 21 ]
|
||||
jdk: [ 8, 11, 17, 19 ]
|
||||
env:
|
||||
DISABLE_FILE_SYSTEM_TEST: true
|
||||
steps:
|
||||
|
|
@ -169,6 +169,8 @@ jobs:
|
|||
timeout-minutes: 90
|
||||
if: ${{ startsWith( matrix.os, 'windows') }}
|
||||
run: ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean test verify -Pjacoco -D"http.keepAlive=false" -D"maven.wagon.http.pool=false" -D"maven.wagon.httpconnectionManager.ttlSeconds=120" -D"maven.wagon.http.retryHandler.count=5" -DskipTests=false -DskipIntegrationTests=true -D"checkstyle.skip=false" -D"checkstyle_unix.skip=true" -D"rat.skip=false" -D"maven.javadoc.skip=true" -D"embeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper"
|
||||
- name: "Upload coverage to Codecov"
|
||||
uses: codecov/codecov-action@v3
|
||||
|
||||
unit-test-fastjson2:
|
||||
needs: [build-source, unit-test-prepare]
|
||||
|
|
@ -178,17 +180,18 @@ jobs:
|
|||
fail-fast: false
|
||||
matrix:
|
||||
os: [ ubuntu-latest, windows-latest ]
|
||||
jdk: [ 8, 11, 17, 21 ]
|
||||
jdk: [ 8, 11, 17, 19 ]
|
||||
env:
|
||||
DISABLE_FILE_SYSTEM_TEST: true
|
||||
DUBBO_DEFAULT_SERIALIZATION: fastjson2
|
||||
MAVEN_SUREFIRE_ADD_OPENS: true
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: "Set up JDK ${{ matrix.jdk }}"
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: 'zulu'
|
||||
ref: "3.2"
|
||||
- name: "Set up JDK ${{ matrix.jdk }}"
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: ${{ matrix.jdk }}
|
||||
- uses: actions/cache@v3
|
||||
name: "Cache local Maven repository"
|
||||
|
|
@ -206,120 +209,16 @@ jobs:
|
|||
key: zookeeper-${{ runner.os }}-${{ env.ZOOKEEPER_VERSION }}
|
||||
restore-keys: |
|
||||
zookeeper-${{ runner.os }}-
|
||||
- name: "Test with Maven with Integration Tests on JDK 8"
|
||||
timeout-minutes: 70
|
||||
if: ${{ startsWith( matrix.os, 'ubuntu') && matrix.jdk == '8' }}
|
||||
run: ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean test verify -Pjacoco,'!jdk15ge' -Dmaven.wagon.httpconnectionManager.ttlSeconds=120 -Dmaven.wagon.http.retryHandler.count=5 -DskipTests=false -DskipIntegrationTests=false -Dcheckstyle.skip=false -Dcheckstyle_unix.skip=false -Drat.skip=false -Dmaven.javadoc.skip=true -DembeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper
|
||||
- name: "Test with Maven without Integration Tests on JDK 8"
|
||||
timeout-minutes: 90
|
||||
if: ${{ startsWith( matrix.os, 'windows') && matrix.jdk == '8' }}
|
||||
run: ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean test verify -P"jacoco,'!jdk15ge'" -D"http.keepAlive=false" -D"maven.wagon.http.pool=false" -D"maven.wagon.httpconnectionManager.ttlSeconds=120" -D"maven.wagon.http.retryHandler.count=5" -DskipTests=false -DskipIntegrationTests=true -D"checkstyle.skip=false" -D"checkstyle_unix.skip=true" -D"rat.skip=false" -D"maven.javadoc.skip=true" -D"embeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper"
|
||||
- name: "Test with Maven with Integration Tests"
|
||||
timeout-minutes: 70
|
||||
if: ${{ startsWith( matrix.os, 'ubuntu') && matrix.jdk != '8' }}
|
||||
if: ${{ startsWith( matrix.os, 'ubuntu') }}
|
||||
run: ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean test verify -Pjacoco,jdk15ge-simple,'!jdk15ge' -Dmaven.wagon.httpconnectionManager.ttlSeconds=120 -Dmaven.wagon.http.retryHandler.count=5 -DskipTests=false -DskipIntegrationTests=false -Dcheckstyle.skip=false -Dcheckstyle_unix.skip=false -Drat.skip=false -Dmaven.javadoc.skip=true -DembeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper
|
||||
- name: "Test with Maven without Integration Tests"
|
||||
timeout-minutes: 90
|
||||
if: ${{ startsWith( matrix.os, 'windows') && matrix.jdk != '8' }}
|
||||
if: ${{ startsWith( matrix.os, 'windows') }}
|
||||
run: ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean test verify -P"jacoco,jdk15ge-simple,'!jdk15ge'" -D"http.keepAlive=false" -D"maven.wagon.http.pool=false" -D"maven.wagon.httpconnectionManager.ttlSeconds=120" -D"maven.wagon.http.retryHandler.count=5" -DskipTests=false -DskipIntegrationTests=true -D"checkstyle.skip=false" -D"checkstyle_unix.skip=true" -D"rat.skip=false" -D"maven.javadoc.skip=true" -D"embeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper"
|
||||
|
||||
samples-test-prepare:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
JOB_COUNT: 5
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
repository: 'apache/dubbo-samples'
|
||||
ref: master
|
||||
- name: "Prepare test list"
|
||||
run: |
|
||||
bash ./test/scripts/prepare-test.sh
|
||||
- name: "Upload test list"
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: samples-test-list
|
||||
path: test/jobs
|
||||
samples-test-job:
|
||||
needs: [build-source, samples-test-prepare]
|
||||
name: "Samples Test on ubuntu-latest (JobId: ${{matrix.job_id}} JavaVer: ${{matrix.jdk}})"
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 90
|
||||
env:
|
||||
JAVA_VER: ${{matrix.jdk}}
|
||||
TEST_CASE_FILE: jobs/testjob_${{matrix.job_id}}.txt
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
jdk: [ 8, 11, 17, 21 ]
|
||||
job_id: [1, 2, 3, 4, 5]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
repository: 'apache/dubbo-samples'
|
||||
ref: master
|
||||
- name: "Cache local Maven repository"
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.m2/repository
|
||||
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}-${{ github.run_id }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
|
||||
${{ runner.os }}-maven-
|
||||
- name: "Restore Dubbo cache"
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.m2/repository/org/apache/dubbo
|
||||
key: ${{ runner.os }}-dubbo-snapshot-${{ github.sha }}-${{ github.run_id }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-dubbo-snapshot-${{ github.sha }}
|
||||
${{ runner.os }}-dubbo-snapshot-
|
||||
- name: "Download test list"
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: samples-test-list
|
||||
path: test/jobs/
|
||||
- name: "Set up JDK ${{matrix.jdk}}"
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: ${{matrix.jdk}}
|
||||
- name: "Init Candidate Versions"
|
||||
run: |
|
||||
DUBBO_VERSION="${{needs.build-source.outputs.version}}"
|
||||
CANDIDATE_VERSIONS="dubbo.version:$DUBBO_VERSION;compiler.version:$DUBBO_VERSION;$CANDIDATE_VERSIONS;dubbo.compiler.version:$DUBBO_VERSION"
|
||||
echo "CANDIDATE_VERSIONS=$CANDIDATE_VERSIONS" >> $GITHUB_ENV
|
||||
- name: "Build test image"
|
||||
run: |
|
||||
cd test && bash ./build-test-image.sh
|
||||
- name: "Run tests"
|
||||
run: cd test && bash ./run-tests.sh
|
||||
- name: "Upload test result"
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: samples-test-result-${{matrix.jdk}}
|
||||
path: test/jobs/*-result*
|
||||
samples-test-result:
|
||||
needs: [samples-test-job]
|
||||
if: always()
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
JAVA_VER: ${{matrix.jdk}}
|
||||
strategy:
|
||||
matrix:
|
||||
jdk: [ 8, 11, 17, 21 ]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
repository: 'apache/dubbo-samples'
|
||||
ref: master
|
||||
- name: "Download test result"
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: samples-test-result-${{matrix.jdk}}
|
||||
path: test/jobs/
|
||||
- name: "Merge test result"
|
||||
run: ./test/scripts/merge-test-results.sh
|
||||
- name: "Upload coverage to Codecov"
|
||||
uses: codecov/codecov-action@v3
|
||||
|
||||
integration-test-prepare:
|
||||
runs-on: ubuntu-latest
|
||||
|
|
@ -328,19 +227,20 @@ jobs:
|
|||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
repository: 'apache/dubbo-integration-cases'
|
||||
ref: main
|
||||
repository: 'apache/dubbo-samples'
|
||||
ref: master
|
||||
- name: "Prepare test list"
|
||||
run: |
|
||||
bash ./test/scripts/prepare-test.sh
|
||||
- name: "Upload test list"
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: integration-test-list
|
||||
name: test-list
|
||||
path: test/jobs
|
||||
|
||||
integration-test-job:
|
||||
needs: [build-source, integration-test-prepare]
|
||||
name: "Integration Test on ubuntu-latest (JobId: ${{matrix.job_id}} JavaVer: ${{matrix.jdk}})"
|
||||
name: "Integration Test on ubuntu-latest (JobId: ${{matrix.job_id}})"
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 90
|
||||
env:
|
||||
|
|
@ -349,13 +249,13 @@ jobs:
|
|||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
jdk: [ 8, 11, 17, 21 ]
|
||||
jdk: [ 8, 11, 17, 19 ]
|
||||
job_id: [1, 2, 3, 4, 5]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
repository: 'apache/dubbo-integration-cases'
|
||||
ref: main
|
||||
repository: 'apache/dubbo-samples'
|
||||
ref: master
|
||||
- name: "Cache local Maven repository"
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
|
|
@ -375,7 +275,7 @@ jobs:
|
|||
- name: "Download test list"
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: integration-test-list
|
||||
name: test-list
|
||||
path: test/jobs/
|
||||
- name: "Set up JDK ${{matrix.jdk}}"
|
||||
uses: actions/setup-java@v1
|
||||
|
|
@ -395,8 +295,9 @@ jobs:
|
|||
if: always()
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: integration-test-result-${{matrix.jdk}}
|
||||
name: test-result-${{matrix.jdk}}
|
||||
path: test/jobs/*-result*
|
||||
|
||||
integration-test-result:
|
||||
needs: [integration-test-job]
|
||||
if: always()
|
||||
|
|
@ -405,16 +306,16 @@ jobs:
|
|||
JAVA_VER: ${{matrix.jdk}}
|
||||
strategy:
|
||||
matrix:
|
||||
jdk: [ 8, 11, 17, 21 ]
|
||||
jdk: [ 8, 11, 17, 19 ]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
repository: 'apache/dubbo-integration-cases'
|
||||
ref: main
|
||||
repository: 'apache/dubbo-samples'
|
||||
ref: master
|
||||
- name: "Download test result"
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: integration-test-result-${{matrix.jdk}}
|
||||
name: test-result-${{matrix.jdk}}
|
||||
path: test/jobs/
|
||||
- name: "Merge test result"
|
||||
run: ./test/scripts/merge-test-results.sh
|
||||
|
|
@ -433,11 +334,10 @@ jobs:
|
|||
ref: main
|
||||
path: "./dubbo-test-tools"
|
||||
|
||||
- name: "Set up JDK 21"
|
||||
uses: actions/setup-java@v3
|
||||
- name: "Set up JDK 17"
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
distribution: 'zulu'
|
||||
java-version: 21
|
||||
java-version: 17
|
||||
|
||||
- name: "Compile Dubbo (Linux)"
|
||||
run: |
|
||||
|
|
@ -477,10 +377,10 @@ jobs:
|
|||
|
||||
- name: "Setup Zookeeper environment"
|
||||
run: |
|
||||
wget https://dlcdn.apache.org/zookeeper/zookeeper-3.8.4/apache-zookeeper-3.8.4-bin.tar.gz
|
||||
tar -zxvf apache-zookeeper-3.8.4-bin.tar.gz
|
||||
mv apache-zookeeper-3.8.4-bin/conf/zoo_sample.cfg apache-zookeeper-3.8.4-bin/conf/zoo.cfg
|
||||
apache-zookeeper-3.8.4-bin/bin/zkServer.sh start
|
||||
wget https://dlcdn.apache.org/zookeeper/zookeeper-3.7.1/apache-zookeeper-3.7.1-bin.tar.gz
|
||||
tar -zxvf apache-zookeeper-3.7.1-bin.tar.gz
|
||||
mv apache-zookeeper-3.7.1-bin/conf/zoo_sample.cfg apache-zookeeper-3.7.1-bin/conf/zoo.cfg
|
||||
apache-zookeeper-3.7.1-bin/bin/zkServer.sh start
|
||||
|
||||
- name: "Check environment"
|
||||
run: |
|
||||
|
|
|
|||
|
|
@ -1,502 +0,0 @@
|
|||
name: Build and Test Scheduled On 3.3
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 0/6 * * *'
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
FORK_COUNT: 2
|
||||
FAIL_FAST: 0
|
||||
SHOW_ERROR_DETAIL: 1
|
||||
#multi-version size limit
|
||||
VERSIONS_LIMIT: 4
|
||||
ALL_REMOTE_VERSION: true
|
||||
CANDIDATE_VERSIONS: '
|
||||
spring.version:5.3.24;
|
||||
spring-boot.version:2.7.6;
|
||||
'
|
||||
|
||||
jobs:
|
||||
license:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
ref: "3.3"
|
||||
- name: Check License
|
||||
uses: apache/skywalking-eyes@main
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
build-source:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
version: ${{ steps.dubbo-version.outputs.version }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
ref: "3.3"
|
||||
path: dubbo
|
||||
- uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: 'zulu'
|
||||
java-version: 21
|
||||
- uses: actions/cache@v3
|
||||
name: "Cache local Maven repository"
|
||||
with:
|
||||
path: ~/.m2/repository
|
||||
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}-${{ github.run_id }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
|
||||
${{ runner.os }}-maven-
|
||||
- name: "Dubbo cache"
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.m2/repository/org/apache/dubbo
|
||||
key: ${{ runner.os }}-dubbo-snapshot-${{ github.sha }}-${{ github.run_id }}
|
||||
- name: "Build Dubbo with Maven"
|
||||
run: |
|
||||
cd ./dubbo
|
||||
./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean source:jar install -Pjacoco,checkstyle -Dmaven.wagon.httpconnectionManager.ttlSeconds=120 -Dmaven.wagon.http.retryHandler.count=5 -Dmaven.test.skip=true -Dmaven.test.skip.exec=true -DembeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper
|
||||
- name: "Pack checkstyle file if failure"
|
||||
if: failure()
|
||||
run: 7z a ${{ github.workspace }}/checkstyle.zip *checkstyle* -r
|
||||
- name: "Upload checkstyle file if failure"
|
||||
if: failure()
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: "checkstyle-file"
|
||||
path: ${{ github.workspace }}/checkstyle.zip
|
||||
- name: "Calculate Dubbo Version"
|
||||
id: dubbo-version
|
||||
run: |
|
||||
REVISION=`awk '/<revision>[^<]+<\/revision>/{gsub(/<revision>|<\/revision>/,"",$1);print $1;exit;}' ./dubbo/pom.xml`
|
||||
echo "version=$REVISION" >> $GITHUB_OUTPUT
|
||||
echo "dubbo version: $REVISION"
|
||||
|
||||
unit-test-prepare:
|
||||
name: " Preparation for Unit Test On ${{ matrix.os }}"
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ ubuntu-latest, windows-latest ]
|
||||
env:
|
||||
ZOOKEEPER_VERSION: 3.6.3
|
||||
steps:
|
||||
- uses: actions/cache@v3
|
||||
name: "Cache zookeeper binary archive"
|
||||
id: "cache-zookeeper"
|
||||
with:
|
||||
path: ${{ github.workspace }}/.tmp/zookeeper
|
||||
key: zookeeper-${{ runner.os }}-${{ env.ZOOKEEPER_VERSION }}
|
||||
restore-keys: |
|
||||
zookeeper-${{ runner.os }}-${{ env.ZOOKEEPER_VERSION }}
|
||||
- name: "Set up msys2 if necessary"
|
||||
if: ${{ startsWith( matrix.os, 'windows') && steps.cache-zookeeper.outputs.cache-hit != 'true' }}
|
||||
uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
release: false # support cache, see https://github.com/msys2/setup-msys2#context
|
||||
- name: "Download zookeeper binary archive in Linux OS"
|
||||
if: ${{ startsWith( matrix.os, 'ubuntu') && steps.cache-zookeeper.outputs.cache-hit != 'true' }}
|
||||
run: |
|
||||
mkdir -p ${{ github.workspace }}/.tmp/zookeeper
|
||||
wget -c https://archive.apache.org/dist/zookeeper/zookeeper-${{ env.ZOOKEEPER_VERSION }}/apache-zookeeper-${{ env.ZOOKEEPER_VERSION }}-bin.tar.gz -O ${{ github.workspace }}/.tmp/zookeeper/apache-zookeeper-bin.tar.gz ||
|
||||
wget -c https://apache.website-solution.net/zookeeper/zookeeper-${{ env.ZOOKEEPER_VERSION }}/apache-zookeeper-${{ env.ZOOKEEPER_VERSION }}-bin.tar.gz -O ${{ github.workspace }}/.tmp/zookeeper/apache-zookeeper-bin.tar.gz ||
|
||||
wget -c http://apache.stu.edu.tw/zookeeper/zookeeper-${{ env.ZOOKEEPER_VERSION }}/apache-zookeeper-${{ env.ZOOKEEPER_VERSION }}-bin.tar.gz -O ${{ github.workspace }}/.tmp/zookeeper/apache-zookeeper-bin.tar.gz ||
|
||||
wget -c http://ftp.jaist.ac.jp/pub/apache/zookeeper/zookeeper-${{ env.ZOOKEEPER_VERSION }}/apache-zookeeper-${{ env.ZOOKEEPER_VERSION }}-bin.tar.gz -O ${{ github.workspace }}/.tmp/zookeeper/apache-zookeeper-bin.tar.gz ||
|
||||
wget -c http://apache.mirror.cdnetworks.com/zookeeper/zookeeper-${{ env.ZOOKEEPER_VERSION }}/apache-zookeeper-${{ env.ZOOKEEPER_VERSION }}-bin.tar.gz -O ${{ github.workspace }}/.tmp/zookeeper/apache-zookeeper-bin.tar.gz ||
|
||||
wget -c http://mirror.apache-kr.org/apache/zookeeper/zookeeper-${{ env.ZOOKEEPER_VERSION }}/apache-zookeeper-${{ env.ZOOKEEPER_VERSION }}-bin.tar.gz -O ${{ github.workspace }}/.tmp/zookeeper/apache-zookeeper-bin.tar.gz
|
||||
echo "list the downloaded zookeeper binary archive"
|
||||
ls -al ${{ github.workspace }}/.tmp/zookeeper/apache-zookeeper-bin.tar.gz
|
||||
- name: "Download zookeeper binary archive in Windows OS"
|
||||
if: ${{ startsWith( matrix.os, 'windows') && steps.cache-zookeeper.outputs.cache-hit != 'true' }}
|
||||
shell: msys2 {0}
|
||||
run: |
|
||||
mkdir -p ${{ github.workspace }}/.tmp/zookeeper
|
||||
wget -c https://archive.apache.org/dist/zookeeper/zookeeper-${{ env.ZOOKEEPER_VERSION }}/apache-zookeeper-${{ env.ZOOKEEPER_VERSION }}-bin.tar.gz -O ${{ github.workspace }}/.tmp/zookeeper/apache-zookeeper-bin.tar.gz ||
|
||||
wget -c https://apache.website-solution.net/zookeeper/zookeeper-${{ env.ZOOKEEPER_VERSION }}/apache-zookeeper-${{ env.ZOOKEEPER_VERSION }}-bin.tar.gz -O ${{ github.workspace }}/.tmp/zookeeper/apache-zookeeper-bin.tar.gz ||
|
||||
wget -c http://apache.stu.edu.tw/zookeeper/zookeeper-${{ env.ZOOKEEPER_VERSION }}/apache-zookeeper-${{ env.ZOOKEEPER_VERSION }}-bin.tar.gz -O ${{ github.workspace }}/.tmp/zookeeper/apache-zookeeper-bin.tar.gz ||
|
||||
wget -c http://ftp.jaist.ac.jp/pub/apache/zookeeper/zookeeper-${{ env.ZOOKEEPER_VERSION }}/apache-zookeeper-${{ env.ZOOKEEPER_VERSION }}-bin.tar.gz -O ${{ github.workspace }}/.tmp/zookeeper/apache-zookeeper-bin.tar.gz ||
|
||||
wget -c http://apache.mirror.cdnetworks.com/zookeeper/zookeeper-${{ env.ZOOKEEPER_VERSION }}/apache-zookeeper-${{ env.ZOOKEEPER_VERSION }}-bin.tar.gz -O ${{ github.workspace }}/.tmp/zookeeper/apache-zookeeper-bin.tar.gz ||
|
||||
wget -c http://mirror.apache-kr.org/apache/zookeeper/zookeeper-${{ env.ZOOKEEPER_VERSION }}/apache-zookeeper-${{ env.ZOOKEEPER_VERSION }}-bin.tar.gz -O ${{ github.workspace }}/.tmp/zookeeper/apache-zookeeper-bin.tar.gz
|
||||
echo "list the downloaded zookeeper binary archive"
|
||||
ls -al ${{ github.workspace }}/.tmp/zookeeper/apache-zookeeper-bin.tar.gz
|
||||
|
||||
unit-test:
|
||||
needs: [build-source, unit-test-prepare]
|
||||
name: "Unit Test On ${{ matrix.os }} (JDK: ${{ matrix.jdk }})"
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ ubuntu-latest, windows-latest ]
|
||||
jdk: [ 8, 11, 17, 21 ]
|
||||
env:
|
||||
DISABLE_FILE_SYSTEM_TEST: true
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
ref: "3.3"
|
||||
- name: "Set up JDK ${{ matrix.jdk }}"
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: ${{ matrix.jdk }}
|
||||
- uses: actions/cache@v3
|
||||
name: "Cache local Maven repository"
|
||||
with:
|
||||
path: ~/.m2/repository
|
||||
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}-${{ github.run_id }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
|
||||
${{ runner.os }}-maven-
|
||||
- uses: actions/cache@v3
|
||||
name: "Cache zookeeper binary archive"
|
||||
id: "cache-zookeeper"
|
||||
with:
|
||||
path: ${{ github.workspace }}/.tmp/zookeeper
|
||||
key: zookeeper-${{ runner.os }}-${{ env.ZOOKEEPER_VERSION }}
|
||||
restore-keys: |
|
||||
zookeeper-${{ runner.os }}-
|
||||
- name: "Test with Maven with Integration Tests"
|
||||
timeout-minutes: 70
|
||||
if: ${{ startsWith( matrix.os, 'ubuntu') }}
|
||||
run: ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean test verify -Pjacoco -Dmaven.wagon.httpconnectionManager.ttlSeconds=120 -Dmaven.wagon.http.retryHandler.count=5 -DskipTests=false -DskipIntegrationTests=false -Dcheckstyle.skip=false -Dcheckstyle_unix.skip=false -Drat.skip=false -Dmaven.javadoc.skip=true -DembeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper
|
||||
- name: "Test with Maven without Integration Tests"
|
||||
timeout-minutes: 90
|
||||
if: ${{ startsWith( matrix.os, 'windows') }}
|
||||
run: ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean test verify -Pjacoco -D"http.keepAlive=false" -D"maven.wagon.http.pool=false" -D"maven.wagon.httpconnectionManager.ttlSeconds=120" -D"maven.wagon.http.retryHandler.count=5" -DskipTests=false -DskipIntegrationTests=true -D"checkstyle.skip=false" -D"checkstyle_unix.skip=true" -D"rat.skip=false" -D"maven.javadoc.skip=true" -D"embeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper"
|
||||
|
||||
unit-test-fastjson2:
|
||||
needs: [build-source, unit-test-prepare]
|
||||
name: "Unit Test On ${{ matrix.os }} (JDK: ${{ matrix.jdk }}, Serialization: fastjson2)"
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ ubuntu-latest, windows-latest ]
|
||||
jdk: [ 8, 11, 17, 21 ]
|
||||
env:
|
||||
DISABLE_FILE_SYSTEM_TEST: true
|
||||
DUBBO_DEFAULT_SERIALIZATION: fastjson2
|
||||
MAVEN_SUREFIRE_ADD_OPENS: true
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: "Set up JDK ${{ matrix.jdk }}"
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: 'zulu'
|
||||
java-version: ${{ matrix.jdk }}
|
||||
- uses: actions/cache@v3
|
||||
name: "Cache local Maven repository"
|
||||
with:
|
||||
path: ~/.m2/repository
|
||||
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}-${{ github.run_id }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
|
||||
${{ runner.os }}-maven-
|
||||
- uses: actions/cache@v3
|
||||
name: "Cache zookeeper binary archive"
|
||||
id: "cache-zookeeper"
|
||||
with:
|
||||
path: ${{ github.workspace }}/.tmp/zookeeper
|
||||
key: zookeeper-${{ runner.os }}-${{ env.ZOOKEEPER_VERSION }}
|
||||
restore-keys: |
|
||||
zookeeper-${{ runner.os }}-
|
||||
- name: "Test with Maven with Integration Tests on JDK 8"
|
||||
timeout-minutes: 70
|
||||
if: ${{ startsWith( matrix.os, 'ubuntu') && matrix.jdk == '8' }}
|
||||
run: ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean test verify -Pjacoco,'!jdk15ge' -Dmaven.wagon.httpconnectionManager.ttlSeconds=120 -Dmaven.wagon.http.retryHandler.count=5 -DskipTests=false -DskipIntegrationTests=false -Dcheckstyle.skip=false -Dcheckstyle_unix.skip=false -Drat.skip=false -Dmaven.javadoc.skip=true -DembeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper
|
||||
- name: "Test with Maven without Integration Tests on JDK 8"
|
||||
timeout-minutes: 90
|
||||
if: ${{ startsWith( matrix.os, 'windows') && matrix.jdk == '8' }}
|
||||
run: ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean test verify -P"jacoco,'!jdk15ge'" -D"http.keepAlive=false" -D"maven.wagon.http.pool=false" -D"maven.wagon.httpconnectionManager.ttlSeconds=120" -D"maven.wagon.http.retryHandler.count=5" -DskipTests=false -DskipIntegrationTests=true -D"checkstyle.skip=false" -D"checkstyle_unix.skip=true" -D"rat.skip=false" -D"maven.javadoc.skip=true" -D"embeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper"
|
||||
- name: "Test with Maven with Integration Tests"
|
||||
timeout-minutes: 70
|
||||
if: ${{ startsWith( matrix.os, 'ubuntu') && matrix.jdk != '8' }}
|
||||
run: ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean test verify -Pjacoco,jdk15ge-simple,'!jdk15ge' -Dmaven.wagon.httpconnectionManager.ttlSeconds=120 -Dmaven.wagon.http.retryHandler.count=5 -DskipTests=false -DskipIntegrationTests=false -Dcheckstyle.skip=false -Dcheckstyle_unix.skip=false -Drat.skip=false -Dmaven.javadoc.skip=true -DembeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper
|
||||
- name: "Test with Maven without Integration Tests"
|
||||
timeout-minutes: 90
|
||||
if: ${{ startsWith( matrix.os, 'windows') && matrix.jdk != '8' }}
|
||||
run: ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean test verify -P"jacoco,jdk15ge-simple,'!jdk15ge'" -D"http.keepAlive=false" -D"maven.wagon.http.pool=false" -D"maven.wagon.httpconnectionManager.ttlSeconds=120" -D"maven.wagon.http.retryHandler.count=5" -DskipTests=false -DskipIntegrationTests=true -D"checkstyle.skip=false" -D"checkstyle_unix.skip=true" -D"rat.skip=false" -D"maven.javadoc.skip=true" -D"embeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper"
|
||||
|
||||
samples-test-prepare:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
JOB_COUNT: 5
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
repository: 'apache/dubbo-samples'
|
||||
ref: master
|
||||
- name: "Prepare test list"
|
||||
run: |
|
||||
bash ./test/scripts/prepare-test.sh
|
||||
- name: "Upload test list"
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: samples-test-list
|
||||
path: test/jobs
|
||||
samples-test-job:
|
||||
needs: [build-source, samples-test-prepare]
|
||||
name: "Samples Test on ubuntu-latest (JobId: ${{matrix.job_id}} JavaVer: ${{matrix.jdk}})"
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 90
|
||||
env:
|
||||
JAVA_VER: ${{matrix.jdk}}
|
||||
TEST_CASE_FILE: jobs/testjob_${{matrix.job_id}}.txt
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
jdk: [ 8, 11, 17, 21 ]
|
||||
job_id: [1, 2, 3, 4, 5]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
repository: 'apache/dubbo-samples'
|
||||
ref: master
|
||||
- name: "Cache local Maven repository"
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.m2/repository
|
||||
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}-${{ github.run_id }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
|
||||
${{ runner.os }}-maven-
|
||||
- name: "Restore Dubbo cache"
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.m2/repository/org/apache/dubbo
|
||||
key: ${{ runner.os }}-dubbo-snapshot-${{ github.sha }}-${{ github.run_id }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-dubbo-snapshot-${{ github.sha }}
|
||||
${{ runner.os }}-dubbo-snapshot-
|
||||
- name: "Download test list"
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: samples-test-list
|
||||
path: test/jobs/
|
||||
- name: "Set up JDK ${{matrix.jdk}}"
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: ${{matrix.jdk}}
|
||||
- name: "Init Candidate Versions"
|
||||
run: |
|
||||
DUBBO_VERSION="${{needs.build-source.outputs.version}}"
|
||||
CANDIDATE_VERSIONS="dubbo.version:$DUBBO_VERSION;compiler.version:$DUBBO_VERSION;$CANDIDATE_VERSIONS;dubbo.compiler.version:$DUBBO_VERSION"
|
||||
echo "CANDIDATE_VERSIONS=$CANDIDATE_VERSIONS" >> $GITHUB_ENV
|
||||
- name: "Build test image"
|
||||
run: |
|
||||
cd test && bash ./build-test-image.sh
|
||||
- name: "Run tests"
|
||||
run: cd test && bash ./run-tests.sh
|
||||
- name: "Upload test result"
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: samples-test-result-${{matrix.jdk}}
|
||||
path: test/jobs/*-result*
|
||||
samples-test-result:
|
||||
needs: [samples-test-job]
|
||||
if: always()
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
JAVA_VER: ${{matrix.jdk}}
|
||||
strategy:
|
||||
matrix:
|
||||
jdk: [ 8, 11, 17, 21 ]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
repository: 'apache/dubbo-samples'
|
||||
ref: master
|
||||
- name: "Download test result"
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: samples-test-result-${{matrix.jdk}}
|
||||
path: test/jobs/
|
||||
- name: "Merge test result"
|
||||
run: ./test/scripts/merge-test-results.sh
|
||||
|
||||
integration-test-prepare:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
JOB_COUNT: 5
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
repository: 'apache/dubbo-integration-cases'
|
||||
ref: main
|
||||
- name: "Prepare test list"
|
||||
run: |
|
||||
bash ./test/scripts/prepare-test.sh
|
||||
- name: "Upload test list"
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: integration-test-list
|
||||
path: test/jobs
|
||||
integration-test-job:
|
||||
needs: [build-source, integration-test-prepare]
|
||||
name: "Integration Test on ubuntu-latest (JobId: ${{matrix.job_id}} JavaVer: ${{matrix.jdk}})"
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 90
|
||||
env:
|
||||
JAVA_VER: ${{matrix.jdk}}
|
||||
TEST_CASE_FILE: jobs/testjob_${{matrix.job_id}}.txt
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
jdk: [ 8, 11, 17, 21 ]
|
||||
job_id: [1, 2, 3, 4, 5]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
repository: 'apache/dubbo-integration-cases'
|
||||
ref: main
|
||||
- name: "Cache local Maven repository"
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.m2/repository
|
||||
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}-${{ github.run_id }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
|
||||
${{ runner.os }}-maven-
|
||||
- name: "Restore Dubbo cache"
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.m2/repository/org/apache/dubbo
|
||||
key: ${{ runner.os }}-dubbo-snapshot-${{ github.sha }}-${{ github.run_id }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-dubbo-snapshot-${{ github.sha }}
|
||||
${{ runner.os }}-dubbo-snapshot-
|
||||
- name: "Download test list"
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: integration-test-list
|
||||
path: test/jobs/
|
||||
- name: "Set up JDK ${{matrix.jdk}}"
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: ${{matrix.jdk}}
|
||||
- name: "Init Candidate Versions"
|
||||
run: |
|
||||
DUBBO_VERSION="${{needs.build-source.outputs.version}}"
|
||||
CANDIDATE_VERSIONS="dubbo.version:$DUBBO_VERSION;compiler.version:$DUBBO_VERSION;$CANDIDATE_VERSIONS;dubbo.compiler.version:$DUBBO_VERSION"
|
||||
echo "CANDIDATE_VERSIONS=$CANDIDATE_VERSIONS" >> $GITHUB_ENV
|
||||
- name: "Build test image"
|
||||
run: |
|
||||
cd test && bash ./build-test-image.sh
|
||||
- name: "Run tests"
|
||||
run: cd test && bash ./run-tests.sh
|
||||
- name: "Upload test result"
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: integration-test-result-${{matrix.jdk}}
|
||||
path: test/jobs/*-result*
|
||||
integration-test-result:
|
||||
needs: [integration-test-job]
|
||||
if: always()
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
JAVA_VER: ${{matrix.jdk}}
|
||||
strategy:
|
||||
matrix:
|
||||
jdk: [ 8, 11, 17, 21 ]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
repository: 'apache/dubbo-integration-cases'
|
||||
ref: main
|
||||
- name: "Download test result"
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: integration-test-result-${{matrix.jdk}}
|
||||
path: test/jobs/
|
||||
- name: "Merge test result"
|
||||
run: ./test/scripts/merge-test-results.sh
|
||||
|
||||
error-code-inspecting:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
ref: "3.3"
|
||||
path: "./dubbo"
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
repository: 'apache/dubbo-test-tools'
|
||||
ref: main
|
||||
path: "./dubbo-test-tools"
|
||||
|
||||
- name: "Set up JDK 21"
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: 'zulu'
|
||||
java-version: 21
|
||||
|
||||
- name: "Compile Dubbo (Linux)"
|
||||
run: |
|
||||
cd ${{ github.workspace }}/dubbo
|
||||
./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast -T 2C clean install -DskipTests=true -DskipIntegrationTests=true -Dcheckstyle.skip=true -Dcheckstyle_unix.skip=true -Drat.skip=true -Dmaven.javadoc.skip=true
|
||||
- name: "Run Error Code Inspecting"
|
||||
env:
|
||||
DUBBO_ECI_REPORT_AS_ERROR: true
|
||||
run: |
|
||||
cd ${{ github.workspace }}/dubbo-test-tools/dubbo-error-code-inspector
|
||||
../mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast -T 2C package exec:java -Ddubbo.eci.report-as-error=${DUBBO_ECI_REPORT_AS_ERROR} -Dmaven.test.skip=true -Dmaven.test.skip.exec=true -Ddubbo.eci.path=${{ github.workspace }}/dubbo
|
||||
|
||||
- name: "Upload error code inspection result"
|
||||
# always() should not be used here, since we don't need to handle the 'canceled' situation.
|
||||
if: ${{ success() || failure() }}
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: "error-inspection-result"
|
||||
path: ${{ github.workspace }}/dubbo-test-tools/dubbo-error-code-inspector/error-inspection-result.txt
|
||||
|
||||
native-image-inspecting:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
ref: "3.3"
|
||||
path: "./dubbo"
|
||||
|
||||
- name: "Setup GraalVM environment"
|
||||
uses: graalvm/setup-graalvm@v1
|
||||
with:
|
||||
version: '22.3.0'
|
||||
java-version: '17'
|
||||
components: 'native-image'
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
native-image-job-reports: 'true'
|
||||
|
||||
- name: "Setup Zookeeper environment"
|
||||
run: |
|
||||
wget https://dlcdn.apache.org/zookeeper/zookeeper-3.8.4/apache-zookeeper-3.8.4-bin.tar.gz
|
||||
tar -zxvf apache-zookeeper-3.8.4-bin.tar.gz
|
||||
mv apache-zookeeper-3.8.4-bin/conf/zoo_sample.cfg apache-zookeeper-3.8.4-bin/conf/zoo.cfg
|
||||
apache-zookeeper-3.8.4-bin/bin/zkServer.sh start
|
||||
|
||||
- name: "Check environment"
|
||||
run: |
|
||||
java --version
|
||||
native-image --version
|
||||
|
||||
- name: "Compile Dubbo (Linux)"
|
||||
run: |
|
||||
cd ${{ github.workspace }}/dubbo
|
||||
./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast -T 2C clean install -DskipTests=true -DskipIntegrationTests=true -Dcheckstyle.skip=true -Dcheckstyle_unix.skip=true -Drat.skip=true -Dmaven.javadoc.skip=true
|
||||
|
||||
- name: "Compile and run Dubbo demo for native (Linux)"
|
||||
run: |
|
||||
cd ${{ github.workspace }}/dubbo/dubbo-demo/dubbo-demo-native/dubbo-demo-native-provider
|
||||
${{ github.workspace }}/dubbo/mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast -T 2C clean package -P native -Dmaven.test.skip=true native:compile
|
||||
nohup ./target/dubbo-demo-native-provider &
|
||||
cd ${{ github.workspace }}/dubbo/dubbo-demo/dubbo-demo-native/dubbo-demo-native-consumer
|
||||
${{ github.workspace }}/dubbo/mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast -T 2C clean package -P native -Dmaven.test.skip=true native:compile
|
||||
./target/dubbo-demo-native-consumer
|
||||
|
|
@ -41,7 +41,7 @@ jobs:
|
|||
- uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: 'zulu'
|
||||
java-version: 8
|
||||
java-version: 17
|
||||
- uses: actions/cache@v3
|
||||
name: "Cache local Maven repository"
|
||||
with:
|
||||
|
|
@ -64,7 +64,7 @@ jobs:
|
|||
run: 7z a ${{ github.workspace }}/checkstyle.zip *checkstyle* -r
|
||||
- name: "Upload checkstyle file if failure"
|
||||
if: failure()
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: "checkstyle-file"
|
||||
path: ${{ github.workspace }}/checkstyle.zip
|
||||
|
|
@ -132,7 +132,7 @@ jobs:
|
|||
fail-fast: false
|
||||
matrix:
|
||||
os: [ ubuntu-latest, windows-latest ]
|
||||
jdk: [ 8, 11, 17, 21 ]
|
||||
jdk: [ 17, 19 ]
|
||||
env:
|
||||
DISABLE_FILE_SYSTEM_TEST: true
|
||||
steps:
|
||||
|
|
@ -150,14 +150,6 @@ jobs:
|
|||
restore-keys: |
|
||||
${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
|
||||
${{ runner.os }}-maven-
|
||||
- uses: actions/cache@v3
|
||||
name: "Cache zookeeper binary archive"
|
||||
id: "cache-zookeeper"
|
||||
with:
|
||||
path: ${{ github.workspace }}/.tmp/zookeeper
|
||||
key: zookeeper-${{ runner.os }}-${{ env.ZOOKEEPER_VERSION }}
|
||||
restore-keys: |
|
||||
zookeeper-${{ runner.os }}-
|
||||
- name: "Test with Maven with Integration Tests"
|
||||
timeout-minutes: 70
|
||||
if: ${{ startsWith( matrix.os, 'ubuntu') }}
|
||||
|
|
@ -166,6 +158,8 @@ jobs:
|
|||
timeout-minutes: 90
|
||||
if: ${{ startsWith( matrix.os, 'windows') }}
|
||||
run: ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean test verify -Pjacoco -D"http.keepAlive=false" -D"maven.wagon.http.pool=false" -D"maven.wagon.httpconnectionManager.ttlSeconds=120" -D"maven.wagon.http.retryHandler.count=5" -DskipTests=false -DskipIntegrationTests=true -D"checkstyle.skip=false" -D"checkstyle_unix.skip=true" -D"rat.skip=false" -D"maven.javadoc.skip=true" -D"embeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper"
|
||||
- name: "Upload coverage to Codecov"
|
||||
uses: codecov/codecov-action@v3
|
||||
|
||||
unit-test-fastjson2:
|
||||
needs: [build-source, unit-test-prepare]
|
||||
|
|
@ -175,7 +169,7 @@ jobs:
|
|||
fail-fast: false
|
||||
matrix:
|
||||
os: [ ubuntu-latest, windows-latest ]
|
||||
jdk: [ 8, 11, 17, 21 ]
|
||||
jdk: [ 17, 19 ]
|
||||
env:
|
||||
DISABLE_FILE_SYSTEM_TEST: true
|
||||
DUBBO_DEFAULT_SERIALIZATION: fastjson2
|
||||
|
|
@ -195,128 +189,16 @@ jobs:
|
|||
restore-keys: |
|
||||
${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
|
||||
${{ runner.os }}-maven-
|
||||
- uses: actions/cache@v3
|
||||
name: "Cache zookeeper binary archive"
|
||||
id: "cache-zookeeper"
|
||||
with:
|
||||
path: ${{ github.workspace }}/.tmp/zookeeper
|
||||
key: zookeeper-${{ runner.os }}-${{ env.ZOOKEEPER_VERSION }}
|
||||
restore-keys: |
|
||||
zookeeper-${{ runner.os }}-
|
||||
- name: "Test with Maven with Integration Tests on JDK 8"
|
||||
timeout-minutes: 70
|
||||
if: ${{ startsWith( matrix.os, 'ubuntu') && matrix.jdk == '8' }}
|
||||
run: ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean test verify -Pjacoco,'!jdk15ge' -Dmaven.wagon.httpconnectionManager.ttlSeconds=120 -Dmaven.wagon.http.retryHandler.count=5 -DskipTests=false -DskipIntegrationTests=false -Dcheckstyle.skip=false -Dcheckstyle_unix.skip=false -Drat.skip=false -Dmaven.javadoc.skip=true -DembeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper
|
||||
- name: "Test with Maven without Integration Tests on JDK 8"
|
||||
timeout-minutes: 90
|
||||
if: ${{ startsWith( matrix.os, 'windows') && matrix.jdk == '8' }}
|
||||
run: ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean test verify -P"jacoco,'!jdk15ge'" -D"http.keepAlive=false" -D"maven.wagon.http.pool=false" -D"maven.wagon.httpconnectionManager.ttlSeconds=120" -D"maven.wagon.http.retryHandler.count=5" -DskipTests=false -DskipIntegrationTests=true -D"checkstyle.skip=false" -D"checkstyle_unix.skip=true" -D"rat.skip=false" -D"maven.javadoc.skip=true" -D"embeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper"
|
||||
- name: "Test with Maven with Integration Tests"
|
||||
timeout-minutes: 70
|
||||
if: ${{ startsWith( matrix.os, 'ubuntu') && matrix.jdk != '8' }}
|
||||
run: ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean test verify -Pjacoco,jdk15ge-simple,'!jdk15ge' -Dmaven.wagon.httpconnectionManager.ttlSeconds=120 -Dmaven.wagon.http.retryHandler.count=5 -DskipTests=false -DskipIntegrationTests=false -Dcheckstyle.skip=false -Dcheckstyle_unix.skip=false -Drat.skip=false -Dmaven.javadoc.skip=true -DembeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper
|
||||
if: ${{ startsWith( matrix.os, 'ubuntu') }}
|
||||
run: ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean test verify -Pjacoco -Dmaven.wagon.httpconnectionManager.ttlSeconds=120 -Dmaven.wagon.http.retryHandler.count=5 -DskipTests=false -DskipIntegrationTests=false -Dcheckstyle.skip=false -Dcheckstyle_unix.skip=false -Drat.skip=false -Dmaven.javadoc.skip=true -DembeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper
|
||||
- name: "Test with Maven without Integration Tests"
|
||||
timeout-minutes: 90
|
||||
if: ${{ startsWith( matrix.os, 'windows') && matrix.jdk != '8' }}
|
||||
run: ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean test verify -P"jacoco,jdk15ge-simple,'!jdk15ge'" -D"http.keepAlive=false" -D"maven.wagon.http.pool=false" -D"maven.wagon.httpconnectionManager.ttlSeconds=120" -D"maven.wagon.http.retryHandler.count=5" -DskipTests=false -DskipIntegrationTests=true -D"checkstyle.skip=false" -D"checkstyle_unix.skip=true" -D"rat.skip=false" -D"maven.javadoc.skip=true" -D"embeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper"
|
||||
|
||||
samples-test-prepare:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
JOB_COUNT: 5
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
repository: 'apache/dubbo-samples'
|
||||
ref: master
|
||||
- name: "Prepare test list"
|
||||
run: |
|
||||
bash ./test/scripts/prepare-test.sh
|
||||
- name: "Upload test list"
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: samples-test-list
|
||||
path: test/jobs
|
||||
samples-test-job:
|
||||
needs: [build-source, samples-test-prepare]
|
||||
name: "Samples Test on ubuntu-latest (JobId: ${{matrix.job_id}} JavaVer: ${{matrix.jdk}})"
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 90
|
||||
env:
|
||||
JAVA_VER: ${{matrix.jdk}}
|
||||
TEST_CASE_FILE: jobs/testjob_${{matrix.job_id}}.txt
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
jdk: [ 8, 11, 17, 21 ]
|
||||
job_id: [1, 2, 3, 4, 5]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
repository: 'apache/dubbo-samples'
|
||||
ref: master
|
||||
- name: "Cache local Maven repository"
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.m2/repository
|
||||
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}-${{ github.run_id }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
|
||||
${{ runner.os }}-maven-
|
||||
- name: "Restore Dubbo cache"
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.m2/repository/org/apache/dubbo
|
||||
key: ${{ runner.os }}-dubbo-snapshot-${{ github.sha }}-${{ github.run_id }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-dubbo-snapshot-${{ github.sha }}
|
||||
${{ runner.os }}-dubbo-snapshot-
|
||||
- name: "Download test list"
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: samples-test-list
|
||||
path: test/jobs/
|
||||
- name: "Set up JDK ${{matrix.jdk}}"
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: ${{matrix.jdk}}
|
||||
- name: "Init Candidate Versions"
|
||||
run: |
|
||||
DUBBO_VERSION="${{needs.build-source.outputs.version}}"
|
||||
CANDIDATE_VERSIONS="dubbo.version:$DUBBO_VERSION;compiler.version:$DUBBO_VERSION;$CANDIDATE_VERSIONS;dubbo.compiler.version:$DUBBO_VERSION"
|
||||
echo "CANDIDATE_VERSIONS=$CANDIDATE_VERSIONS" >> $GITHUB_ENV
|
||||
- name: "Build test image"
|
||||
run: |
|
||||
cd test && bash ./build-test-image.sh
|
||||
- name: "Run tests"
|
||||
run: cd test && bash ./run-tests.sh
|
||||
- name: "Upload test result"
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: samples-test-result-${{matrix.jdk}}
|
||||
path: test/jobs/*-result*
|
||||
samples-test-result:
|
||||
needs: [samples-test-job]
|
||||
if: always()
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
JAVA_VER: ${{matrix.jdk}}
|
||||
strategy:
|
||||
matrix:
|
||||
jdk: [ 8, 11, 17, 21 ]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
repository: 'apache/dubbo-samples'
|
||||
ref: master
|
||||
- name: "Download test result"
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: samples-test-result-${{matrix.jdk}}
|
||||
path: test/jobs/
|
||||
- name: "Merge test result"
|
||||
run: ./test/scripts/merge-test-results.sh
|
||||
if: ${{ startsWith( matrix.os, 'windows') }}
|
||||
run: ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean test verify -Pjacoco -D"http.keepAlive=false" -D"maven.wagon.http.pool=false" -D"maven.wagon.httpconnectionManager.ttlSeconds=120" -D"maven.wagon.http.retryHandler.count=5" -DskipTests=false -DskipIntegrationTests=true -D"checkstyle.skip=false" -D"checkstyle_unix.skip=true" -D"rat.skip=false" -D"maven.javadoc.skip=true" -D"embeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper"
|
||||
- name: "Upload coverage to Codecov"
|
||||
uses: codecov/codecov-action@v3
|
||||
|
||||
integration-test-prepare:
|
||||
runs-on: ubuntu-latest
|
||||
|
|
@ -325,19 +207,20 @@ jobs:
|
|||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
repository: 'apache/dubbo-integration-cases'
|
||||
ref: main
|
||||
repository: 'apache/dubbo-samples'
|
||||
ref: master
|
||||
- name: "Prepare test list"
|
||||
run: |
|
||||
bash ./test/scripts/prepare-test.sh
|
||||
- name: "Upload test list"
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: integration-test-list
|
||||
name: test-list
|
||||
path: test/jobs
|
||||
|
||||
integration-test-job:
|
||||
needs: [build-source, integration-test-prepare]
|
||||
name: "Integration Test on ubuntu-latest (JobId: ${{matrix.job_id}} JavaVer: ${{matrix.jdk}})"
|
||||
name: "Integration Test on ubuntu-latest (JobId: ${{matrix.job_id}})"
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 90
|
||||
env:
|
||||
|
|
@ -346,13 +229,13 @@ jobs:
|
|||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
jdk: [ 8, 11, 17, 21 ]
|
||||
jdk: [ 8, 11, 17, 19 ]
|
||||
job_id: [1, 2, 3, 4, 5]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
repository: 'apache/dubbo-integration-cases'
|
||||
ref: main
|
||||
repository: 'apache/dubbo-samples'
|
||||
ref: master
|
||||
- name: "Cache local Maven repository"
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
|
|
@ -372,7 +255,7 @@ jobs:
|
|||
- name: "Download test list"
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: integration-test-list
|
||||
name: test-list
|
||||
path: test/jobs/
|
||||
- name: "Set up JDK ${{matrix.jdk}}"
|
||||
uses: actions/setup-java@v1
|
||||
|
|
@ -392,8 +275,9 @@ jobs:
|
|||
if: always()
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: integration-test-result-${{matrix.jdk}}
|
||||
name: test-result-${{matrix.jdk}}
|
||||
path: test/jobs/*-result*
|
||||
|
||||
integration-test-result:
|
||||
needs: [integration-test-job]
|
||||
if: always()
|
||||
|
|
@ -402,16 +286,16 @@ jobs:
|
|||
JAVA_VER: ${{matrix.jdk}}
|
||||
strategy:
|
||||
matrix:
|
||||
jdk: [ 8, 11, 17, 21 ]
|
||||
jdk: [ 8, 11, 17, 19 ]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
repository: 'apache/dubbo-integration-cases'
|
||||
ref: main
|
||||
repository: 'apache/dubbo-samples'
|
||||
ref: master
|
||||
- name: "Download test result"
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: integration-test-result-${{matrix.jdk}}
|
||||
name: test-result-${{matrix.jdk}}
|
||||
path: test/jobs/
|
||||
- name: "Merge test result"
|
||||
run: ./test/scripts/merge-test-results.sh
|
||||
|
|
@ -429,10 +313,10 @@ jobs:
|
|||
ref: main
|
||||
path: "./dubbo-test-tools"
|
||||
|
||||
- name: "Set up JDK 21"
|
||||
- name: "Set up JDK 17"
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
java-version: 21
|
||||
java-version: 17
|
||||
distribution: 'zulu'
|
||||
|
||||
- name: "Compile Dubbo (Linux)"
|
||||
|
|
@ -449,7 +333,7 @@ jobs:
|
|||
- name: "Upload error code inspection result"
|
||||
# always() should not be used here, since we don't need to handle the 'canceled' situation.
|
||||
if: ${{ success() || failure() }}
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: "error-inspection-result"
|
||||
path: ${{ github.workspace }}/dubbo-test-tools/dubbo-error-code-inspector/error-inspection-result.txt
|
||||
|
|
@ -472,10 +356,10 @@ jobs:
|
|||
|
||||
- name: "Setup Zookeeper environment"
|
||||
run: |
|
||||
wget https://dlcdn.apache.org/zookeeper/zookeeper-3.8.4/apache-zookeeper-3.8.4-bin.tar.gz
|
||||
tar -zxvf apache-zookeeper-3.8.4-bin.tar.gz
|
||||
mv apache-zookeeper-3.8.4-bin/conf/zoo_sample.cfg apache-zookeeper-3.8.4-bin/conf/zoo.cfg
|
||||
apache-zookeeper-3.8.4-bin/bin/zkServer.sh start
|
||||
wget https://dlcdn.apache.org/zookeeper/zookeeper-3.7.1/apache-zookeeper-3.7.1-bin.tar.gz
|
||||
tar -zxvf apache-zookeeper-3.7.1-bin.tar.gz
|
||||
mv apache-zookeeper-3.7.1-bin/conf/zoo_sample.cfg apache-zookeeper-3.7.1-bin/conf/zoo.cfg
|
||||
apache-zookeeper-3.7.1-bin/bin/zkServer.sh start
|
||||
|
||||
- name: "Check environment"
|
||||
run: |
|
||||
|
|
|
|||
|
|
@ -11,8 +11,6 @@ target/
|
|||
.settings/
|
||||
.project
|
||||
.classpath
|
||||
.externalToolBuilders
|
||||
maven-eclipse.xml
|
||||
|
||||
# idea ignore
|
||||
.idea/
|
||||
|
|
@ -52,6 +50,3 @@ dubbo-demo/dubbo-demo-triple/build/*
|
|||
|
||||
.git.exec.error
|
||||
|
||||
# log files generated by testcase.
|
||||
dubbo-rpc/dubbo-rpc-api/custom-access.log*
|
||||
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ header:
|
|||
- '**/*.fc'
|
||||
- '**/*.javascript'
|
||||
- '**/*.properties'
|
||||
- '**/*.thrift'
|
||||
- '**/*.sh'
|
||||
- '**/*.bat'
|
||||
- '**/*.md'
|
||||
|
|
@ -95,11 +96,13 @@ header:
|
|||
- 'dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/MatchingGroupIdFilter.java'
|
||||
- 'dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/RunArguments.java'
|
||||
- 'dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/RunProcess.java'
|
||||
- 'dubbo-native/src/main/java/org/apache/dubbo/aot/generate/BasicJsonWriter.java'
|
||||
- 'dubbo-native/src/main/java/org/apache/dubbo/aot/generate/ExecutableMode.java'
|
||||
- 'dubbo-native/src/main/java/org/apache/dubbo/aot/generate/MemberCategory.java'
|
||||
- 'dubbo-plugin/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/BasicJsonWriter.java'
|
||||
- 'dubbo-plugin/dubbo-native/src/main/java/org/apache/dubbo/aot/api/ExecutableMode.java'
|
||||
- 'dubbo-plugin/dubbo-native/src/main/java/org/apache/dubbo/aot/api/MemberCategory.java'
|
||||
- 'dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/aggregate/DubboMergingDigest.java'
|
||||
- 'dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/aggregate/DubboAbstractTDigest.java'
|
||||
- 'dubbo-common/src/main/java/org/apache/dubbo/common/logger/helpers/FormattingTuple.java'
|
||||
- 'dubbo-common/src/main/java/org/apache/dubbo/common/logger/helpers/MessageFormatter.java'
|
||||
|
||||
comment: on-failure
|
||||
|
||||
|
|
@ -198,10 +201,26 @@ dependency:
|
|||
license: Apache-2.0
|
||||
- name: org.sonatype.plexus:plexus-cipher
|
||||
license: Apache-2.0
|
||||
- name: com.alibaba.csp:sentinel-apache-dubbo3-adapter
|
||||
license: Apache-2.0
|
||||
- name: com.alibaba.csp:sentinel-transport-simple-http
|
||||
license: Apache-2.0
|
||||
- name: com.alibaba.csp:sentinel-transport-common
|
||||
license: Apache-2.0
|
||||
- name: com.alibaba.csp:sentinel-datasource-extension
|
||||
license: Apache-2.0
|
||||
- name: com.alibaba.csp:sentinel-core
|
||||
license: Apache-2.0
|
||||
- name: com.google.protobuf:protobuf-java
|
||||
license: BSD 3-clause
|
||||
- name: com.google.protobuf:protobuf-java-util
|
||||
license: BSD 3-clause
|
||||
- name: org.antlr:antlr4
|
||||
license: BSD 3-clause
|
||||
- name: org.antlr:antlr-runtime
|
||||
license: BSD 3-clause
|
||||
- name: org.antlr:ST4
|
||||
license: BSD 3-clause
|
||||
# multi license
|
||||
- name: org.javassist:javassist
|
||||
license: Apache-2.0
|
||||
|
|
|
|||
2
NOTICE
2
NOTICE
|
|
@ -1,5 +1,5 @@
|
|||
Apache Dubbo
|
||||
Copyright 2018-2024 The Apache Software Foundation
|
||||
Copyright 2018-2023 The Apache Software Foundation
|
||||
|
||||
This product includes software developed at
|
||||
The Apache Software Foundation (http://www.apache.org/).
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
## What is the purpose of the change?
|
||||
|
||||
|
||||
## Checklist
|
||||
- [x] Make sure there is a [GitHub_issue](https://github.com/apache/dubbo/issues) field for the change.
|
||||
- [x] Write a pull request description that is detailed enough to understand what the pull request does, how, and why.
|
||||
- [x] Write necessary unit-test to verify your logic correction. If the new feature or significant change is committed, please remember to add sample in [dubbo samples](https://github.com/apache/dubbo-samples) project.
|
||||
- [x] Make sure gitHub actions can pass. [Why the workflow is failing and how to fix it?](./CONTRIBUTING.md)
|
||||
286
README.md
286
README.md
|
|
@ -6,267 +6,73 @@
|
|||

|
||||
[](http://isitmaintained.com/project/apache/dubbo "Average time to resolve an issue")
|
||||
[](http://isitmaintained.com/project/apache/dubbo "Percentage of issues still open")
|
||||
[](https://twitter.com/intent/tweet?text=Apache%20Dubbo%20is%20a%20high-performance%2C%20java%20based%2C%20open%20source%20RPC%20framework.&url=http://dubbo.apache.org/&via=ApacheDubbo&hashtags=rpc,java,dubbo,micro-service)
|
||||
[](https://twitter.com/intent/follow?screen_name=ApacheDubbo)
|
||||
[](https://gitter.im/alibaba/dubbo?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
||||
|
||||
Apache Dubbo is a high-performance, Java-based open-source RPC framework. Please visit the [official site](http://dubbo.apache.org) for the quick start guide and documentation, as well as the [wiki](https://github.com/apache/dubbo/wiki) for news, FAQ, and release notes.
|
||||
Apache Dubbo is an easy-to-use Web and RPC framework that provides multiple
|
||||
language implementations(Java, [Go](https://github.com/apache/dubbo-go), [Rust](https://github.com/apache/dubbo-rust), [Node.js](https://github.com/apache/dubbo-js), [Web](https://github.com/apache/dubbo-js)) for communication, service discovery, traffic management,
|
||||
observability, security, tools, and best practices for building enterprise-ready microservices.
|
||||
|
||||
We are now collecting Dubbo user info to help us to improve Dubbo further. Kindly support us by providing your usage information on [Wanted: who's using dubbo](https://github.com/apache/dubbo/discussions/13842), thanks :)
|
||||
Visit [the official website](https://dubbo.apache.org/) for more information.
|
||||
|
||||
## Architecture
|
||||
|
||||

|
||||
|
||||
## Features
|
||||
|
||||
* Transparent interface based RPC
|
||||
* Intelligent load balancing
|
||||
* Automatic service registration and discovery
|
||||
* High extensibility
|
||||
* Runtime traffic routing
|
||||
* Visualized service governance
|
||||
* Consumer and provider communicate with each other using RPC protocol like triple, tcp, rest, etc.
|
||||
* Consumers automatically trace provider instances registered in registries(Zookeeper, Nacos) and distribute traffic among them by following traffic strategies.
|
||||
* Rich features for monitoring and managing the cluster with dynamic configuration, metrics, tracing, security, and visualized console.
|
||||
|
||||
## Getting started
|
||||
Follow the instructions below to learn how to:
|
||||
|
||||
The following code snippet comes from [Dubbo Samples](https://github.com/apache/dubbo-samples.git). You may clone the sample project and step into the `dubbo-samples-api` subdirectory before proceeding.
|
||||
### Programming with lightweight RPC API
|
||||
[5 minutes step-by-step guide](https://dubbo.apache.org/zh-cn/overview/quickstart/rpc/java)
|
||||
|
||||
```bash
|
||||
git clone https://github.com/apache/dubbo-samples.git
|
||||
cd dubbo-samples/1-basic/dubbo-samples-api
|
||||
```
|
||||
|
||||
There's a [README](https://github.com/apache/dubbo-samples/blob/389cd612f1ea57ee6e575005b32f195c442c35a2/1-basic/dubbo-samples-api/README.md) file under `dubbo-samples-api` directory. We recommend referencing the samples in that directory by following the below-mentioned instructions:
|
||||
|
||||
### Maven dependency
|
||||
|
||||
```xml
|
||||
<properties>
|
||||
<dubbo.version>3.2.13-SNAPSHOT</dubbo.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo</artifactId>
|
||||
<version>${dubbo.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo-dependencies-zookeeper</artifactId>
|
||||
<version>${dubbo.version}</version>
|
||||
<type>pom</type>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
```
|
||||
|
||||
### Define service interfaces
|
||||
|
||||
```java
|
||||
package org.apache.dubbo.samples.api;
|
||||
|
||||
public interface GreetingsService {
|
||||
String sayHi(String name);
|
||||
}
|
||||
```
|
||||
|
||||
*See [api/GreetingsService.java](https://github.com/apache/dubbo-samples/blob/389cd612f1ea57ee6e575005b32f195c442c35a2/1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/api/GreetingsService.java) on GitHub.*
|
||||
|
||||
### Implement service interface for the provider
|
||||
|
||||
```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;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
*See [provider/GreetingsServiceImpl.java](https://github.com/apache/dubbo-samples/blob/389cd612f1ea57ee6e575005b32f195c442c35a2/1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/provider/GreetingsServiceImpl.java) on GitHub.*
|
||||
|
||||
### Start service provider
|
||||
|
||||
```java
|
||||
package org.apache.dubbo.samples.provider;
|
||||
Dubbo supports building RPC services with only a few lines of code while depending only on a lightweight SDK (<10MB). The protocol on the wire can be [Triple](https://dubbo.apache.org/zh-cn/overview/reference/protocols/triple/)(fully gRPC compatible and HTTP-friendly), Dubbo2(TCP), REST, or any protocol of your choice.
|
||||
|
||||
|
||||
import org.apache.dubbo.config.ApplicationConfig;
|
||||
import org.apache.dubbo.config.RegistryConfig;
|
||||
import org.apache.dubbo.config.ServiceConfig;
|
||||
import org.apache.dubbo.samples.api.GreetingsService;
|
||||
### Building a microservice application with Spring Boot
|
||||
[5 minutes step-by-step guide](https://dubbo.apache.org/zh-cn/overview/quickstart/microservice)
|
||||
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
It's highly recommended to start your microservice application with the Spring Boot Starter `dubbo-spring-boot-starter` provided by Dubbo. With only a single dependency and yaml file, and optionally a bunch of other useful spring boot starters, you can enable all of the Dubo features like service discovery, observability, tracing, etc.
|
||||
|
||||
public class Application {
|
||||
private static String zookeeperHost = System.getProperty("zookeeper.address", "127.0.0.1");
|
||||
Next, learn how to [deploy](https://dubbo.apache.org/zh-cn/overview/tasks/deploy/), [monitor](https://dubbo.apache.org/zh-cn/overview/tasks/observability/), and [manage the traffic](https://dubbo.apache.org/zh-cn/overview/tasks/traffic-management/) of your Dubbo application and cluster.
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
ServiceConfig<GreetingsService> service = new ServiceConfig<>();
|
||||
service.setApplication(new ApplicationConfig("first-dubbo-provider"));
|
||||
service.setRegistry(new RegistryConfig("zookeeper://" + zookeeperHost + ":2181"));
|
||||
service.setInterface(GreetingsService.class);
|
||||
service.setRef(new GreetingsServiceImpl());
|
||||
service.export();
|
||||
## More Features
|
||||
Get more details by visiting the links below to get your hands dirty with some well-designed tasks on our website.
|
||||
|
||||
System.out.println("dubbo service started");
|
||||
new CountDownLatch(1).await();
|
||||
}
|
||||
}
|
||||
```
|
||||
* [Launch a Dubbo project](https://dubbo.apache.org/zh-cn/overview/tasks/develop/template/)
|
||||
* [RPC protocols](https://dubbo.apache.org/zh-cn/overview/core-features/protocols/)
|
||||
* [Traffic management](https://dubbo.apache.org/zh-cn/overview/core-features/traffic/)
|
||||
* [Service discovery](https://dubbo.apache.org/zh-cn/overview/core-features/service-discovery/)
|
||||
* [Observability](https://dubbo.apache.org/zh-cn/overview/core-features/observability/)
|
||||
* [Extensibility](https://dubbo.apache.org/zh-cn/overview/core-features/extensibility/)
|
||||
* [Security](https://dubbo.apache.org/zh-cn/overview/core-features/security/)
|
||||
* [Visualized console and control plane](https://dubbo.apache.org/zh-cn/overview/reference/admin/)
|
||||
* [Kubernetes and Service mesh](https://dubbo.apache.org/zh-cn/overview/core-features/service-mesh/)
|
||||
|
||||
*See [provider/Application.java](https://github.com/apache/dubbo-samples/blob/389cd612f1ea57ee6e575005b32f195c442c35a2/1-basic/dubbo-samples-spring-xml/src/main/java/org/apache/dubbo/samples/provider/Application.java) on GitHub.*
|
||||
## Which Dubbo version should I use?
|
||||
| **Dubbo3** | **JDK** | **Dependencies** | **Description** |
|
||||
| --- | --- | --- | --- |
|
||||
| 3.3.0-beta| 1.8 ~ 17 | [dependency list](https://github.com/apache/dubbo/blob/3.3/dubbo-dependencies-bom/pom.xml#L94) | **- Unstable version** <br/> **- Features** <br/> - Triple - gRPC and cURL compatible.<br/> - Rest-style programming support.<br/> - Spring Boot Starters. |
|
||||
| 3.2.5 | 1.8 ~ 17 | [dependency list](https://github.com/apache/dubbo/blob/dubbo-3.2.5/dubbo-dependencies-bom/pom.xml#L94) | **- Stable version (active)** <br/> **- Features** <br/> - Out-of-box metrics and tracing support.<br/> - Threadpool Isolation<br/> - 30% performance<br/> - Native Image|
|
||||
| 3.1.11 | 1.8 ~ 11 | [dependency list](https://github.com/apache/dubbo/blob/dubbo-3.2.11/dubbo-dependencies-bom/pom.xml#L94) | **Stable version (not active)** |
|
||||
|
||||
### Build and run the provider
|
||||
| **Dubbo2** | **JDK** | **Dependencies** | **Description** |
|
||||
| --- | --- | --- | --- |
|
||||
| 2.7.23 | 1.8 | [dependency list](https://github.com/apache/dubbo/blob/dubbo-2.7.23/dubbo-dependencies-bom/pom.xml#L92) | EOL |
|
||||
| 2.6.x, 2.5.x | 1.6 ~ 1.7 | | EOL |
|
||||
|
||||
```bash
|
||||
mvn clean package
|
||||
mvn -Djava.net.preferIPv4Stack=true -Dexec.mainClass=org.apache.dubbo.samples.provider.Application exec:java
|
||||
```
|
||||
|
||||
### Call remote service in the consumer
|
||||
|
||||
```java
|
||||
package org.apache.dubbo.samples.client;
|
||||
|
||||
|
||||
import org.apache.dubbo.config.ApplicationConfig;
|
||||
import org.apache.dubbo.config.ReferenceConfig;
|
||||
import org.apache.dubbo.config.RegistryConfig;
|
||||
import org.apache.dubbo.samples.api.GreetingsService;
|
||||
|
||||
public class Application {
|
||||
private static String zookeeperHost = System.getProperty("zookeeper.address", "127.0.0.1");
|
||||
|
||||
public static void main(String[] args) {
|
||||
ReferenceConfig<GreetingsService> reference = new ReferenceConfig<>();
|
||||
reference.setApplication(new ApplicationConfig("first-dubbo-consumer"));
|
||||
reference.setRegistry(new RegistryConfig("zookeeper://" + zookeeperHost + ":2181"));
|
||||
reference.setInterface(GreetingsService.class);
|
||||
GreetingsService service = reference.get();
|
||||
String message = service.sayHi("dubbo");
|
||||
System.out.println(message);
|
||||
}
|
||||
}
|
||||
```
|
||||
*See [client/Application.java](https://github.com/apache/dubbo-samples/blob/389cd612f1ea57ee6e575005b32f195c442c35a2/1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/client/Application.java) on GitHub.*
|
||||
|
||||
### Build and run the consumer
|
||||
|
||||
```bash
|
||||
mvn clean package
|
||||
mvn -Djava.net.preferIPv4Stack=true -Dexec.mainClass=org.apache.dubbo.samples.client.Application exec:java
|
||||
```
|
||||
|
||||
The consumer will print out `hi, dubbo` on the screen.
|
||||
|
||||
|
||||
### Next steps
|
||||
|
||||
* [Your first Dubbo application](https://dubbo.apache.org/en/blog/2018/08/07/dubbo-101/) - A 101 tutorial to reveal more details, with the same code above.
|
||||
* [Dubbo user manual](https://dubbo.apache.org/en/overview/what/) - How to use Dubbo and all its features.
|
||||
* [Dubbo developer guide](https://dubbo.apache.org/en/docs3-v2/java-sdk/) - How to involve in Dubbo development.
|
||||
* [Dubbo admin manual](https://dubbo.apache.org/en/docs/v2.7/admin/ops/) - How to admin and manage Dubbo services.
|
||||
|
||||
## Building
|
||||
|
||||
If you want to try out the cutting-edge features, you can build with the following commands. (Java 1.8 is needed to build the master branch)
|
||||
|
||||
```
|
||||
mvn clean install
|
||||
```
|
||||
|
||||
## Recommended Test Environment
|
||||
To avoid intermittent test failures (i.e., flaky tests), it is recommended to have a machine or virtual machine with the following specifications:
|
||||
|
||||
* Minimum of 2CPUs.
|
||||
* Minimum of 2Gb of RAM.
|
||||
|
||||
### How does the Dubbo Community collaborate?
|
||||
|
||||
The Dubbo Community primarily communicates on GitHub through issues, discussions, and pull requests.
|
||||
|
||||
- Issues: We use issues to track bugs and tasks. Any **work-related** item is associated with an issue.
|
||||
- Discussions: We use discussions for questions, early proposals, and announcements. Any **idea-related** item is associated with a discussion.
|
||||
- Pull Requests: We use pull requests to merge a set of changes from contributors into Dubbo.
|
||||
|
||||
We have also implemented [a project board](https://github.com/orgs/apache/projects/337) to monitor all the items.
|
||||
|
||||
Any essential changes should be discussed on the mailing list before they happen.
|
||||
|
||||
### Seeking for help
|
||||
|
||||
If you have questions such as:
|
||||
|
||||
- What is Dubbo?
|
||||
- How do I use Dubbo?
|
||||
- Why did an unexpected result occur?
|
||||
|
||||
Please start a discussion at https://github.com/apache/dubbo/discussions.
|
||||
|
||||
However, if you encounter the following situations:
|
||||
|
||||
- You're certain there's a bug that Dubbo needs to fix,
|
||||
- You believe a feature could be enhanced,
|
||||
- You have a detailed proposal for improving Dubbo,
|
||||
|
||||
Please open an issue at https://github.com/apache/dubbo/issues.
|
||||
|
||||
To ask effective questions, we recommend reading **[How To Ask Questions The Smart Way](https://github.com/selfteaching/How-To-Ask-Questions-The-Smart-Way/blob/master/How-To-Ask-Questions-The-Smart-Way.md)** first.
|
||||
|
||||
### Contribution
|
||||
|
||||
- Browse the "help wanted" tasks in the [Dubbo project board](https://github.com/orgs/apache/projects/337).
|
||||
- Participate in discussions on the mailing list. See the subscription [guide](https://github.com/apache/dubbo/wiki/Mailing-list-subscription-guide).
|
||||
- Respond to queries in the [discussions](https://github.com/apache/dubbo/issues).
|
||||
- Resolve bugs reported in [issues](https://github.com/apache/dubbo/issues) and send us a pull request.
|
||||
- Review existing [pull requests](https://github.com/apache/dubbo/pulls).
|
||||
- Enhance the [website](https://github.com/apache/dubbo-website). We typically need:
|
||||
- Blog posts
|
||||
- Translations for documentation
|
||||
- Use cases showcasing Dubbo integration in enterprise systems.
|
||||
- Improve the [dubbo-admin](https://github.com/apache/dubbo-admin).
|
||||
- Contribute to the projects listed in the [ecosystem](https://github.com/apache/?q=dubbo&type=all&language=&sort=).
|
||||
- Any other forms of contribution not listed above are also welcome.
|
||||
- If you're interested in contributing, please send an email to [dev@dubbo.apache.org](mailto:dev@dubbo.apache.org) to let us know!
|
||||
|
||||
For further details, please refer our [guide](https://github.com/apache/dubbo/blob/master/CONTRIBUTING.md) about how to contribute Dubbo.
|
||||
|
||||
## Reporting bugs
|
||||
|
||||
Please follow the [template](https://github.com/apache/dubbo/issues/new?template=dubbo-issue-report-template.md) for reporting any issues.
|
||||
|
||||
## Reporting a security vulnerability
|
||||
|
||||
Please report security vulnerabilities to [us](mailto:security@dubbo.apache.org) privately.
|
||||
## Contributing
|
||||
See [CONTRIBUTING](https://github.com/apache/dubbo/blob/master/CONTRIBUTING.md) for details on submitting patches and the contribution workflow.
|
||||
|
||||
## Contact
|
||||
|
||||
* Mailing list:
|
||||
* dev list: for dev/user discussion. [subscribe](mailto:dev-subscribe@dubbo.apache.org), [unsubscribe](mailto:dev-unsubscribe@dubbo.apache.org), [archive](https://lists.apache.org/list.html?dev@dubbo.apache.org), [guide](https://github.com/apache/dubbo/wiki/Mailing-list-subscription-guide)
|
||||
|
||||
* Bugs: [Issues](https://github.com/apache/dubbo/issues/new?template=dubbo-issue-report-template.md)
|
||||
* Gitter: [Gitter channel](https://gitter.im/alibaba/dubbo)
|
||||
* WeChat: apachedubbo
|
||||
* DingTalk group: 37290003945
|
||||
* Mailing list: [guide](https://dubbo.apache.org/zh-cn/contact/)
|
||||
* Twitter: [@ApacheDubbo](https://twitter.com/ApacheDubbo)
|
||||
|
||||
## Dubbo ecosystem
|
||||
|
||||
* [Dubbo Ecosystem Entry](https://github.com/apache?utf8=%E2%9C%93&q=dubbo&type=&language=) - A GitHub group `dubbo` to gather all Dubbo relevant projects not appropriate in [apache](https://github.com/apache) group yet
|
||||
* [Dubbo Website](https://github.com/apache/dubbo-website) - Apache Dubbo official website
|
||||
* [Dubbo Samples](https://github.com/apache/dubbo-samples) - samples for Apache Dubbo
|
||||
* [Dubbo Admin](https://github.com/apache/dubbo-admin) - The reference implementation for Dubbo admin
|
||||
* [Dubbo Awesome](https://github.com/apache/dubbo-awesome) - Dubbo's slides and video links in Meetup
|
||||
|
||||
#### Language
|
||||
|
||||
* [Go](https://github.com/apache/dubbo-go) (recommended)
|
||||
* [Rust](https://github.com/apache/dubbo-rust)
|
||||
* [Node.js](https://github.com/apache/dubbo-js)
|
||||
* [Python](https://github.com/dubbo/py-client-for-apache-dubbo)
|
||||
* [PHP](https://github.com/apache/dubbo-php-framework)
|
||||
* [Erlang](https://github.com/apache/dubbo-erlang)
|
||||
* Security issues: please mail to [us](mailto:security@dubbo.apache.org) privately.
|
||||
|
||||
## License
|
||||
|
||||
Apache Dubbo software is licensed under the Apache License Version 2.0. See the [LICENSE](https://github.com/apache/dubbo/blob/master/LICENSE) file for details.
|
||||
Apache Dubbo is licensed under the Apache License Version 2.0. See the [LICENSE](https://github.com/apache/dubbo/blob/master/LICENSE) file for details.
|
||||
|
|
|
|||
12
SECURITY.md
12
SECURITY.md
|
|
@ -5,15 +5,13 @@
|
|||
Below is a table that shows versions that we accept security fixes.
|
||||
|
||||
| Version | Supported |
|
||||
|---------| ------------------ |
|
||||
| 3.3.x | :white_check_mark: |
|
||||
| 3.2.x | :white_check_mark: |
|
||||
| 3.1.x | :white_check_mark: |
|
||||
| 3.0.x | :x: |
|
||||
| 2.7.x | :x: |
|
||||
| 2.6.x | :x: |
|
||||
| ------- | ------------------ |
|
||||
| 3.0.x | :white_check_mark: |
|
||||
| 2.7.x | :white_check_mark: |
|
||||
| 2.6.x | :white_check_mark: |
|
||||
| 2.5.x | :x: |
|
||||
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
The Apache Software Foundation takes a rigorous standpoint in annihilating the security issues in its software projects. Apache Dubbo is highly sensitive and forthcoming to issues pertaining to its features and functionality.
|
||||
|
|
|
|||
|
|
@ -29,6 +29,6 @@ ignore:
|
|||
- "**/dubbo-test/**"
|
||||
- "**/dubbo-compatible/**"
|
||||
- "**/dubbo-native/**"
|
||||
- "**/dubbo-native-plugin/**"
|
||||
- "**/dubbo-common/src/main/java/org/apache/dubbo/common/json/*.java" # internal JSON impl is deprecate, ignore test coverage for them
|
||||
- "**/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/AnnotationBean.java" # Deprecated
|
||||
- "**/dubbo-rpc/dubbo-rpc-thrift/**"
|
||||
|
|
|
|||
|
|
@ -1,89 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo-build-tools</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<properties>
|
||||
<maven.deploy.skip>true</maven.deploy.skip>
|
||||
<spotless-maven-plugin.version>2.43.0</spotless-maven-plugin.version>
|
||||
<spotless.action>check</spotless.action>
|
||||
<dubbo-shared-resources.version>1.0.0</dubbo-shared-resources.version>
|
||||
<palantirJavaFormat.version>2.38.0</palantirJavaFormat.version>
|
||||
</properties>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>java11+</id>
|
||||
<activation>
|
||||
<jdk>[11,)</jdk>
|
||||
</activation>
|
||||
<build>
|
||||
<!--- newer versions of plugins requires JDK 11 -->
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>com.diffplug.spotless</groupId>
|
||||
<artifactId>spotless-maven-plugin</artifactId>
|
||||
<version>${spotless-maven-plugin.version}</version>
|
||||
<configuration>
|
||||
<java>
|
||||
<palantirJavaFormat>
|
||||
<version>${palantirJavaFormat.version}</version>
|
||||
</palantirJavaFormat>
|
||||
<removeUnusedImports />
|
||||
<importOrder>
|
||||
<file>dubbo-importorder.txt</file>
|
||||
</importOrder>
|
||||
<licenseHeader>
|
||||
<file>checkstyle-header.txt</file>
|
||||
</licenseHeader>
|
||||
</java>
|
||||
<pom>
|
||||
<sortPom>
|
||||
<expandEmptyElements>false</expandEmptyElements>
|
||||
<spaceBeforeCloseEmptyElement>true</spaceBeforeCloseEmptyElement>
|
||||
</sortPom>
|
||||
</pom>
|
||||
<upToDateChecking>
|
||||
<enabled>true</enabled>
|
||||
</upToDateChecking>
|
||||
</configuration>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>dubbo-shared-resources</artifactId>
|
||||
<version>${dubbo-shared-resources.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>${spotless.action}</goal>
|
||||
</goals>
|
||||
<phase>process-sources</phase>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
</project>
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
|
@ -1,4 +1,3 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
|
|
@ -15,104 +14,77 @@
|
|||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo-parent</artifactId>
|
||||
<version>${revision}</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<artifactId>dubbo-cluster</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>${project.artifactId}</name>
|
||||
<description>The cluster module of dubbo project</description>
|
||||
<properties>
|
||||
<skip_maven_deploy>false</skip_maven_deploy>
|
||||
<nashorn-core.version>15.4</nashorn-core.version>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo-rpc-api</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.yaml</groupId>
|
||||
<artifactId>snakeyaml</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo-rpc-injvm</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.curator</groupId>
|
||||
<artifactId>curator-framework</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.zookeeper</groupId>
|
||||
<artifactId>zookeeper</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo-serialization-hessian2</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo-serialization-fastjson2</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo-test-check</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo-metrics-registry</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo-metrics-default</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.micrometer</groupId>
|
||||
<artifactId>micrometer-tracing-integration-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<profiles>
|
||||
<!--
|
||||
https://github.com/openjdk/nashorn
|
||||
Nashorn used to be part of the JDK until Java 14.
|
||||
This project provides a standalone version of Nashorn suitable for use with Java 11 and later.
|
||||
-->
|
||||
<profile>
|
||||
<id>nashorn-jdk11</id>
|
||||
<activation>
|
||||
<jdk>[11,)</jdk>
|
||||
</activation>
|
||||
<dependencies>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo-parent</artifactId>
|
||||
<version>${revision}</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<artifactId>dubbo-cluster</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>${project.artifactId}</name>
|
||||
<description>The cluster module of dubbo project</description>
|
||||
<properties>
|
||||
<skip_maven_deploy>false</skip_maven_deploy>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.openjdk.nashorn</groupId>
|
||||
<artifactId>nashorn-core</artifactId>
|
||||
<version>${nashorn-core.version}</version>
|
||||
<scope>test</scope>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo-rpc-api</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</profile>
|
||||
</profiles>
|
||||
<dependency>
|
||||
<groupId>org.yaml</groupId>
|
||||
<artifactId>snakeyaml</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo-rpc-injvm</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.curator</groupId>
|
||||
<artifactId>curator-framework</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.zookeeper</groupId>
|
||||
<artifactId>zookeeper</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo-serialization-hessian2</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo-serialization-fastjson2</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo-test-check</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo-metrics-registry</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo-metrics-default</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
|
|||
|
|
@ -35,5 +35,8 @@ public interface AddressListener {
|
|||
*/
|
||||
List<URL> notify(List<URL> addresses, URL consumerUrl, Directory registryDirectory);
|
||||
|
||||
default void destroy(URL consumerUrl, Directory registryDirectory) {}
|
||||
default void destroy(URL consumerUrl, Directory registryDirectory) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,8 +55,6 @@ public interface Cluster {
|
|||
if (StringUtils.isEmpty(name)) {
|
||||
name = Cluster.DEFAULT;
|
||||
}
|
||||
return ScopeModelUtil.getApplicationModel(scopeModel)
|
||||
.getExtensionLoader(Cluster.class)
|
||||
.getExtension(name, wrap);
|
||||
return ScopeModelUtil.getApplicationModel(scopeModel).getExtensionLoader(Cluster.class).getExtension(name, wrap);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,10 +17,7 @@
|
|||
package org.apache.dubbo.rpc.cluster;
|
||||
|
||||
import org.apache.dubbo.common.beans.factory.ScopeBeanFactory;
|
||||
import org.apache.dubbo.rpc.AdaptiveMetrics;
|
||||
import org.apache.dubbo.rpc.cluster.merger.MergerFactory;
|
||||
import org.apache.dubbo.rpc.cluster.router.RouterSnapshotSwitcher;
|
||||
import org.apache.dubbo.rpc.cluster.router.mesh.route.MeshRuleManager;
|
||||
import org.apache.dubbo.rpc.cluster.support.ClusterUtils;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.model.FrameworkModel;
|
||||
|
|
@ -37,14 +34,10 @@ public class ClusterScopeModelInitializer implements ScopeModelInitializer {
|
|||
@Override
|
||||
public void initializeApplicationModel(ApplicationModel applicationModel) {
|
||||
ScopeBeanFactory beanFactory = applicationModel.getBeanFactory();
|
||||
beanFactory.registerBean(MergerFactory.class);
|
||||
beanFactory.registerBean(ClusterUtils.class);
|
||||
beanFactory.registerBean(AdaptiveMetrics.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initializeModuleModel(ModuleModel moduleModel) {
|
||||
ScopeBeanFactory beanFactory = moduleModel.getBeanFactory();
|
||||
beanFactory.registerBean(MeshRuleManager.class);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ public interface Configurator extends Comparable<Configurator> {
|
|||
*/
|
||||
URL configure(URL url);
|
||||
|
||||
|
||||
/**
|
||||
* Convert override urls to map for use when re-refer. Send all rules every time, the urls will be reassembled and
|
||||
* calculated
|
||||
|
|
@ -72,9 +73,7 @@ public interface Configurator extends Comparable<Configurator> {
|
|||
return Optional.empty();
|
||||
}
|
||||
|
||||
ConfiguratorFactory configuratorFactory = urls.get(0)
|
||||
.getOrDefaultApplicationModel()
|
||||
.getExtensionLoader(ConfiguratorFactory.class)
|
||||
ConfiguratorFactory configuratorFactory = urls.get(0).getOrDefaultApplicationModel().getExtensionLoader(ConfiguratorFactory.class)
|
||||
.getAdaptiveExtension();
|
||||
|
||||
List<Configurator> configurators = new ArrayList<>(urls.size());
|
||||
|
|
@ -84,8 +83,7 @@ public interface Configurator extends Comparable<Configurator> {
|
|||
break;
|
||||
}
|
||||
Map<String, String> override = new HashMap<>(url.getParameters());
|
||||
// The anyhost parameter of override may be added automatically, it can't change the judgement of changing
|
||||
// url
|
||||
//The anyhost parameter of override may be added automatically, it can't change the judgement of changing url
|
||||
override.remove(ANYHOST_KEY);
|
||||
if (CollectionUtils.isEmptyMap(override)) {
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -36,4 +36,5 @@ public interface ConfiguratorFactory {
|
|||
*/
|
||||
@Adaptive(CommonConstants.PROTOCOL_KEY)
|
||||
Configurator getConfigurator(URL url);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -100,6 +100,7 @@ public interface Constants {
|
|||
|
||||
String OVERRIDE_PROVIDERS_KEY = "providerAddresses";
|
||||
|
||||
|
||||
/**
|
||||
* key for router type, for e.g., "script"/"file", corresponding to ScriptRouterFactory.NAME, FileRouterFactory.NAME
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -46,4 +46,5 @@ public interface LoadBalance {
|
|||
*/
|
||||
@Adaptive("loadbalance")
|
||||
<T> Invoker<T> select(List<Invoker<T>> invokers, URL url, Invocation invocation) throws RpcException;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,4 +22,5 @@ import org.apache.dubbo.common.extension.SPI;
|
|||
public interface Merger<T> {
|
||||
|
||||
T merge(T... items);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,9 +33,7 @@ public interface ProviderURLMergeProcessor {
|
|||
*/
|
||||
URL mergeUrl(URL remoteUrl, Map<String, String> localParametersMap);
|
||||
|
||||
default Map<String, String> mergeLocalParams(Map<String, String> localMap) {
|
||||
return localMap;
|
||||
}
|
||||
default Map<String, String> mergeLocalParams(Map<String, String> localMap) { return localMap; }
|
||||
|
||||
default boolean accept(URL providerUrl, Map<String, String> localParametersMap) {
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -68,8 +68,8 @@ public interface Router extends Comparable<Router> {
|
|||
* @return state with route result
|
||||
* @throws RpcException
|
||||
*/
|
||||
default <T> RouterResult<Invoker<T>> route(
|
||||
List<Invoker<T>> invokers, URL url, Invocation invocation, boolean needToPrintMessage) throws RpcException {
|
||||
default <T> RouterResult<Invoker<T>> route(List<Invoker<T>> invokers, URL url, Invocation invocation,
|
||||
boolean needToPrintMessage) throws RpcException {
|
||||
return new RouterResult<>(route(invokers, url, invocation));
|
||||
}
|
||||
|
||||
|
|
@ -80,7 +80,9 @@ public interface Router extends Comparable<Router> {
|
|||
* @param invokers invoker list
|
||||
* @param <T> invoker's type
|
||||
*/
|
||||
default <T> void notify(List<Invoker<T>> invokers) {}
|
||||
default <T> void notify(List<Invoker<T>> invokers) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* To decide whether this router need to execute every time an RPC comes or should only execute when addresses or
|
||||
|
|
@ -107,7 +109,7 @@ public interface Router extends Comparable<Router> {
|
|||
int getPriority();
|
||||
|
||||
default void stop() {
|
||||
// do nothing by default
|
||||
//do nothing by default
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -16,6 +16,12 @@
|
|||
*/
|
||||
package org.apache.dubbo.rpc.cluster;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.concurrent.locks.ReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.config.ConfigurationUtils;
|
||||
import org.apache.dubbo.common.constants.LoggerCodeConstants;
|
||||
|
|
@ -30,12 +36,6 @@ import org.apache.dubbo.rpc.cluster.router.state.StateRouterFactory;
|
|||
import org.apache.dubbo.rpc.model.ModuleModel;
|
||||
import org.apache.dubbo.rpc.model.ScopeModelUtil;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.concurrent.locks.ReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.apache.dubbo.rpc.cluster.Constants.ROUTER_KEY;
|
||||
|
||||
/**
|
||||
|
|
@ -52,30 +52,31 @@ public class RouterChain<T> {
|
|||
public static <T> RouterChain<T> buildChain(Class<T> interfaceClass, URL url) {
|
||||
SingleRouterChain<T> chain1 = buildSingleChain(interfaceClass, url);
|
||||
SingleRouterChain<T> chain2 = buildSingleChain(interfaceClass, url);
|
||||
return new RouterChain<>(new SingleRouterChain[] {chain1, chain2});
|
||||
return new RouterChain<>(new SingleRouterChain[]{chain1, chain2});
|
||||
}
|
||||
|
||||
public static <T> SingleRouterChain<T> buildSingleChain(Class<T> interfaceClass, URL url) {
|
||||
ModuleModel moduleModel = url.getOrDefaultModuleModel();
|
||||
|
||||
List<RouterFactory> extensionFactories =
|
||||
moduleModel.getExtensionLoader(RouterFactory.class).getActivateExtension(url, ROUTER_KEY);
|
||||
List<RouterFactory> extensionFactories = moduleModel.getExtensionLoader(RouterFactory.class)
|
||||
.getActivateExtension(url, ROUTER_KEY);
|
||||
|
||||
List<Router> routers = extensionFactories.stream()
|
||||
.map(factory -> factory.getRouter(url))
|
||||
.sorted(Router::compareTo)
|
||||
.collect(Collectors.toList());
|
||||
.map(factory -> factory.getRouter(url))
|
||||
.sorted(Router::compareTo)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
List<StateRouter<T>> stateRouters =
|
||||
moduleModel.getExtensionLoader(StateRouterFactory.class).getActivateExtension(url, ROUTER_KEY).stream()
|
||||
.map(factory -> factory.getRouter(interfaceClass, url))
|
||||
.collect(Collectors.toList());
|
||||
List<StateRouter<T>> stateRouters = moduleModel
|
||||
.getExtensionLoader(StateRouterFactory.class)
|
||||
.getActivateExtension(url, ROUTER_KEY)
|
||||
.stream()
|
||||
.map(factory -> factory.getRouter(interfaceClass, url))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
boolean shouldFailFast = Boolean.parseBoolean(
|
||||
ConfigurationUtils.getProperty(moduleModel, Constants.SHOULD_FAIL_FAST_KEY, "true"));
|
||||
|
||||
RouterSnapshotSwitcher routerSnapshotSwitcher =
|
||||
ScopeModelUtil.getFrameworkModel(moduleModel).getBeanFactory().getBean(RouterSnapshotSwitcher.class);
|
||||
boolean shouldFailFast = Boolean.parseBoolean(ConfigurationUtils.getProperty(moduleModel, Constants.SHOULD_FAIL_FAST_KEY, "true"));
|
||||
|
||||
RouterSnapshotSwitcher routerSnapshotSwitcher = ScopeModelUtil.getFrameworkModel(moduleModel).getBeanFactory().getBean(RouterSnapshotSwitcher.class);
|
||||
|
||||
return new SingleRouterChain<>(routers, stateRouters, shouldFailFast, routerSnapshotSwitcher);
|
||||
}
|
||||
|
|
@ -105,9 +106,9 @@ public class RouterChain<T> {
|
|||
// If `availableInvokers` is created from origin invokers => use backup chain
|
||||
// If `availableInvokers` is created from newly invokers => use main chain
|
||||
BitList<Invoker<T>> notifying = notifyingInvokers.get();
|
||||
if (notifying != null
|
||||
&& currentChain == backupChain
|
||||
&& availableInvokers.getOriginList() == notifying.getOriginList()) {
|
||||
if (notifying != null &&
|
||||
currentChain == backupChain &&
|
||||
availableInvokers.getOriginList() == notifying.getOriginList()) {
|
||||
return mainChain;
|
||||
}
|
||||
return currentChain;
|
||||
|
|
@ -139,8 +140,7 @@ public class RouterChain<T> {
|
|||
}
|
||||
|
||||
// Refresh main chain.
|
||||
// No one can request to use main chain. `currentChain` is backup chain. `route` method cannot access main
|
||||
// chain.
|
||||
// No one can request to use main chain. `currentChain` is backup chain. `route` method cannot access main chain.
|
||||
try {
|
||||
// Lock main chain to wait all invocation end
|
||||
// To wait until no one is using main chain.
|
||||
|
|
@ -157,32 +157,26 @@ public class RouterChain<T> {
|
|||
}
|
||||
|
||||
// Set the reference of newly invokers to temp variable.
|
||||
// Reason: The next step will switch the invokers reference in directory, so we should check the
|
||||
// `availableInvokers`
|
||||
// argument when `route`. If the current invocation use newly invokers, we should use main chain to
|
||||
// route, and
|
||||
// Reason: The next step will switch the invokers reference in directory, so we should check the `availableInvokers`
|
||||
// argument when `route`. If the current invocation use newly invokers, we should use main chain to route, and
|
||||
// this can prevent use newly invokers to route backup chain, which can only route origin invokers now.
|
||||
notifyingInvokers.set(invokers);
|
||||
|
||||
// Switch the invokers reference in directory.
|
||||
// Cannot switch before update main chain or after backup chain update success. Or that will cause state
|
||||
// inconsistent.
|
||||
// Cannot switch before update main chain or after backup chain update success. Or that will cause state inconsistent.
|
||||
switchAction.run();
|
||||
|
||||
try {
|
||||
// Lock to prevent directory continue list
|
||||
// The invokers reference in directory now should be the newly one and should always use the newly one once
|
||||
// lock released.
|
||||
// The invokers reference in directory now should be the newly one and should always use the newly one once lock released.
|
||||
lock.writeLock().lock();
|
||||
|
||||
// Switch to main chain. Will update backup chain later.
|
||||
currentChain = mainChain;
|
||||
|
||||
// Clean up temp variable.
|
||||
// `availableInvokers` check is useless now, because `route` method will no longer receive any
|
||||
// `availableInvokers` related
|
||||
// with the origin invokers. The getter of invokers reference in directory is locked now, and will return
|
||||
// newly invokers
|
||||
// `availableInvokers` check is useless now, because `route` method will no longer receive any `availableInvokers` related
|
||||
// with the origin invokers. The getter of invokers reference in directory is locked now, and will return newly invokers
|
||||
// once lock released.
|
||||
notifyingInvokers.set(null);
|
||||
} finally {
|
||||
|
|
@ -192,8 +186,7 @@ public class RouterChain<T> {
|
|||
}
|
||||
|
||||
// Refresh main chain.
|
||||
// No one can request to use main chain. `currentChain` is main chain. `route` method cannot access backup
|
||||
// chain.
|
||||
// No one can request to use main chain. `currentChain` is main chain. `route` method cannot access backup chain.
|
||||
try {
|
||||
// Lock main chain to wait all invocation end
|
||||
backupChain.getLock().writeLock().lock();
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.dubbo.rpc.cluster;
|
||||
|
||||
import org.apache.dubbo.common.URL;
|
||||
|
|
@ -25,4 +26,5 @@ import java.util.List;
|
|||
public interface RuleConverter {
|
||||
|
||||
List<URL> convert(URL subscribeUrl, Object source);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,13 @@
|
|||
*/
|
||||
package org.apache.dubbo.rpc.cluster;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.locks.ReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.Version;
|
||||
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
|
||||
|
|
@ -33,13 +40,6 @@ import org.apache.dubbo.rpc.cluster.router.state.BitList;
|
|||
import org.apache.dubbo.rpc.cluster.router.state.StateRouter;
|
||||
import org.apache.dubbo.rpc.cluster.router.state.TailStateRouter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.locks.ReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
||||
import static org.apache.dubbo.common.constants.LoggerCodeConstants.CLUSTER_FAILED_STOP;
|
||||
import static org.apache.dubbo.common.constants.LoggerCodeConstants.CLUSTER_NO_VALID_PROVIDER;
|
||||
import static org.apache.dubbo.common.constants.LoggerCodeConstants.INTERNAL_ERROR;
|
||||
|
|
@ -79,11 +79,7 @@ public class SingleRouterChain<T> {
|
|||
|
||||
private final ReadWriteLock lock = new ReentrantReadWriteLock();
|
||||
|
||||
public SingleRouterChain(
|
||||
List<Router> routers,
|
||||
List<StateRouter<T>> stateRouters,
|
||||
boolean shouldFailFast,
|
||||
RouterSnapshotSwitcher routerSnapshotSwitcher) {
|
||||
public SingleRouterChain(List<Router> routers, List<StateRouter<T>> stateRouters, boolean shouldFailFast, RouterSnapshotSwitcher routerSnapshotSwitcher) {
|
||||
initWithRouters(routers);
|
||||
|
||||
initWithStateRouters(stateRouters);
|
||||
|
|
@ -138,12 +134,9 @@ public class SingleRouterChain<T> {
|
|||
|
||||
public List<Invoker<T>> route(URL url, BitList<Invoker<T>> availableInvokers, Invocation invocation) {
|
||||
if (invokers.getOriginList() != availableInvokers.getOriginList()) {
|
||||
logger.error(
|
||||
INTERNAL_ERROR,
|
||||
"",
|
||||
"Router's invoker size: " + invokers.getOriginList().size() + " Invocation's invoker size: "
|
||||
+ availableInvokers.getOriginList().size(),
|
||||
"Reject to route, because the invokers has changed.");
|
||||
logger.error(INTERNAL_ERROR, "", "Router's invoker size: " + invokers.getOriginList().size() +
|
||||
" Invocation's invoker size: " + availableInvokers.getOriginList().size(),
|
||||
"Reject to route, because the invokers has changed.");
|
||||
throw new IllegalStateException("reject to route, because the invokers has changed.");
|
||||
}
|
||||
if (RpcContext.getServiceContext().isNeedPrintRouterSnapshot()) {
|
||||
|
|
@ -209,10 +202,9 @@ public class SingleRouterChain<T> {
|
|||
/**
|
||||
* Build each router's result
|
||||
*/
|
||||
public RouterSnapshotNode<T> buildRouterSnapshot(
|
||||
URL url, BitList<Invoker<T>> availableInvokers, Invocation invocation) {
|
||||
public RouterSnapshotNode<T> buildRouterSnapshot(URL url, BitList<Invoker<T>> availableInvokers, Invocation invocation) {
|
||||
BitList<Invoker<T>> resultInvokers = availableInvokers.clone();
|
||||
RouterSnapshotNode<T> parentNode = new RouterSnapshotNode<>("Parent", resultInvokers.clone());
|
||||
RouterSnapshotNode<T> parentNode = new RouterSnapshotNode<T>("Parent", resultInvokers.clone());
|
||||
parentNode.setNodeOutputInvokers(resultInvokers.clone());
|
||||
|
||||
// 1. route state router
|
||||
|
|
@ -227,7 +219,7 @@ public class SingleRouterChain<T> {
|
|||
return parentNode;
|
||||
}
|
||||
|
||||
RouterSnapshotNode<T> commonRouterNode = new RouterSnapshotNode<>("CommonRouter", resultInvokers.clone());
|
||||
RouterSnapshotNode<T> commonRouterNode = new RouterSnapshotNode<T>("CommonRouter", resultInvokers.clone());
|
||||
parentNode.appendNode(commonRouterNode);
|
||||
List<Invoker<T>> commonRouterResult = resultInvokers;
|
||||
|
||||
|
|
@ -236,8 +228,7 @@ public class SingleRouterChain<T> {
|
|||
// Copy resultInvokers to a arrayList. BitList not support
|
||||
List<Invoker<T>> inputInvokers = new ArrayList<>(commonRouterResult);
|
||||
|
||||
RouterSnapshotNode<T> currentNode =
|
||||
new RouterSnapshotNode<>(router.getClass().getSimpleName(), inputInvokers);
|
||||
RouterSnapshotNode<T> currentNode = new RouterSnapshotNode<T>(router.getClass().getSimpleName(), inputInvokers);
|
||||
|
||||
// append to router node chain
|
||||
commonRouterNode.appendNode(currentNode);
|
||||
|
|
@ -277,27 +268,24 @@ public class SingleRouterChain<T> {
|
|||
}
|
||||
|
||||
private void logRouterSnapshot(URL url, Invocation invocation, RouterSnapshotNode<T> snapshotNode) {
|
||||
if (snapshotNode.getChainOutputInvokers() == null
|
||||
|| snapshotNode.getChainOutputInvokers().isEmpty()) {
|
||||
if (snapshotNode.getChainOutputInvokers() == null ||
|
||||
snapshotNode.getChainOutputInvokers().isEmpty()) {
|
||||
if (logger.isWarnEnabled()) {
|
||||
String message = "No provider available after route for the service " + url.getServiceKey()
|
||||
+ " from registry " + url.getAddress()
|
||||
+ " on the consumer " + NetUtils.getLocalHost()
|
||||
+ " using the dubbo version " + Version.getVersion() + ". Router snapshot is below: \n"
|
||||
+ snapshotNode.toString();
|
||||
+ " from registry " + url.getAddress()
|
||||
+ " on the consumer " + NetUtils.getLocalHost()
|
||||
+ " using the dubbo version " + Version.getVersion() + ". Router snapshot is below: \n" + snapshotNode.toString();
|
||||
if (routerSnapshotSwitcher.isEnable()) {
|
||||
routerSnapshotSwitcher.setSnapshot(message);
|
||||
}
|
||||
logger.warn(
|
||||
CLUSTER_NO_VALID_PROVIDER, "No provider available after route for the service", "", message);
|
||||
logger.warn(CLUSTER_NO_VALID_PROVIDER, "No provider available after route for the service", "", message);
|
||||
}
|
||||
} else {
|
||||
if (logger.isInfoEnabled()) {
|
||||
String message = "Router snapshot service " + url.getServiceKey()
|
||||
+ " from registry " + url.getAddress()
|
||||
+ " on the consumer " + NetUtils.getLocalHost()
|
||||
+ " using the dubbo version " + Version.getVersion() + " is below: \n"
|
||||
+ snapshotNode.toString();
|
||||
+ " from registry " + url.getAddress()
|
||||
+ " on the consumer " + NetUtils.getLocalHost()
|
||||
+ " using the dubbo version " + Version.getVersion() + " is below: \n" + snapshotNode.toString();
|
||||
if (routerSnapshotSwitcher.isEnable()) {
|
||||
routerSnapshotSwitcher.setSnapshot(message);
|
||||
}
|
||||
|
|
@ -342,12 +330,7 @@ public class SingleRouterChain<T> {
|
|||
try {
|
||||
router.stop();
|
||||
} catch (Exception e) {
|
||||
logger.error(
|
||||
CLUSTER_FAILED_STOP,
|
||||
"route stop failed",
|
||||
"",
|
||||
"Error trying to stop router " + router.getClass(),
|
||||
e);
|
||||
logger.error(CLUSTER_FAILED_STOP, "route stop failed", "", "Error trying to stop router " + router.getClass(), e);
|
||||
}
|
||||
}
|
||||
routers = Collections.emptyList();
|
||||
|
|
@ -357,12 +340,7 @@ public class SingleRouterChain<T> {
|
|||
try {
|
||||
router.stop();
|
||||
} catch (Exception e) {
|
||||
logger.error(
|
||||
CLUSTER_FAILED_STOP,
|
||||
"StateRouter stop failed",
|
||||
"",
|
||||
"Error trying to stop StateRouter " + router.getClass(),
|
||||
e);
|
||||
logger.error(CLUSTER_FAILED_STOP, "StateRouter stop failed", "", "Error trying to stop StateRouter " + router.getClass(), e);
|
||||
}
|
||||
}
|
||||
stateRouters = Collections.emptyList();
|
||||
|
|
|
|||
|
|
@ -72,10 +72,7 @@ public abstract class AbstractConfigurator implements Configurator {
|
|||
@Override
|
||||
public URL configure(URL url) {
|
||||
// If override url is not enabled or is invalid, just return.
|
||||
if (!configuratorUrl.getParameter(ENABLED_KEY, true)
|
||||
|| configuratorUrl.getHost() == null
|
||||
|| url == null
|
||||
|| url.getHost() == null) {
|
||||
if (!configuratorUrl.getParameter(ENABLED_KEY, true) || configuratorUrl.getHost() == null || url == null || url.getHost() == null) {
|
||||
logger.info("Cannot apply configurator rule, the rule is disabled or is invalid: \n" + configuratorUrl);
|
||||
return url;
|
||||
}
|
||||
|
|
@ -101,9 +98,7 @@ public abstract class AbstractConfigurator implements Configurator {
|
|||
|
||||
@Deprecated
|
||||
private URL configureDeprecated(URL url) {
|
||||
// If override url has port, means it is a provider address. We want to control a specific provider with this
|
||||
// override url, it may take effect on the specific provider instance or on consumers holding this provider
|
||||
// instance.
|
||||
// If override url has port, means it is a provider address. We want to control a specific provider with this override url, it may take effect on the specific provider instance or on consumers holding this provider instance.
|
||||
if (configuratorUrl.getPort() != 0) {
|
||||
if (url.getPort() == configuratorUrl.getPort()) {
|
||||
return configureIfMatch(url.getHost(), url);
|
||||
|
|
@ -136,8 +131,7 @@ public abstract class AbstractConfigurator implements Configurator {
|
|||
if (matcher.isMatch(host, url)) {
|
||||
return doConfigure(url, configuratorUrl.removeParameters(conditionKeys));
|
||||
} else {
|
||||
logger.debug("Cannot apply configurator rule, param mismatch, current params are " + url
|
||||
+ ", params in rule is " + matcher);
|
||||
logger.debug("Cannot apply configurator rule, param mismatch, current params are " + url + ", params in rule is " + matcher);
|
||||
}
|
||||
} else {
|
||||
return doConfigure(url, configuratorUrl.removeParameters(conditionKeys));
|
||||
|
|
@ -147,8 +141,7 @@ public abstract class AbstractConfigurator implements Configurator {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
logger.debug("Cannot apply configurator rule, host mismatch, current host is " + host + ", host in rule is "
|
||||
+ configuratorUrl.getHost());
|
||||
logger.debug("Cannot apply configurator rule, host mismatch, current host is " + host + ", host in rule is " + configuratorUrl.getHost());
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
|
@ -166,16 +159,15 @@ public abstract class AbstractConfigurator implements Configurator {
|
|||
String[] providerAddresses = providers.split(CommonConstants.COMMA_SEPARATOR);
|
||||
for (String address : providerAddresses) {
|
||||
if (address.equals(url.getAddress())
|
||||
|| address.equals(ANYHOST_VALUE)
|
||||
|| address.equals(ANYHOST_VALUE + CommonConstants.GROUP_CHAR_SEPARATOR + ANY_VALUE)
|
||||
|| address.equals(ANYHOST_VALUE + CommonConstants.GROUP_CHAR_SEPARATOR + url.getPort())
|
||||
|| address.equals(url.getHost())) {
|
||||
|| address.equals(ANYHOST_VALUE)
|
||||
|| address.equals(ANYHOST_VALUE + CommonConstants.GROUP_CHAR_SEPARATOR + ANY_VALUE)
|
||||
|| address.equals(ANYHOST_VALUE + CommonConstants.GROUP_CHAR_SEPARATOR + url.getPort())
|
||||
|| address.equals(url.getHost())) {
|
||||
match = true;
|
||||
}
|
||||
}
|
||||
if (!match) {
|
||||
logger.debug("Cannot apply configurator rule, provider address mismatch, current address "
|
||||
+ url.getAddress() + ", address in rule is " + providers);
|
||||
logger.debug("Cannot apply configurator rule, provider address mismatch, current address " + url.getAddress() + ", address in rule is " + providers);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -183,18 +175,17 @@ public abstract class AbstractConfigurator implements Configurator {
|
|||
String configApplication = configuratorUrl.getApplication(configuratorUrl.getUsername());
|
||||
String currentApplication = url.getApplication(url.getUsername());
|
||||
if (configApplication != null
|
||||
&& !ANY_VALUE.equals(configApplication)
|
||||
&& !configApplication.equals(currentApplication)) {
|
||||
logger.debug("Cannot apply configurator rule, application name mismatch, current application is "
|
||||
+ currentApplication + ", application in rule is " + configApplication);
|
||||
&& !ANY_VALUE.equals(configApplication)
|
||||
&& !configApplication.equals(currentApplication)) {
|
||||
logger.debug("Cannot apply configurator rule, application name mismatch, current application is " + currentApplication + ", application in rule is " + configApplication);
|
||||
return false;
|
||||
}
|
||||
|
||||
String configServiceKey = configuratorUrl.getServiceKey();
|
||||
String currentServiceKey = url.getServiceKey();
|
||||
if (!ANY_VALUE.equals(configServiceKey) && !configServiceKey.equals(currentServiceKey)) {
|
||||
logger.debug("Cannot apply configurator rule, service mismatch, current service is " + currentServiceKey
|
||||
+ ", service in rule is " + configServiceKey);
|
||||
if (!ANY_VALUE.equals(configServiceKey)
|
||||
&& !configServiceKey.equals(currentServiceKey)) {
|
||||
logger.debug("Cannot apply configurator rule, service mismatch, current service is " + currentServiceKey + ", service in rule is " + configServiceKey);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -211,9 +202,8 @@ public abstract class AbstractConfigurator implements Configurator {
|
|||
if (startWithTilde) {
|
||||
conditionKeys.add(key);
|
||||
}
|
||||
if (value != null
|
||||
&& !ANY_VALUE.equals(value)
|
||||
&& !value.equals(url.getParameter(startWithTilde ? key.substring(1) : key))) {
|
||||
if (value != null && !ANY_VALUE.equals(value)
|
||||
&& !value.equals(url.getParameter(startWithTilde ? key.substring(1) : key))) {
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
|
|
@ -223,7 +213,7 @@ public abstract class AbstractConfigurator implements Configurator {
|
|||
}
|
||||
|
||||
private Set<String> genConditionKeys() {
|
||||
Set<String> conditionKeys = new HashSet<>();
|
||||
Set<String> conditionKeys = new HashSet<String>();
|
||||
conditionKeys.add(CATEGORY_KEY);
|
||||
conditionKeys.add(Constants.CHECK_KEY);
|
||||
conditionKeys.add(DYNAMIC_KEY);
|
||||
|
|
@ -243,4 +233,5 @@ public abstract class AbstractConfigurator implements Configurator {
|
|||
}
|
||||
|
||||
protected abstract URL doConfigure(URL currentUrl, URL configUrl);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,4 +32,5 @@ public class AbsentConfigurator extends AbstractConfigurator {
|
|||
public URL doConfigure(URL currentUrl, URL configUrl) {
|
||||
return currentUrl.addParametersIfAbsent(configUrl.getParameters());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,4 +30,5 @@ public class AbsentConfiguratorFactory implements ConfiguratorFactory {
|
|||
public Configurator getConfigurator(URL url) {
|
||||
return new AbsentConfigurator(url);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,4 +36,5 @@ public class OverrideConfigurator extends AbstractConfigurator {
|
|||
logger.info("Start overriding url " + currentUrl + " with override url " + configUrl);
|
||||
return currentUrl.addParameters(configUrl.getParameters());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,4 +30,5 @@ public class OverrideConfiguratorFactory implements ConfiguratorFactory {
|
|||
public Configurator getConfigurator(URL url) {
|
||||
return new OverrideConfigurator(url);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,14 +23,14 @@ import org.apache.dubbo.common.utils.StringUtils;
|
|||
import org.apache.dubbo.rpc.cluster.configurator.parser.model.ConfigItem;
|
||||
import org.apache.dubbo.rpc.cluster.configurator.parser.model.ConfiguratorConfig;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.yaml.snakeyaml.LoaderOptions;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
import org.yaml.snakeyaml.constructor.SafeConstructor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.ANYHOST_VALUE;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER;
|
||||
import static org.apache.dubbo.common.constants.RegistryConstants.APP_DYNAMIC_CONFIGURATORS_CATEGORY;
|
||||
|
|
@ -104,12 +104,7 @@ public class ConfigParser {
|
|||
if (CollectionUtils.isNotEmpty(apps)) {
|
||||
apps.forEach(app -> {
|
||||
StringBuilder tmpUrlBuilder = new StringBuilder(urlBuilder);
|
||||
urls.add(appendMatchCondition(
|
||||
URL.valueOf(tmpUrlBuilder
|
||||
.append("&application=")
|
||||
.append(app)
|
||||
.toString()),
|
||||
item));
|
||||
urls.add(appendMatchCondition(URL.valueOf(tmpUrlBuilder.append("&application=").append(app).toString()), item));
|
||||
});
|
||||
} else {
|
||||
urls.add(appendMatchCondition(URL.valueOf(urlBuilder.toString()), item));
|
||||
|
|
@ -160,8 +155,8 @@ public class ConfigParser {
|
|||
}
|
||||
Map<String, String> parameters = item.getParameters();
|
||||
if (CollectionUtils.isEmptyMap(parameters)) {
|
||||
throw new IllegalStateException("Invalid configurator rule, please specify at least one parameter "
|
||||
+ "you want to change in the rule.");
|
||||
throw new IllegalStateException("Invalid configurator rule, please specify at least one parameter " +
|
||||
"you want to change in the rule.");
|
||||
}
|
||||
|
||||
parameters.forEach((k, v) -> {
|
||||
|
|
|
|||
|
|
@ -101,11 +101,12 @@ public class ConditionMatch {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ConditionMatch{" + "address='"
|
||||
+ address + '\'' + "providerAddress='"
|
||||
+ providerAddress + '\'' + ", service='"
|
||||
+ service + '\'' + ", app='"
|
||||
+ app + '\'' + ", param='"
|
||||
+ param + '\'' + '}';
|
||||
return "ConditionMatch{" +
|
||||
"address='" + address + '\'' +
|
||||
"providerAddress='" + providerAddress + '\'' +
|
||||
", service='" + service + '\'' +
|
||||
", app='" + app + '\'' +
|
||||
", param='" + param + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,33 +68,32 @@ public class ConfigItem {
|
|||
|
||||
Object addresses = map.get(ADDRESSES_KEY);
|
||||
if (addresses != null && List.class.isAssignableFrom(addresses.getClass())) {
|
||||
configItem.setAddresses(
|
||||
((List<Object>) addresses).stream().map(String::valueOf).collect(Collectors.toList()));
|
||||
configItem.setAddresses(((List<Object>) addresses).stream()
|
||||
.map(String::valueOf).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
Object providerAddresses = map.get(PROVIDER_ADDRESSES_KEY);
|
||||
if (providerAddresses != null && List.class.isAssignableFrom(providerAddresses.getClass())) {
|
||||
configItem.setProviderAddresses(((List<Object>) providerAddresses)
|
||||
.stream().map(String::valueOf).collect(Collectors.toList()));
|
||||
configItem.setProviderAddresses(((List<Object>) providerAddresses).stream()
|
||||
.map(String::valueOf).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
Object services = map.get(SERVICES_KEY);
|
||||
if (services != null && List.class.isAssignableFrom(services.getClass())) {
|
||||
configItem.setServices(
|
||||
((List<Object>) services).stream().map(String::valueOf).collect(Collectors.toList()));
|
||||
configItem.setServices(((List<Object>) services).stream()
|
||||
.map(String::valueOf).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
Object applications = map.get(APPLICATIONS_KEY);
|
||||
if (applications != null && List.class.isAssignableFrom(applications.getClass())) {
|
||||
configItem.setApplications(
|
||||
((List<Object>) applications).stream().map(String::valueOf).collect(Collectors.toList()));
|
||||
configItem.setApplications(((List<Object>) applications).stream()
|
||||
.map(String::valueOf).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
Object parameters = map.get(PARAMETERS_KEY);
|
||||
if (parameters != null && Map.class.isAssignableFrom(parameters.getClass())) {
|
||||
configItem.setParameters(((Map<String, Object>) parameters)
|
||||
.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, entry -> entry.getValue()
|
||||
.toString())));
|
||||
configItem.setParameters(((Map<String, Object>) parameters).entrySet()
|
||||
.stream().collect(Collectors.toMap(Map.Entry::getKey, entry -> entry.getValue().toString())));
|
||||
}
|
||||
|
||||
try {
|
||||
|
|
@ -103,12 +102,7 @@ public class ConfigItem {
|
|||
configItem.setMatch(PojoUtils.mapToPojo((Map<String, Object>) match, ConditionMatch.class));
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
logger.error(
|
||||
CLUSTER_FAILED_RECEIVE_RULE,
|
||||
" Failed to parse dynamic configuration rule",
|
||||
String.valueOf(map.get(MATCH_KEY)),
|
||||
"Error occurred when parsing rule component.",
|
||||
t);
|
||||
logger.error(CLUSTER_FAILED_RECEIVE_RULE, " Failed to parse dynamic configuration rule", String.valueOf(map.get(MATCH_KEY)), "Error occurred when parsing rule component.", t);
|
||||
}
|
||||
|
||||
configItem.setSide((String) map.get(SIDE_KEY));
|
||||
|
|
|
|||
|
|
@ -52,8 +52,8 @@ public class ConfiguratorConfig {
|
|||
|
||||
Object configs = map.get(CONFIGS_KEY);
|
||||
if (configs != null && List.class.isAssignableFrom(configs.getClass())) {
|
||||
configuratorConfig.setConfigs(((List<Map<String, Object>>) configs)
|
||||
.stream().map(ConfigItem::parseFromMap).collect(Collectors.toList()));
|
||||
configuratorConfig.setConfigs(((List<Map<String, Object>>) configs).stream()
|
||||
.map(ConfigItem::parseFromMap).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
return configuratorConfig;
|
||||
|
|
|
|||
|
|
@ -50,6 +50,9 @@ public class ParamMatch {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ParamMatch{" + "key='" + key + '\'' + ", value='" + value + '\'' + '}';
|
||||
return "ParamMatch{" +
|
||||
"key='" + key + '\'' +
|
||||
", value='" + value + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@ import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
|
|||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
import org.apache.dubbo.common.threadpool.manager.FrameworkExecutorRepository;
|
||||
import org.apache.dubbo.common.utils.ConcurrentHashSet;
|
||||
import org.apache.dubbo.common.utils.LockUtils;
|
||||
import org.apache.dubbo.common.utils.NetUtils;
|
||||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
import org.apache.dubbo.metrics.event.MetricsEventBus;
|
||||
|
|
@ -57,8 +56,6 @@ import java.util.concurrent.ScheduledFuture;
|
|||
import java.util.concurrent.Semaphore;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER;
|
||||
|
|
@ -125,8 +122,6 @@ public abstract class AbstractDirectory<T> implements Directory<T> {
|
|||
|
||||
private volatile ScheduledFuture<?> connectivityCheckFuture;
|
||||
|
||||
private final ReentrantLock invokerRefreshLock = new ReentrantLock();
|
||||
|
||||
/**
|
||||
* The max count of invokers for each reconnect task select to try to reconnect.
|
||||
*/
|
||||
|
|
@ -165,20 +160,18 @@ public abstract class AbstractDirectory<T> implements Directory<T> {
|
|||
|
||||
// remove some local only parameters
|
||||
applicationModel = url.getOrDefaultApplicationModel();
|
||||
this.queryMap =
|
||||
applicationModel.getBeanFactory().getBean(ClusterUtils.class).mergeLocalParams(queryMap);
|
||||
this.queryMap = applicationModel.getBeanFactory().getBean(ClusterUtils.class).mergeLocalParams(queryMap);
|
||||
|
||||
if (consumerUrl == null) {
|
||||
String host =
|
||||
isNotEmpty(queryMap.get(REGISTER_IP_KEY)) ? queryMap.get(REGISTER_IP_KEY) : this.url.getHost();
|
||||
String host = isNotEmpty(queryMap.get(REGISTER_IP_KEY)) ? queryMap.get(REGISTER_IP_KEY) : this.url.getHost();
|
||||
String path = isNotEmpty(queryMap.get(PATH_KEY)) ? queryMap.get(PATH_KEY) : queryMap.get(INTERFACE_KEY);
|
||||
String consumedProtocol = isNotEmpty(queryMap.get(PROTOCOL_KEY)) ? queryMap.get(PROTOCOL_KEY) : CONSUMER;
|
||||
|
||||
URL consumerUrlFrom = this.url
|
||||
.setHost(host)
|
||||
.setPort(0)
|
||||
.setProtocol(consumedProtocol)
|
||||
.setPath(path);
|
||||
.setHost(host)
|
||||
.setPort(0)
|
||||
.setProtocol(consumedProtocol)
|
||||
.setPath(path);
|
||||
if (isUrlFromRegistry) {
|
||||
// reserve parameters if url is already a consumer url
|
||||
consumerUrlFrom = consumerUrlFrom.clearParameters();
|
||||
|
|
@ -186,23 +179,19 @@ public abstract class AbstractDirectory<T> implements Directory<T> {
|
|||
this.consumerUrl = consumerUrlFrom.addParameters(queryMap);
|
||||
}
|
||||
|
||||
this.connectivityExecutor = applicationModel
|
||||
.getFrameworkModel()
|
||||
.getBeanFactory()
|
||||
.getBean(FrameworkExecutorRepository.class)
|
||||
.getConnectivityScheduledExecutor();
|
||||
this.connectivityExecutor = applicationModel.getFrameworkModel().getBeanFactory()
|
||||
.getBean(FrameworkExecutorRepository.class).getConnectivityScheduledExecutor();
|
||||
Configuration configuration = ConfigurationUtils.getGlobalConfiguration(url.getOrDefaultModuleModel());
|
||||
this.reconnectTaskTryCount = configuration.getInt(RECONNECT_TASK_TRY_COUNT, DEFAULT_RECONNECT_TASK_TRY_COUNT);
|
||||
this.reconnectTaskPeriod = configuration.getInt(RECONNECT_TASK_PERIOD, DEFAULT_RECONNECT_TASK_PERIOD);
|
||||
setRouterChain(routerChain);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Invoker<T>> list(Invocation invocation) throws RpcException {
|
||||
if (destroyed) {
|
||||
throw new RpcException(
|
||||
"Directory of type " + this.getClass().getSimpleName() + " already destroyed for service "
|
||||
+ getConsumerUrl().getServiceKey() + " from registry " + getUrl());
|
||||
throw new RpcException("Directory of type " + this.getClass().getSimpleName() + " already destroyed for service " + getConsumerUrl().getServiceKey() + " from registry " + getUrl());
|
||||
}
|
||||
|
||||
BitList<Invoker<T>> availableInvokers;
|
||||
|
|
@ -233,16 +222,12 @@ public abstract class AbstractDirectory<T> implements Directory<T> {
|
|||
if (routedResult.isEmpty()) {
|
||||
// 2-2 - No provider available.
|
||||
|
||||
logger.warn(
|
||||
CLUSTER_NO_VALID_PROVIDER,
|
||||
"provider server or registry center crashed",
|
||||
"",
|
||||
"No provider available after connectivity filter for the service "
|
||||
+ getConsumerUrl().getServiceKey()
|
||||
+ " All routed invokers' size: " + routedResult.size()
|
||||
+ " from registry " + this
|
||||
+ " on the consumer " + NetUtils.getLocalHost()
|
||||
+ " using the dubbo version " + Version.getVersion() + ".");
|
||||
logger.warn(CLUSTER_NO_VALID_PROVIDER, "provider server or registry center crashed", "",
|
||||
"No provider available after connectivity filter for the service " + getConsumerUrl().getServiceKey()
|
||||
+ " All routed invokers' size: " + routedResult.size()
|
||||
+ " from registry " + this
|
||||
+ " on the consumer " + NetUtils.getLocalHost()
|
||||
+ " using the dubbo version " + Version.getVersion() + ".");
|
||||
}
|
||||
return Collections.unmodifiableList(routedResult);
|
||||
} finally {
|
||||
|
|
@ -298,109 +283,75 @@ public abstract class AbstractDirectory<T> implements Directory<T> {
|
|||
|
||||
@Override
|
||||
public void addInvalidateInvoker(Invoker<T> invoker) {
|
||||
LockUtils.safeLock(invokerRefreshLock, LockUtils.DEFAULT_TIMEOUT, () -> {
|
||||
// 1. remove this invoker from validInvokers list, this invoker will not be listed in the next time
|
||||
if (removeValidInvoker(invoker)) {
|
||||
// 2. add this invoker to reconnect list
|
||||
invokersToReconnect.add(invoker);
|
||||
// 3. try start check connectivity task
|
||||
checkConnectivity();
|
||||
// 1. remove this invoker from validInvokers list, this invoker will not be listed in the next time
|
||||
if (removeValidInvoker(invoker)) {
|
||||
// 2. add this invoker to reconnect list
|
||||
invokersToReconnect.add(invoker);
|
||||
// 3. try start check connectivity task
|
||||
checkConnectivity();
|
||||
|
||||
logger.info("The invoker " + invoker.getUrl()
|
||||
+ " has been added to invalidate list due to connectivity problem. "
|
||||
+ "Will trying to reconnect to it in the background.");
|
||||
}
|
||||
});
|
||||
logger.info("The invoker " + invoker.getUrl() + " has been added to invalidate list due to connectivity problem. " +
|
||||
"Will trying to reconnect to it in the background.");
|
||||
}
|
||||
}
|
||||
|
||||
public void checkConnectivity() {
|
||||
// try to submit task, to ensure there is only one task at most for each directory
|
||||
if (checkConnectivityPermit.tryAcquire()) {
|
||||
this.connectivityCheckFuture = connectivityExecutor.schedule(
|
||||
() -> {
|
||||
try {
|
||||
if (isDestroyed()) {
|
||||
return;
|
||||
this.connectivityCheckFuture = connectivityExecutor.schedule(() -> {
|
||||
try {
|
||||
if (isDestroyed()) {
|
||||
return;
|
||||
}
|
||||
RpcContext.getServiceContext().setConsumerUrl(getConsumerUrl());
|
||||
List<Invoker<T>> needDeleteList = new ArrayList<>();
|
||||
List<Invoker<T>> invokersToTry = new ArrayList<>();
|
||||
|
||||
// 1. pick invokers from invokersToReconnect
|
||||
// limit max reconnectTaskTryCount, prevent this task hang up all the connectivityExecutor for long time
|
||||
if (invokersToReconnect.size() < reconnectTaskTryCount) {
|
||||
invokersToTry.addAll(invokersToReconnect);
|
||||
} else {
|
||||
for (int i = 0; i < reconnectTaskTryCount; i++) {
|
||||
Invoker<T> tInvoker = invokersToReconnect.get(ThreadLocalRandom.current().nextInt(invokersToReconnect.size()));
|
||||
if (!invokersToTry.contains(tInvoker)) {
|
||||
// ignore if is selected, invokersToTry's size is always smaller than reconnectTaskTryCount + 1
|
||||
invokersToTry.add(tInvoker);
|
||||
}
|
||||
RpcContext.getServiceContext().setConsumerUrl(getConsumerUrl());
|
||||
List<Invoker<T>> needDeleteList = new ArrayList<>();
|
||||
List<Invoker<T>> invokersToTry = new ArrayList<>();
|
||||
|
||||
// 1. pick invokers from invokersToReconnect
|
||||
// limit max reconnectTaskTryCount, prevent this task hang up all the connectivityExecutor
|
||||
// for long time
|
||||
LockUtils.safeLock(invokerRefreshLock, LockUtils.DEFAULT_TIMEOUT, () -> {
|
||||
if (invokersToReconnect.size() < reconnectTaskTryCount) {
|
||||
invokersToTry.addAll(invokersToReconnect);
|
||||
} else {
|
||||
for (int i = 0; i < reconnectTaskTryCount; i++) {
|
||||
Invoker<T> tInvoker = invokersToReconnect.get(
|
||||
ThreadLocalRandom.current().nextInt(invokersToReconnect.size()));
|
||||
if (!invokersToTry.contains(tInvoker)) {
|
||||
// ignore if is selected, invokersToTry's size is always smaller than
|
||||
// reconnectTaskTryCount + 1
|
||||
invokersToTry.add(tInvoker);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 2. try to check the invoker's status
|
||||
for (Invoker<T> invoker : invokersToTry) {
|
||||
AtomicBoolean invokerExist = new AtomicBoolean(false);
|
||||
LockUtils.safeLock(invokerRefreshLock, LockUtils.DEFAULT_TIMEOUT, () -> {
|
||||
invokerExist.set(invokers.contains(invoker));
|
||||
});
|
||||
// Should not lock here, `invoker.isAvailable` may need some time to check
|
||||
if (invokerExist.get()) {
|
||||
if (invoker.isAvailable()) {
|
||||
needDeleteList.add(invoker);
|
||||
}
|
||||
} else {
|
||||
needDeleteList.add(invoker);
|
||||
}
|
||||
}
|
||||
|
||||
// 3. recover valid invoker
|
||||
LockUtils.safeLock(invokerRefreshLock, LockUtils.DEFAULT_TIMEOUT, () -> {
|
||||
for (Invoker<T> tInvoker : needDeleteList) {
|
||||
if (invokers.contains(tInvoker)) {
|
||||
addValidInvoker(tInvoker);
|
||||
logger.info("Recover service address: " + tInvoker.getUrl()
|
||||
+ " from invalid list.");
|
||||
} else {
|
||||
logger.info(
|
||||
"The invoker " + tInvoker.getUrl()
|
||||
+ " has been removed from invokers list. Will remove it in reconnect list.");
|
||||
}
|
||||
invokersToReconnect.remove(tInvoker);
|
||||
}
|
||||
});
|
||||
} catch (Throwable t) {
|
||||
logger.error(
|
||||
LoggerCodeConstants.INTERNAL_ERROR,
|
||||
"",
|
||||
"",
|
||||
"Error occurred when check connectivity. ",
|
||||
t);
|
||||
} finally {
|
||||
checkConnectivityPermit.release();
|
||||
}
|
||||
}
|
||||
|
||||
// 4. submit new task if it has more to recover
|
||||
LockUtils.safeLock(invokerRefreshLock, LockUtils.DEFAULT_TIMEOUT, () -> {
|
||||
if (!invokersToReconnect.isEmpty()) {
|
||||
checkConnectivity();
|
||||
// 2. try to check the invoker's status
|
||||
for (Invoker<T> invoker : invokersToTry) {
|
||||
if (invokers.contains(invoker)) {
|
||||
if (invoker.isAvailable()) {
|
||||
needDeleteList.add(invoker);
|
||||
}
|
||||
});
|
||||
MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(
|
||||
applicationModel, getSummary(), getDirectoryMeta()));
|
||||
},
|
||||
reconnectTaskPeriod,
|
||||
TimeUnit.MILLISECONDS);
|
||||
} else {
|
||||
needDeleteList.add(invoker);
|
||||
}
|
||||
}
|
||||
|
||||
// 3. recover valid invoker
|
||||
for (Invoker<T> tInvoker : needDeleteList) {
|
||||
if (invokers.contains(tInvoker)) {
|
||||
addValidInvoker(tInvoker);
|
||||
logger.info("Recover service address: " + tInvoker.getUrl() + " from invalid list.");
|
||||
}
|
||||
invokersToReconnect.remove(tInvoker);
|
||||
}
|
||||
} finally {
|
||||
checkConnectivityPermit.release();
|
||||
}
|
||||
|
||||
// 4. submit new task if it has more to recover
|
||||
if (!invokersToReconnect.isEmpty()) {
|
||||
checkConnectivity();
|
||||
}
|
||||
MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary(), getDirectoryMeta()));
|
||||
}, reconnectTaskPeriod, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
MetricsEventBus.publish(
|
||||
RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary(), getDirectoryMeta()));
|
||||
MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary(), getDirectoryMeta()));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -411,20 +362,17 @@ public abstract class AbstractDirectory<T> implements Directory<T> {
|
|||
* 4. all the invokers disappeared from total invokers should be removed in the disabled invokers list
|
||||
*/
|
||||
public void refreshInvoker() {
|
||||
LockUtils.safeLock(invokerRefreshLock, LockUtils.DEFAULT_TIMEOUT, () -> {
|
||||
if (invokersInitialized) {
|
||||
refreshInvokerInternal();
|
||||
}
|
||||
});
|
||||
MetricsEventBus.publish(
|
||||
RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary(), getDirectoryMeta()));
|
||||
if (invokersInitialized) {
|
||||
refreshInvokerInternal();
|
||||
}
|
||||
MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary(), getDirectoryMeta()));
|
||||
}
|
||||
|
||||
protected Map<String, String> getDirectoryMeta() {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
private void refreshInvokerInternal() {
|
||||
private synchronized void refreshInvokerInternal() {
|
||||
BitList<Invoker<T>> copiedInvokers = invokers.clone();
|
||||
refreshInvokers(copiedInvokers, invokersToReconnect);
|
||||
refreshInvokers(copiedInvokers, disabledInvokers);
|
||||
|
|
@ -445,47 +393,37 @@ public abstract class AbstractDirectory<T> implements Directory<T> {
|
|||
|
||||
@Override
|
||||
public void addDisabledInvoker(Invoker<T> invoker) {
|
||||
LockUtils.safeLock(invokerRefreshLock, LockUtils.DEFAULT_TIMEOUT, () -> {
|
||||
if (invokers.contains(invoker)) {
|
||||
disabledInvokers.add(invoker);
|
||||
removeValidInvoker(invoker);
|
||||
logger.info("Disable service address: " + invoker.getUrl() + ".");
|
||||
}
|
||||
});
|
||||
MetricsEventBus.publish(
|
||||
RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary(), getDirectoryMeta()));
|
||||
if (invokers.contains(invoker)) {
|
||||
disabledInvokers.add(invoker);
|
||||
removeValidInvoker(invoker);
|
||||
logger.info("Disable service address: " + invoker.getUrl() + ".");
|
||||
}
|
||||
MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary(), getDirectoryMeta()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recoverDisabledInvoker(Invoker<T> invoker) {
|
||||
LockUtils.safeLock(invokerRefreshLock, LockUtils.DEFAULT_TIMEOUT, () -> {
|
||||
if (disabledInvokers.remove(invoker)) {
|
||||
try {
|
||||
addValidInvoker(invoker);
|
||||
logger.info("Recover service address: " + invoker.getUrl() + " from disabled list.");
|
||||
} catch (Throwable ignore) {
|
||||
if (disabledInvokers.remove(invoker)) {
|
||||
try {
|
||||
addValidInvoker(invoker);
|
||||
logger.info("Recover service address: " + invoker.getUrl() + " from disabled list.");
|
||||
} catch (Throwable ignore) {
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
MetricsEventBus.publish(
|
||||
RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary(), getDirectoryMeta()));
|
||||
}
|
||||
MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary(), getDirectoryMeta()));
|
||||
}
|
||||
|
||||
protected final void refreshRouter(BitList<Invoker<T>> newlyInvokers, Runnable switchAction) {
|
||||
try {
|
||||
routerChain.setInvokers(newlyInvokers.clone(), switchAction);
|
||||
} catch (Throwable t) {
|
||||
logger.error(
|
||||
LoggerCodeConstants.INTERNAL_ERROR,
|
||||
"",
|
||||
"",
|
||||
"Error occurred when refreshing router chain. " + "The addresses from notification: "
|
||||
+ newlyInvokers.stream()
|
||||
.map(Invoker::getUrl)
|
||||
.map(URL::getAddress)
|
||||
.collect(Collectors.joining(", ")),
|
||||
t);
|
||||
logger.error(LoggerCodeConstants.INTERNAL_ERROR, "", "", "Error occurred when refreshing router chain. " +
|
||||
"The addresses from notification: " +
|
||||
newlyInvokers.stream()
|
||||
.map(Invoker::getUrl)
|
||||
.map(URL::getAddress)
|
||||
.collect(Collectors.joining(", ")), t);
|
||||
|
||||
throw t;
|
||||
}
|
||||
|
|
@ -526,48 +464,40 @@ public abstract class AbstractDirectory<T> implements Directory<T> {
|
|||
}
|
||||
|
||||
protected void setInvokers(BitList<Invoker<T>> invokers) {
|
||||
LockUtils.safeLock(invokerRefreshLock, LockUtils.DEFAULT_TIMEOUT, () -> {
|
||||
this.invokers = invokers;
|
||||
refreshInvokerInternal();
|
||||
this.invokersInitialized = true;
|
||||
});
|
||||
this.invokers = invokers;
|
||||
refreshInvokerInternal();
|
||||
this.invokersInitialized = true;
|
||||
|
||||
MetricsEventBus.publish(
|
||||
RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary(), getDirectoryMeta()));
|
||||
MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary(), getDirectoryMeta()));
|
||||
}
|
||||
|
||||
protected void destroyInvokers() {
|
||||
// set empty instead of clearing to support concurrent access.
|
||||
LockUtils.safeLock(invokerRefreshLock, LockUtils.DEFAULT_TIMEOUT, () -> {
|
||||
this.invokers = BitList.emptyList();
|
||||
this.validInvokers = BitList.emptyList();
|
||||
this.invokersInitialized = false;
|
||||
});
|
||||
this.invokers = BitList.emptyList();
|
||||
this.validInvokers = BitList.emptyList();
|
||||
this.invokersInitialized = false;
|
||||
}
|
||||
|
||||
private boolean addValidInvoker(Invoker<T> invoker) {
|
||||
AtomicBoolean result = new AtomicBoolean(false);
|
||||
LockUtils.safeLock(invokerRefreshLock, LockUtils.DEFAULT_TIMEOUT, () -> {
|
||||
result.set(this.validInvokers.add(invoker));
|
||||
});
|
||||
MetricsEventBus.publish(
|
||||
RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary(), getDirectoryMeta()));
|
||||
return result.get();
|
||||
boolean result;
|
||||
synchronized (this.validInvokers) {
|
||||
result = this.validInvokers.add(invoker);
|
||||
}
|
||||
MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary(), getDirectoryMeta()));
|
||||
return result;
|
||||
}
|
||||
|
||||
private boolean removeValidInvoker(Invoker<T> invoker) {
|
||||
AtomicBoolean result = new AtomicBoolean(false);
|
||||
LockUtils.safeLock(invokerRefreshLock, LockUtils.DEFAULT_TIMEOUT, () -> {
|
||||
result.set(this.validInvokers.remove(invoker));
|
||||
});
|
||||
MetricsEventBus.publish(
|
||||
RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary(), getDirectoryMeta()));
|
||||
return result.get();
|
||||
boolean result;
|
||||
synchronized (this.validInvokers) {
|
||||
result = this.validInvokers.remove(invoker);
|
||||
}
|
||||
MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary(), getDirectoryMeta()));
|
||||
return result;
|
||||
}
|
||||
|
||||
protected abstract List<Invoker<T>> doList(
|
||||
SingleRouterChain<T> singleRouterChain, BitList<Invoker<T>> invokers, Invocation invocation)
|
||||
throws RpcException;
|
||||
protected abstract List<Invoker<T>> doList(SingleRouterChain<T> singleRouterChain,
|
||||
BitList<Invoker<T>> invokers, Invocation invocation) throws RpcException;
|
||||
|
||||
protected String joinValidInvokerAddresses() {
|
||||
BitList<Invoker<T>> validInvokers = getValidInvokers().clone();
|
||||
|
|
@ -575,10 +505,10 @@ public abstract class AbstractDirectory<T> implements Directory<T> {
|
|||
return "empty";
|
||||
}
|
||||
return validInvokers.stream()
|
||||
.limit(5)
|
||||
.map(Invoker::getUrl)
|
||||
.map(URL::getAddress)
|
||||
.collect(Collectors.joining(","));
|
||||
.limit(5)
|
||||
.map(Invoker::getUrl)
|
||||
.map(URL::getAddress)
|
||||
.collect(Collectors.joining(","));
|
||||
}
|
||||
|
||||
private Map<MetricsKey, Map<String, Integer>> getSummary() {
|
||||
|
|
@ -597,27 +527,25 @@ public abstract class AbstractDirectory<T> implements Directory<T> {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Directory(" + "invokers: "
|
||||
+ invokers.size() + "["
|
||||
+ invokers.stream()
|
||||
.map(Invoker::getUrl)
|
||||
.map(URL::getAddress)
|
||||
.limit(3)
|
||||
.collect(Collectors.joining(", "))
|
||||
+ "]" + ", validInvokers: "
|
||||
+ validInvokers.size() + "["
|
||||
+ validInvokers.stream()
|
||||
.map(Invoker::getUrl)
|
||||
.map(URL::getAddress)
|
||||
.limit(3)
|
||||
.collect(Collectors.joining(", "))
|
||||
+ "]" + ", invokersToReconnect: "
|
||||
+ invokersToReconnect.size() + "["
|
||||
+ invokersToReconnect.stream()
|
||||
.map(Invoker::getUrl)
|
||||
.map(URL::getAddress)
|
||||
.limit(3)
|
||||
.collect(Collectors.joining(", "))
|
||||
+ "]" + ')';
|
||||
return "Directory(" +
|
||||
"invokers: " + invokers.size() + "[" +
|
||||
invokers.stream()
|
||||
.map(Invoker::getUrl)
|
||||
.map(URL::getAddress)
|
||||
.limit(3)
|
||||
.collect(Collectors.joining(", ")) + "]" +
|
||||
", validInvokers: " + validInvokers.size() + "[" +
|
||||
validInvokers.stream()
|
||||
.map(Invoker::getUrl)
|
||||
.map(URL::getAddress)
|
||||
.limit(3)
|
||||
.collect(Collectors.joining(", ")) + "]" +
|
||||
", invokersToReconnect: " + invokersToReconnect.size() + "[" +
|
||||
invokersToReconnect.stream()
|
||||
.map(Invoker::getUrl)
|
||||
.map(URL::getAddress)
|
||||
.limit(3)
|
||||
.collect(Collectors.joining(", ")) + "]" +
|
||||
')';
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,12 +55,7 @@ public class StaticDirectory<T> extends AbstractDirectory<T> {
|
|||
}
|
||||
|
||||
public StaticDirectory(URL url, List<Invoker<T>> invokers, RouterChain<T> routerChain) {
|
||||
super(
|
||||
url == null && CollectionUtils.isNotEmpty(invokers)
|
||||
? invokers.get(0).getUrl()
|
||||
: url,
|
||||
routerChain,
|
||||
false);
|
||||
super(url == null && CollectionUtils.isNotEmpty(invokers) ? invokers.get(0).getUrl() : url, routerChain, false);
|
||||
if (CollectionUtils.isEmpty(invokers)) {
|
||||
throw new IllegalArgumentException("invokers == null");
|
||||
}
|
||||
|
|
@ -106,34 +101,28 @@ public class StaticDirectory<T> extends AbstractDirectory<T> {
|
|||
|
||||
public void buildRouterChain() {
|
||||
RouterChain<T> routerChain = RouterChain.buildChain(getInterface(), getUrl());
|
||||
routerChain.setInvokers(getInvokers(), () -> {});
|
||||
routerChain.setInvokers(getInvokers(), () -> {
|
||||
});
|
||||
this.setRouterChain(routerChain);
|
||||
}
|
||||
|
||||
public void notify(List<Invoker<T>> invokers) {
|
||||
BitList<Invoker<T>> bitList = new BitList<>(invokers);
|
||||
if (routerChain != null) {
|
||||
refreshRouter(bitList.clone(), () -> this.setInvokers(bitList));
|
||||
refreshRouter(bitList.clone(), () -> this.setInvokers(bitList));
|
||||
} else {
|
||||
this.setInvokers(bitList);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<Invoker<T>> doList(
|
||||
SingleRouterChain<T> singleRouterChain, BitList<Invoker<T>> invokers, Invocation invocation)
|
||||
throws RpcException {
|
||||
protected List<Invoker<T>> doList(SingleRouterChain<T> singleRouterChain, BitList<Invoker<T>> invokers, Invocation invocation) throws RpcException {
|
||||
if (singleRouterChain != null) {
|
||||
try {
|
||||
List<Invoker<T>> finalInvokers = singleRouterChain.route(getConsumerUrl(), invokers, invocation);
|
||||
return finalInvokers == null ? BitList.emptyList() : finalInvokers;
|
||||
} catch (Throwable t) {
|
||||
logger.error(
|
||||
CLUSTER_FAILED_SITE_SELECTION,
|
||||
"Failed to execute router",
|
||||
"",
|
||||
"Failed to execute router: " + getUrl() + ", cause: " + t.getMessage(),
|
||||
t);
|
||||
logger.error(CLUSTER_FAILED_SITE_SELECTION, "Failed to execute router", "", "Failed to execute router: " + getUrl() + ", cause: " + t.getMessage(), t);
|
||||
return BitList.emptyList();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,14 +47,12 @@ public class DefaultFilterChainBuilder implements FilterChainBuilder {
|
|||
List<ModuleModel> moduleModels = getModuleModelsFromUrl(url);
|
||||
List<Filter> filters;
|
||||
if (moduleModels != null && moduleModels.size() == 1) {
|
||||
filters = ScopeModelUtil.getExtensionLoader(Filter.class, moduleModels.get(0))
|
||||
.getActivateExtension(url, key, group);
|
||||
filters = ScopeModelUtil.getExtensionLoader(Filter.class, moduleModels.get(0)).getActivateExtension(url, key, group);
|
||||
} else if (moduleModels != null && moduleModels.size() > 1) {
|
||||
filters = new ArrayList<>();
|
||||
List<ExtensionDirector> directors = new ArrayList<>();
|
||||
for (ModuleModel moduleModel : moduleModels) {
|
||||
List<Filter> tempFilters = ScopeModelUtil.getExtensionLoader(Filter.class, moduleModel)
|
||||
.getActivateExtension(url, key, group);
|
||||
List<Filter> tempFilters = ScopeModelUtil.getExtensionLoader(Filter.class, moduleModel).getActivateExtension(url, key, group);
|
||||
filters.addAll(tempFilters);
|
||||
directors.add(moduleModel.getExtensionDirector());
|
||||
}
|
||||
|
|
@ -64,6 +62,7 @@ public class DefaultFilterChainBuilder implements FilterChainBuilder {
|
|||
filters = ScopeModelUtil.getExtensionLoader(Filter.class, null).getActivateExtension(url, key, group);
|
||||
}
|
||||
|
||||
|
||||
if (!CollectionUtils.isEmpty(filters)) {
|
||||
for (int i = filters.size() - 1; i >= 0; i--) {
|
||||
final Filter filter = filters.get(i);
|
||||
|
|
@ -80,29 +79,25 @@ public class DefaultFilterChainBuilder implements FilterChainBuilder {
|
|||
* build consumer cluster filter chain
|
||||
*/
|
||||
@Override
|
||||
public <T> ClusterInvoker<T> buildClusterInvokerChain(
|
||||
final ClusterInvoker<T> originalInvoker, String key, String group) {
|
||||
public <T> ClusterInvoker<T> buildClusterInvokerChain(final ClusterInvoker<T> originalInvoker, String key, String group) {
|
||||
ClusterInvoker<T> last = originalInvoker;
|
||||
URL url = originalInvoker.getUrl();
|
||||
List<ModuleModel> moduleModels = getModuleModelsFromUrl(url);
|
||||
List<ClusterFilter> filters;
|
||||
if (moduleModels != null && moduleModels.size() == 1) {
|
||||
filters = ScopeModelUtil.getExtensionLoader(ClusterFilter.class, moduleModels.get(0))
|
||||
.getActivateExtension(url, key, group);
|
||||
filters = ScopeModelUtil.getExtensionLoader(ClusterFilter.class, moduleModels.get(0)).getActivateExtension(url, key, group);
|
||||
} else if (moduleModels != null && moduleModels.size() > 1) {
|
||||
filters = new ArrayList<>();
|
||||
List<ExtensionDirector> directors = new ArrayList<>();
|
||||
for (ModuleModel moduleModel : moduleModels) {
|
||||
List<ClusterFilter> tempFilters = ScopeModelUtil.getExtensionLoader(ClusterFilter.class, moduleModel)
|
||||
.getActivateExtension(url, key, group);
|
||||
List<ClusterFilter> tempFilters = ScopeModelUtil.getExtensionLoader(ClusterFilter.class, moduleModel).getActivateExtension(url, key, group);
|
||||
filters.addAll(tempFilters);
|
||||
directors.add(moduleModel.getExtensionDirector());
|
||||
}
|
||||
filters = sortingAndDeduplication(filters, directors);
|
||||
|
||||
} else {
|
||||
filters =
|
||||
ScopeModelUtil.getExtensionLoader(ClusterFilter.class, null).getActivateExtension(url, key, group);
|
||||
filters = ScopeModelUtil.getExtensionLoader(ClusterFilter.class, null).getActivateExtension(url, key, group);
|
||||
}
|
||||
|
||||
if (!CollectionUtils.isEmpty(filters)) {
|
||||
|
|
@ -146,4 +141,5 @@ public class DefaultFilterChainBuilder implements FilterChainBuilder {
|
|||
}
|
||||
return moduleModels;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -92,8 +92,7 @@ public interface FilterChainBuilder {
|
|||
public Result invoke(Invocation invocation) throws RpcException {
|
||||
Result asyncResult;
|
||||
try {
|
||||
InvocationProfilerUtils.enterDetailProfiler(
|
||||
invocation, () -> "Filter " + filter.getClass().getName() + " invoke.");
|
||||
InvocationProfilerUtils.enterDetailProfiler(invocation, () -> "Filter " + filter.getClass().getName() + " invoke.");
|
||||
asyncResult = filter.invoke(nextNode, invocation);
|
||||
} catch (Exception e) {
|
||||
InvocationProfilerUtils.releaseDetailProfiler(invocation);
|
||||
|
|
@ -160,11 +159,12 @@ public interface FilterChainBuilder {
|
|||
* @param <TYPE>
|
||||
*/
|
||||
class ClusterFilterChainNode<T, TYPE extends ClusterInvoker<T>, FILTER extends BaseFilter>
|
||||
extends FilterChainNode<T, TYPE, FILTER> implements ClusterInvoker<T> {
|
||||
extends FilterChainNode<T, TYPE, FILTER> implements ClusterInvoker<T> {
|
||||
public ClusterFilterChainNode(TYPE originalInvoker, Invoker<T> nextNode, FILTER filter) {
|
||||
super(originalInvoker, nextNode, filter);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public URL getRegistryUrl() {
|
||||
return getOriginalInvoker().getRegistryUrl();
|
||||
|
|
@ -182,8 +182,7 @@ public interface FilterChainBuilder {
|
|||
}
|
||||
|
||||
class CallbackRegistrationInvoker<T, FILTER extends BaseFilter> implements Invoker<T> {
|
||||
private static final ErrorTypeAwareLogger LOGGER =
|
||||
LoggerFactory.getErrorTypeAwareLogger(CallbackRegistrationInvoker.class);
|
||||
private static final ErrorTypeAwareLogger LOGGER = LoggerFactory.getErrorTypeAwareLogger(CallbackRegistrationInvoker.class);
|
||||
final Invoker<T> filterInvoker;
|
||||
final List<FILTER> filters;
|
||||
|
||||
|
|
@ -224,20 +223,9 @@ public interface FilterChainBuilder {
|
|||
}
|
||||
}
|
||||
} catch (RuntimeException runtimeException) {
|
||||
LOGGER.error(
|
||||
CLUSTER_EXECUTE_FILTER_EXCEPTION,
|
||||
"the custom filter is abnormal",
|
||||
"",
|
||||
String.format(
|
||||
"Exception occurred while executing the %s filter named %s.",
|
||||
i, filter.getClass().getSimpleName()));
|
||||
LOGGER.error(CLUSTER_EXECUTE_FILTER_EXCEPTION, "the custom filter is abnormal", "", String.format("Exception occurred while executing the %s filter named %s.", i, filter.getClass().getSimpleName()));
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug(String.format(
|
||||
"Whole filter list is: %s",
|
||||
filters.stream()
|
||||
.map(tmpFilter ->
|
||||
tmpFilter.getClass().getSimpleName())
|
||||
.collect(Collectors.toList())));
|
||||
LOGGER.debug(String.format("Whole filter list is: %s", filters.stream().map(tmpFilter -> tmpFilter.getClass().getSimpleName()).collect(Collectors.toList())));
|
||||
}
|
||||
filterRuntimeException = runtimeException;
|
||||
t = runtimeException;
|
||||
|
|
@ -276,12 +264,11 @@ public interface FilterChainBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
class ClusterCallbackRegistrationInvoker<T, FILTER extends BaseFilter>
|
||||
extends CallbackRegistrationInvoker<T, FILTER> implements ClusterInvoker<T> {
|
||||
class ClusterCallbackRegistrationInvoker<T, FILTER extends BaseFilter> extends CallbackRegistrationInvoker<T, FILTER>
|
||||
implements ClusterInvoker<T> {
|
||||
private ClusterInvoker<T> originalInvoker;
|
||||
|
||||
public ClusterCallbackRegistrationInvoker(
|
||||
ClusterInvoker<T> originalInvoker, Invoker<T> filterInvoker, List<FILTER> filters) {
|
||||
public ClusterCallbackRegistrationInvoker(ClusterInvoker<T> originalInvoker, Invoker<T> filterInvoker, List<FILTER> filters) {
|
||||
super(filterInvoker, filters);
|
||||
this.originalInvoker = originalInvoker;
|
||||
}
|
||||
|
|
@ -306,11 +293,10 @@ public interface FilterChainBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
@Experimental(
|
||||
"Works for the same purpose as FilterChainNode, replace FilterChainNode with this one when proved stable enough")
|
||||
|
||||
@Experimental("Works for the same purpose as FilterChainNode, replace FilterChainNode with this one when proved stable enough")
|
||||
class CopyOfFilterChainNode<T, TYPE extends Invoker<T>, FILTER extends BaseFilter> implements Invoker<T> {
|
||||
private static final ErrorTypeAwareLogger LOGGER =
|
||||
LoggerFactory.getErrorTypeAwareLogger(CopyOfFilterChainNode.class);
|
||||
private static final ErrorTypeAwareLogger LOGGER = LoggerFactory.getErrorTypeAwareLogger(CopyOfFilterChainNode.class);
|
||||
TYPE originalInvoker;
|
||||
Invoker<T> nextNode;
|
||||
FILTER filter;
|
||||
|
|
@ -344,14 +330,11 @@ public interface FilterChainBuilder {
|
|||
public Result invoke(Invocation invocation) throws RpcException {
|
||||
Result asyncResult;
|
||||
try {
|
||||
InvocationProfilerUtils.enterDetailProfiler(
|
||||
invocation, () -> "Filter " + filter.getClass().getName() + " invoke.");
|
||||
InvocationProfilerUtils.enterDetailProfiler(invocation, () -> "Filter " + filter.getClass().getName() + " invoke.");
|
||||
asyncResult = filter.invoke(nextNode, invocation);
|
||||
if (!(asyncResult instanceof AsyncRpcResult)) {
|
||||
String msg =
|
||||
"The result of filter invocation must be AsyncRpcResult. (If you want to recreate a result, please use AsyncRpcResult.newDefaultAsyncResult.) "
|
||||
+ "Filter class: " + filter.getClass().getName() + ". Result class: "
|
||||
+ asyncResult.getClass().getName() + ".";
|
||||
String msg = "The result of filter invocation must be AsyncRpcResult. (If you want to recreate a result, please use AsyncRpcResult.newDefaultAsyncResult.) " +
|
||||
"Filter class: " + filter.getClass().getName() + ". Result class: " + asyncResult.getClass().getName() + ".";
|
||||
LOGGER.error(INTERNAL_ERROR, "", "", msg);
|
||||
throw new RpcException(msg);
|
||||
}
|
||||
|
|
@ -389,14 +372,14 @@ public interface FilterChainBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
@Experimental(
|
||||
"Works for the same purpose as ClusterFilterChainNode, replace ClusterFilterChainNode with this one when proved stable enough")
|
||||
@Experimental("Works for the same purpose as ClusterFilterChainNode, replace ClusterFilterChainNode with this one when proved stable enough")
|
||||
class CopyOfClusterFilterChainNode<T, TYPE extends ClusterInvoker<T>, FILTER extends BaseFilter>
|
||||
extends CopyOfFilterChainNode<T, TYPE, FILTER> implements ClusterInvoker<T> {
|
||||
extends CopyOfFilterChainNode<T, TYPE, FILTER> implements ClusterInvoker<T> {
|
||||
public CopyOfClusterFilterChainNode(TYPE originalInvoker, Invoker<T> nextNode, FILTER filter) {
|
||||
super(originalInvoker, nextNode, filter);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public URL getRegistryUrl() {
|
||||
return getOriginalInvoker().getRegistryUrl();
|
||||
|
|
|
|||
|
|
@ -62,8 +62,7 @@ public class ProtocolFilterWrapper implements Protocol {
|
|||
}
|
||||
|
||||
private <T> FilterChainBuilder getFilterChainBuilder(URL url) {
|
||||
return ScopeModelUtil.getExtensionLoader(FilterChainBuilder.class, url.getScopeModel())
|
||||
.getDefaultExtension();
|
||||
return ScopeModelUtil.getExtensionLoader(FilterChainBuilder.class, url.getScopeModel()).getDefaultExtension();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -84,4 +83,5 @@ public class ProtocolFilterWrapper implements Protocol {
|
|||
public List<ProtocolServer> getServers() {
|
||||
return protocol.getServers();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,11 +27,10 @@ import org.apache.dubbo.rpc.cluster.filter.ClusterFilter;
|
|||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER;
|
||||
|
||||
@Activate(
|
||||
group = {CONSUMER},
|
||||
order = Integer.MIN_VALUE + 100)
|
||||
@Activate(group = {CONSUMER}, order = Integer.MIN_VALUE + 100)
|
||||
public class MetricsConsumerFilter extends MetricsFilter implements ClusterFilter, BaseFilter.Listener {
|
||||
public MetricsConsumerFilter() {}
|
||||
public MetricsConsumerFilter() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
|
||||
|
|
|
|||
|
|
@ -56,4 +56,5 @@ public class DefaultGovernanceRuleRepositoryImpl implements GovernanceRuleReposi
|
|||
private DynamicConfiguration getDynamicConfiguration() {
|
||||
return moduleModel.modelEnvironment().getDynamicConfiguration().orElse(null);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ public interface GovernanceRuleRepository {
|
|||
addListener(key, DEFAULT_GROUP, listener);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@link #removeListener(String, String, ConfigurationListener)}
|
||||
*
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ public abstract class AbstractLoadBalance implements LoadBalance {
|
|||
* @return weight which takes warmup into account
|
||||
*/
|
||||
static int calculateWarmupWeight(int uptime, int warmup, int weight) {
|
||||
int ww = (int) (uptime / ((float) warmup / weight));
|
||||
int ww = (int) ( uptime / ((float) warmup / weight));
|
||||
return ww < 1 ? 1 : (Math.min(ww, weight));
|
||||
}
|
||||
|
||||
|
|
@ -64,6 +64,7 @@ public abstract class AbstractLoadBalance implements LoadBalance {
|
|||
|
||||
protected abstract <T> Invoker<T> doSelect(List<Invoker<T>> invokers, URL url, Invocation invocation);
|
||||
|
||||
|
||||
/**
|
||||
* Get the weight of the invoker's invocation which takes warmup time into account
|
||||
* if the uptime is within the warmup time, the weight will be reduce proportionally
|
||||
|
|
@ -93,7 +94,7 @@ public abstract class AbstractLoadBalance implements LoadBalance {
|
|||
}
|
||||
int warmup = invoker.getUrl().getParameter(WARMUP_KEY, DEFAULT_WARMUP);
|
||||
if (uptime > 0 && uptime < warmup) {
|
||||
weight = calculateWarmupWeight((int) uptime, warmup, weight);
|
||||
weight = calculateWarmupWeight((int)uptime, warmup, weight);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ public class ConsistentHashLoadBalance extends AbstractLoadBalance {
|
|||
*/
|
||||
public static final String HASH_ARGUMENTS = "hash.arguments";
|
||||
|
||||
private final ConcurrentMap<String, ConsistentHashSelector<?>> selectors = new ConcurrentHashMap<>();
|
||||
private final ConcurrentMap<String, ConsistentHashSelector<?>> selectors = new ConcurrentHashMap<String, ConsistentHashSelector<?>>();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
|
|
@ -74,7 +74,7 @@ public class ConsistentHashLoadBalance extends AbstractLoadBalance {
|
|||
private final int[] argumentIndex;
|
||||
|
||||
ConsistentHashSelector(List<Invoker<T>> invokers, String methodName, int identityHashCode) {
|
||||
this.virtualInvokers = new TreeMap<>();
|
||||
this.virtualInvokers = new TreeMap<Long, Invoker<T>>();
|
||||
this.identityHashCode = identityHashCode;
|
||||
URL url = invokers.get(0).getUrl();
|
||||
this.replicaNumber = url.getMethodParameter(methodName, HASH_NODES, 160);
|
||||
|
|
@ -96,12 +96,14 @@ public class ConsistentHashLoadBalance extends AbstractLoadBalance {
|
|||
}
|
||||
|
||||
public Invoker<T> select(Invocation invocation) {
|
||||
String key = toKey(RpcUtils.getArguments(invocation));
|
||||
|
||||
byte[] digest = Bytes.getMD5(key);
|
||||
byte[] digest = Bytes.getMD5(RpcUtils.getMethodName(invocation));
|
||||
return selectForKey(hash(digest, 0));
|
||||
}
|
||||
|
||||
private String toKey(Object[] args, boolean isGeneric) {
|
||||
return isGeneric ? toKey((Object[]) args[1]) : toKey(args);
|
||||
}
|
||||
|
||||
private String toKey(Object[] args) {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
for (int i : argumentIndex) {
|
||||
|
|
@ -122,10 +124,11 @@ public class ConsistentHashLoadBalance extends AbstractLoadBalance {
|
|||
|
||||
private long hash(byte[] digest, int number) {
|
||||
return (((long) (digest[3 + number * 4] & 0xFF) << 24)
|
||||
| ((long) (digest[2 + number * 4] & 0xFF) << 16)
|
||||
| ((long) (digest[1 + number * 4] & 0xFF) << 8)
|
||||
| (digest[number * 4] & 0xFF))
|
||||
| ((long) (digest[2 + number * 4] & 0xFF) << 16)
|
||||
| ((long) (digest[1 + number * 4] & 0xFF) << 8)
|
||||
| (digest[number * 4] & 0xFF))
|
||||
& 0xFFFFFFFFL;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,18 +56,17 @@ public class LeastActiveLoadBalance extends AbstractLoadBalance {
|
|||
// Every least active invoker has the same weight value?
|
||||
boolean sameWeight = true;
|
||||
|
||||
|
||||
// Filter out all the least active invokers
|
||||
for (int i = 0; i < length; i++) {
|
||||
Invoker<T> invoker = invokers.get(i);
|
||||
// Get the active number of the invoker
|
||||
int active = RpcStatus.getStatus(invoker.getUrl(), RpcUtils.getMethodName(invocation))
|
||||
.getActive();
|
||||
int active = RpcStatus.getStatus(invoker.getUrl(), RpcUtils.getMethodName(invocation)).getActive();
|
||||
// Get the weight of the invoker's configuration. The default value is 100.
|
||||
int afterWarmup = getWeight(invoker, invocation);
|
||||
// save for later use
|
||||
weights[i] = afterWarmup;
|
||||
// If it is the first invoker or the active number of the invoker is less than the current least active
|
||||
// number
|
||||
// If it is the first invoker or the active number of the invoker is less than the current least active number
|
||||
if (leastActive == -1 || active < leastActive) {
|
||||
// Reset the active number of the current invoker to the least active number
|
||||
leastActive = active;
|
||||
|
|
|
|||
|
|
@ -78,8 +78,7 @@ public class RandomLoadBalance extends AbstractLoadBalance {
|
|||
}
|
||||
}
|
||||
if (totalWeight > 0 && !sameWeight) {
|
||||
// If (not every invoker has the same weight & at least one invoker's weight>0), select randomly based on
|
||||
// totalWeight.
|
||||
// If (not every invoker has the same weight & at least one invoker's weight>0), select randomly based on totalWeight.
|
||||
int offset = ThreadLocalRandom.current().nextInt(totalWeight);
|
||||
// Return an invoker based on the random value.
|
||||
if (length <= 4) {
|
||||
|
|
@ -93,7 +92,7 @@ public class RandomLoadBalance extends AbstractLoadBalance {
|
|||
if (i < 0) {
|
||||
i = -i - 1;
|
||||
} else {
|
||||
while (weights[i + 1] == offset) {
|
||||
while (weights[i+1] == offset) {
|
||||
i++;
|
||||
}
|
||||
i++;
|
||||
|
|
|
|||
|
|
@ -37,8 +37,7 @@ public class RoundRobinLoadBalance extends AbstractLoadBalance {
|
|||
|
||||
private static final int RECYCLE_PERIOD = 60000;
|
||||
|
||||
private final ConcurrentMap<String, ConcurrentMap<String, WeightedRoundRobin>> methodWeightMap =
|
||||
new ConcurrentHashMap<>();
|
||||
private final ConcurrentMap<String, ConcurrentMap<String, WeightedRoundRobin>> methodWeightMap = new ConcurrentHashMap<>();
|
||||
|
||||
protected static class WeightedRoundRobin {
|
||||
private int weight;
|
||||
|
|
@ -92,8 +91,7 @@ public class RoundRobinLoadBalance extends AbstractLoadBalance {
|
|||
@Override
|
||||
protected <T> Invoker<T> doSelect(List<Invoker<T>> invokers, URL url, Invocation invocation) {
|
||||
String key = invokers.get(0).getUrl().getServiceKey() + "." + RpcUtils.getMethodName(invocation);
|
||||
ConcurrentMap<String, WeightedRoundRobin> map =
|
||||
ConcurrentHashMapUtils.computeIfAbsent(methodWeightMap, key, k -> new ConcurrentHashMap<>());
|
||||
ConcurrentMap<String, WeightedRoundRobin> map = ConcurrentHashMapUtils.computeIfAbsent(methodWeightMap, key, k -> new ConcurrentHashMap<>());
|
||||
int totalWeight = 0;
|
||||
long maxCurrent = Long.MIN_VALUE;
|
||||
long now = System.currentTimeMillis();
|
||||
|
|
@ -109,7 +107,7 @@ public class RoundRobinLoadBalance extends AbstractLoadBalance {
|
|||
});
|
||||
|
||||
if (weight != weightedRoundRobin.getWeight()) {
|
||||
// weight changed
|
||||
//weight changed
|
||||
weightedRoundRobin.setWeight(weight);
|
||||
}
|
||||
long cur = weightedRoundRobin.increaseCurrent();
|
||||
|
|
@ -131,4 +129,5 @@ public class RoundRobinLoadBalance extends AbstractLoadBalance {
|
|||
// should not happen here
|
||||
return invokers.get(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,15 +59,9 @@ public class ShortestResponseLoadBalance extends AbstractLoadBalance implements
|
|||
|
||||
@Override
|
||||
public void setApplicationModel(ApplicationModel applicationModel) {
|
||||
slidePeriod = applicationModel
|
||||
.modelEnvironment()
|
||||
.getConfiguration()
|
||||
.getInt(Constants.SHORTEST_RESPONSE_SLIDE_PERIOD, 30_000);
|
||||
executorService = applicationModel
|
||||
.getFrameworkModel()
|
||||
.getBeanFactory()
|
||||
.getBean(FrameworkExecutorRepository.class)
|
||||
.getSharedExecutor();
|
||||
slidePeriod = applicationModel.modelEnvironment().getConfiguration().getInt(Constants.SHORTEST_RESPONSE_SLIDE_PERIOD, 30_000);
|
||||
executorService = applicationModel.getFrameworkModel().getBeanFactory()
|
||||
.getBean(FrameworkExecutorRepository.class).getSharedExecutor();
|
||||
}
|
||||
|
||||
protected static class SlideWindowData {
|
||||
|
|
@ -124,11 +118,9 @@ public class ShortestResponseLoadBalance extends AbstractLoadBalance implements
|
|||
for (int i = 0; i < length; i++) {
|
||||
Invoker<T> invoker = invokers.get(i);
|
||||
RpcStatus rpcStatus = RpcStatus.getStatus(invoker.getUrl(), RpcUtils.getMethodName(invocation));
|
||||
SlideWindowData slideWindowData =
|
||||
ConcurrentHashMapUtils.computeIfAbsent(methodMap, rpcStatus, SlideWindowData::new);
|
||||
SlideWindowData slideWindowData = ConcurrentHashMapUtils.computeIfAbsent(methodMap, rpcStatus, SlideWindowData::new);
|
||||
|
||||
// Calculate the estimated response time from the product of active connections and succeeded average
|
||||
// elapsed time.
|
||||
// Calculate the estimated response time from the product of active connections and succeeded average elapsed time.
|
||||
long estimateResponse = slideWindowData.getEstimateResponse();
|
||||
int afterWarmup = getWeight(invoker, invocation);
|
||||
weights[i] = afterWarmup;
|
||||
|
|
@ -143,15 +135,16 @@ public class ShortestResponseLoadBalance extends AbstractLoadBalance implements
|
|||
} else if (estimateResponse == shortestResponse) {
|
||||
shortestIndexes[shortestCount++] = i;
|
||||
totalWeight += afterWarmup;
|
||||
if (sameWeight && i > 0 && afterWarmup != firstWeight) {
|
||||
if (sameWeight && i > 0
|
||||
&& afterWarmup != firstWeight) {
|
||||
sameWeight = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (System.currentTimeMillis() - lastUpdateTime > slidePeriod
|
||||
&& onResetSlideWindow.compareAndSet(false, true)) {
|
||||
// reset slideWindowData in async way
|
||||
&& onResetSlideWindow.compareAndSet(false, true)) {
|
||||
//reset slideWindowData in async way
|
||||
executorService.execute(() -> {
|
||||
methodMap.values().forEach(SlideWindowData::reset);
|
||||
lastUpdateTime = System.currentTimeMillis();
|
||||
|
|
|
|||
|
|
@ -28,13 +28,12 @@ public abstract class AbstractRouter implements Router {
|
|||
private GovernanceRuleRepository ruleRepository;
|
||||
|
||||
public AbstractRouter(URL url) {
|
||||
this.ruleRepository = url.getOrDefaultModuleModel()
|
||||
.getExtensionLoader(GovernanceRuleRepository.class)
|
||||
.getDefaultExtension();
|
||||
this.ruleRepository = url.getOrDefaultModuleModel().getExtensionLoader(GovernanceRuleRepository.class).getDefaultExtension();
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public AbstractRouter() {}
|
||||
public AbstractRouter() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL getUrl() {
|
||||
|
|
@ -68,7 +67,8 @@ public abstract class AbstractRouter implements Router {
|
|||
this.priority = priority;
|
||||
}
|
||||
|
||||
public GovernanceRuleRepository getRuleRepository() {
|
||||
public GovernanceRuleRepository getRuleRepository(){
|
||||
return this.ruleRepository;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER;
|
|||
public class RouterSnapshotFilter implements ClusterFilter, BaseFilter.Listener {
|
||||
|
||||
private final RouterSnapshotSwitcher switcher;
|
||||
private static final Logger logger = LoggerFactory.getLogger(RouterSnapshotFilter.class);
|
||||
private final static Logger logger = LoggerFactory.getLogger(RouterSnapshotFilter.class);
|
||||
|
||||
public RouterSnapshotFilter(FrameworkModel frameworkModel) {
|
||||
this.switcher = frameworkModel.getBeanFactory().getBean(RouterSnapshotSwitcher.class);
|
||||
|
|
|
|||
|
|
@ -114,55 +114,43 @@ public class RouterSnapshotNode<T> {
|
|||
|
||||
public String toString(int level) {
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
stringBuilder
|
||||
.append("[ ")
|
||||
.append(name)
|
||||
.append(' ')
|
||||
.append("(Input: ")
|
||||
.append(beforeSize)
|
||||
.append(") ")
|
||||
.append("(Current Node Output: ")
|
||||
.append(nodeOutputSize)
|
||||
.append(") ")
|
||||
.append("(Chain Node Output: ")
|
||||
.append(chainOutputSize)
|
||||
.append(')')
|
||||
.append(routerMessage == null ? "" : " Router message: ")
|
||||
.append(routerMessage == null ? "" : routerMessage)
|
||||
.append(" ] ");
|
||||
stringBuilder.append("[ ")
|
||||
.append(name)
|
||||
.append(' ')
|
||||
.append("(Input: ").append(beforeSize).append(") ")
|
||||
.append("(Current Node Output: ").append(nodeOutputSize).append(") ")
|
||||
.append("(Chain Node Output: ").append(chainOutputSize).append(')')
|
||||
.append(routerMessage == null ? "" : " Router message: ")
|
||||
.append(routerMessage == null ? "" : routerMessage)
|
||||
.append(" ] ");
|
||||
if (level == 1) {
|
||||
stringBuilder
|
||||
.append("Input: ")
|
||||
.append(
|
||||
CollectionUtils.isEmpty(inputInvokers)
|
||||
? "Empty"
|
||||
: inputInvokers.subList(0, Math.min(5, inputInvokers.size())).stream()
|
||||
.map(Invoker::getUrl)
|
||||
.map(URL::getAddress)
|
||||
.collect(Collectors.joining(",")))
|
||||
.append(" -> ");
|
||||
stringBuilder.append("Input: ")
|
||||
.append(CollectionUtils.isEmpty(inputInvokers) ? "Empty" :
|
||||
inputInvokers.subList(0, Math.min(5, inputInvokers.size()))
|
||||
.stream()
|
||||
.map(Invoker::getUrl)
|
||||
.map(URL::getAddress)
|
||||
.collect(Collectors.joining(",")))
|
||||
.append(" -> ");
|
||||
|
||||
stringBuilder
|
||||
.append("Chain Node Output: ")
|
||||
.append(
|
||||
CollectionUtils.isEmpty(chainOutputInvokers)
|
||||
? "Empty"
|
||||
: chainOutputInvokers.subList(0, Math.min(5, chainOutputInvokers.size())).stream()
|
||||
.map(Invoker::getUrl)
|
||||
.map(URL::getAddress)
|
||||
.collect(Collectors.joining(",")));
|
||||
stringBuilder.append("Chain Node Output: ")
|
||||
.append(CollectionUtils.isEmpty(chainOutputInvokers) ? "Empty" :
|
||||
chainOutputInvokers.subList(0, Math.min(5, chainOutputInvokers.size()))
|
||||
.stream()
|
||||
.map(Invoker::getUrl)
|
||||
.map(URL::getAddress)
|
||||
.collect(Collectors.joining(",")));
|
||||
} else {
|
||||
stringBuilder
|
||||
.append("Current Node Output: ")
|
||||
.append(
|
||||
CollectionUtils.isEmpty(nodeOutputInvokers)
|
||||
? "Empty"
|
||||
: nodeOutputInvokers.subList(0, Math.min(5, nodeOutputInvokers.size())).stream()
|
||||
.map(Invoker::getUrl)
|
||||
.map(URL::getAddress)
|
||||
.collect(Collectors.joining(",")));
|
||||
stringBuilder.append("Current Node Output: ")
|
||||
.append(CollectionUtils.isEmpty(nodeOutputInvokers) ? "Empty" :
|
||||
nodeOutputInvokers.subList(0, Math.min(5, nodeOutputInvokers.size()))
|
||||
.stream()
|
||||
.map(Invoker::getUrl)
|
||||
.map(URL::getAddress)
|
||||
.collect(Collectors.joining(",")));
|
||||
}
|
||||
|
||||
|
||||
if (nodeOutputInvokers != null && nodeOutputInvokers.size() > 5) {
|
||||
stringBuilder.append("...");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ public class RouterSnapshotSwitcher {
|
|||
private volatile boolean enable;
|
||||
private final Set<String> enabledService = new ConcurrentHashSet<>();
|
||||
|
||||
private static final int MAX_LENGTH = 1 << 5; // 2 ^ 5 = 31
|
||||
private final static int MAX_LENGTH = 1 << 5; // 2 ^ 5 = 31
|
||||
|
||||
private final AtomicInteger offset = new AtomicInteger(0);
|
||||
private volatile String[] recentSnapshot = new String[MAX_LENGTH];
|
||||
|
|
|
|||
|
|
@ -62,14 +62,7 @@ public class AddressMatch {
|
|||
try {
|
||||
return input.equals(getCird()) || matchIpExpression(getCird(), input);
|
||||
} catch (UnknownHostException e) {
|
||||
logger.error(
|
||||
CLUSTER_FAILED_EXEC_CONDITION_ROUTER,
|
||||
"Executing routing rule match expression error.",
|
||||
"",
|
||||
String.format(
|
||||
"Error trying to match cird formatted address %s with input %s in AddressMatch.",
|
||||
getCird(), input),
|
||||
e);
|
||||
logger.error(CLUSTER_FAILED_EXEC_CONDITION_ROUTER, "Executing routing rule match expression error.", "", String.format("Error trying to match cird formatted address %s with input %s in AddressMatch.", getCird(), input), e);
|
||||
}
|
||||
}
|
||||
if (getWildcard() != null && input != null) {
|
||||
|
|
|
|||
|
|
@ -14,8 +14,10 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.dubbo.rpc.cluster.router.mesh.rule.virtualservice.match;
|
||||
|
||||
|
||||
public class BoolMatch {
|
||||
private Boolean exact;
|
||||
|
||||
|
|
@ -27,8 +29,8 @@ public class BoolMatch {
|
|||
this.exact = exact;
|
||||
}
|
||||
|
||||
public boolean isMatch(boolean input) {
|
||||
if (exact != null) {
|
||||
public boolean isMatch(boolean input){
|
||||
if (exact != null){
|
||||
return input == exact;
|
||||
}
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -14,8 +14,10 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.dubbo.rpc.cluster.router.mesh.rule.virtualservice.match;
|
||||
|
||||
|
||||
public class DoubleMatch {
|
||||
private Double exact;
|
||||
private DoubleRangeMatch range;
|
||||
|
|
@ -45,6 +47,7 @@ public class DoubleMatch {
|
|||
this.mod = mod;
|
||||
}
|
||||
|
||||
|
||||
public boolean isMatch(Double input) {
|
||||
if (exact != null && mod == null) {
|
||||
return input.equals(exact);
|
||||
|
|
|
|||
|
|
@ -14,8 +14,10 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.dubbo.rpc.cluster.router.mesh.rule.virtualservice.match;
|
||||
|
||||
|
||||
public class DoubleRangeMatch {
|
||||
private Double start;
|
||||
private Double end;
|
||||
|
|
@ -36,6 +38,7 @@ public class DoubleRangeMatch {
|
|||
this.end = end;
|
||||
}
|
||||
|
||||
|
||||
public boolean isMatch(Double input) {
|
||||
if (start != null && end != null) {
|
||||
return input.compareTo(start) >= 0 && input.compareTo(end) < 0;
|
||||
|
|
|
|||
|
|
@ -14,8 +14,10 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.dubbo.rpc.cluster.router.mesh.rule.virtualservice.match;
|
||||
|
||||
|
||||
public class DubboMethodArg {
|
||||
private int index;
|
||||
private String type;
|
||||
|
|
@ -77,11 +79,12 @@ public class DubboMethodArg {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "DubboMethodArg{" + "index="
|
||||
+ index + ", type='"
|
||||
+ type + '\'' + ", str_value="
|
||||
+ str_value + ", num_value="
|
||||
+ num_value + ", bool_value="
|
||||
+ bool_value + '}';
|
||||
return "DubboMethodArg{" +
|
||||
"index=" + index +
|
||||
", type='" + type + '\'' +
|
||||
", str_value=" + str_value +
|
||||
", num_value=" + num_value +
|
||||
", bool_value=" + bool_value +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.dubbo.rpc.cluster.router.mesh.rule.virtualservice.match;
|
||||
|
||||
import org.apache.dubbo.rpc.Invocation;
|
||||
|
|
@ -22,6 +23,7 @@ import org.apache.dubbo.rpc.support.RpcUtils;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
public class DubboMethodMatch {
|
||||
private StringMatch name_match;
|
||||
private Integer argc;
|
||||
|
|
@ -71,12 +73,13 @@ public class DubboMethodMatch {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "DubboMethodMatch{" + "name_match="
|
||||
+ name_match + ", argc="
|
||||
+ argc + ", args="
|
||||
+ args + ", argp="
|
||||
+ argp + ", headers="
|
||||
+ headers + '}';
|
||||
return "DubboMethodMatch{" +
|
||||
"name_match=" + name_match +
|
||||
", argc=" + argc +
|
||||
", args=" + args +
|
||||
", argp=" + argp +
|
||||
", headers=" + headers +
|
||||
'}';
|
||||
}
|
||||
|
||||
public boolean isMatch(Invocation invocation) {
|
||||
|
|
@ -87,8 +90,8 @@ public class DubboMethodMatch {
|
|||
|
||||
Integer argc = getArgc();
|
||||
Object[] arguments = invocation.getArguments();
|
||||
if (argc != null
|
||||
&& ((argc != 0 && (arguments == null || arguments.length == 0)) || (argc != arguments.length))) {
|
||||
if (argc != null &&
|
||||
((argc != 0 && (arguments == null || arguments.length == 0)) || (argc != arguments.length))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -104,7 +107,7 @@ public class DubboMethodMatch {
|
|||
|
||||
for (int index = 0; index < argp.size(); index++) {
|
||||
boolean match = argp.get(index).isMatch(parameterTypes[index].getName())
|
||||
|| argp.get(index).isMatch(parameterTypes[index].getSimpleName());
|
||||
|| argp.get(index).isMatch(parameterTypes[index].getSimpleName());
|
||||
if (!match) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -131,3 +134,4 @@ public class DubboMethodMatch {
|
|||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,8 +14,10 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.dubbo.rpc.cluster.router.mesh.rule.virtualservice.match;
|
||||
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ListBoolMatch {
|
||||
|
|
@ -39,3 +41,4 @@ public class ListBoolMatch {
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,10 +14,12 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.dubbo.rpc.cluster.router.mesh.rule.virtualservice.match;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class ListDoubleMatch {
|
||||
private List<DoubleMatch> oneof;
|
||||
|
||||
|
|
|
|||
|
|
@ -14,10 +14,12 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.dubbo.rpc.cluster.router.mesh.rule.virtualservice.match;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class ListStringMatch {
|
||||
private List<StringMatch> oneof;
|
||||
|
||||
|
|
@ -29,6 +31,7 @@ public class ListStringMatch {
|
|||
this.oneof = oneof;
|
||||
}
|
||||
|
||||
|
||||
public boolean isMatch(String input) {
|
||||
|
||||
for (StringMatch stringMatch : oneof) {
|
||||
|
|
|
|||
|
|
@ -14,8 +14,10 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.dubbo.rpc.cluster.router.mesh.rule.virtualservice.match;
|
||||
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.ANY_VALUE;
|
||||
|
||||
public class StringMatch {
|
||||
|
|
@ -26,6 +28,7 @@ public class StringMatch {
|
|||
private String empty;
|
||||
private String wildcard;
|
||||
|
||||
|
||||
public String getExact() {
|
||||
return exact;
|
||||
}
|
||||
|
|
@ -95,11 +98,12 @@ public class StringMatch {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "StringMatch{" + "exact='"
|
||||
+ exact + '\'' + ", prefix='"
|
||||
+ prefix + '\'' + ", regex='"
|
||||
+ regex + '\'' + ", noempty='"
|
||||
+ noempty + '\'' + ", empty='"
|
||||
+ empty + '\'' + '}';
|
||||
return "StringMatch{" +
|
||||
"exact='" + exact + '\'' +
|
||||
", prefix='" + prefix + '\'' +
|
||||
", regex='" + regex + '\'' +
|
||||
", noempty='" + noempty + '\'' +
|
||||
", empty='" + empty + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,11 +47,9 @@ public abstract class AbstractStateRouter<T> implements StateRouter<T> {
|
|||
|
||||
public AbstractStateRouter(URL url) {
|
||||
moduleModel = url.getOrDefaultModuleModel();
|
||||
this.ruleRepository =
|
||||
moduleModel.getExtensionLoader(GovernanceRuleRepository.class).getDefaultExtension();
|
||||
this.ruleRepository = moduleModel.getExtensionLoader(GovernanceRuleRepository.class).getDefaultExtension();
|
||||
this.url = url;
|
||||
this.shouldFailFast = Boolean.parseBoolean(
|
||||
ConfigurationUtils.getProperty(moduleModel, Constants.SHOULD_FAIL_FAST_KEY, "true"));
|
||||
this.shouldFailFast = Boolean.parseBoolean(ConfigurationUtils.getProperty(moduleModel, Constants.SHOULD_FAIL_FAST_KEY, "true"));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -91,13 +89,7 @@ public abstract class AbstractStateRouter<T> implements StateRouter<T> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public final BitList<Invoker<T>> route(
|
||||
BitList<Invoker<T>> invokers,
|
||||
URL url,
|
||||
Invocation invocation,
|
||||
boolean needToPrintMessage,
|
||||
Holder<RouterSnapshotNode<T>> nodeHolder)
|
||||
throws RpcException {
|
||||
public final BitList<Invoker<T>> route(BitList<Invoker<T>> invokers, URL url, Invocation invocation, boolean needToPrintMessage, Holder<RouterSnapshotNode<T>> nodeHolder) throws RpcException {
|
||||
if (needToPrintMessage && (nodeHolder == null || nodeHolder.get() == null)) {
|
||||
needToPrintMessage = false;
|
||||
}
|
||||
|
|
@ -159,26 +151,17 @@ public abstract class AbstractStateRouter<T> implements StateRouter<T> {
|
|||
* @param messageHolder message holder when router should current router print message
|
||||
* @return routed result
|
||||
*/
|
||||
protected abstract BitList<Invoker<T>> doRoute(
|
||||
BitList<Invoker<T>> invokers,
|
||||
URL url,
|
||||
Invocation invocation,
|
||||
boolean needToPrintMessage,
|
||||
Holder<RouterSnapshotNode<T>> nodeHolder,
|
||||
Holder<String> messageHolder)
|
||||
throws RpcException;
|
||||
protected abstract BitList<Invoker<T>> doRoute(BitList<Invoker<T>> invokers, URL url, Invocation invocation,
|
||||
boolean needToPrintMessage, Holder<RouterSnapshotNode<T>> nodeHolder,
|
||||
Holder<String> messageHolder) throws RpcException;
|
||||
|
||||
/**
|
||||
* Call next router to get result
|
||||
*
|
||||
* @param invokers current router filtered invokers
|
||||
*/
|
||||
protected final BitList<Invoker<T>> continueRoute(
|
||||
BitList<Invoker<T>> invokers,
|
||||
URL url,
|
||||
Invocation invocation,
|
||||
boolean needToPrintMessage,
|
||||
Holder<RouterSnapshotNode<T>> nodeHolder) {
|
||||
protected final BitList<Invoker<T>> continueRoute(BitList<Invoker<T>> invokers, URL url, Invocation invocation,
|
||||
boolean needToPrintMessage, Holder<RouterSnapshotNode<T>> nodeHolder) {
|
||||
if (nextRouter != null) {
|
||||
return nextRouter.route(invokers, url, invocation, needToPrintMessage, nodeHolder);
|
||||
} else {
|
||||
|
|
@ -209,7 +192,9 @@ public abstract class AbstractStateRouter<T> implements StateRouter<T> {
|
|||
|
||||
@Override
|
||||
public final String buildSnapshot() {
|
||||
return doBuildSnapshot() + " v \n" + nextRouter.buildSnapshot();
|
||||
return doBuildSnapshot() +
|
||||
" v \n" +
|
||||
nextRouter.buildSnapshot();
|
||||
}
|
||||
|
||||
protected String doBuildSnapshot() {
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ import java.util.concurrent.ThreadLocalRandom;
|
|||
public class BitList<E> extends AbstractList<E> implements Cloneable {
|
||||
private final BitSet rootSet;
|
||||
private volatile List<E> originList;
|
||||
private static final BitList emptyList = new BitList(Collections.emptyList());
|
||||
private final static BitList emptyList = new BitList(Collections.emptyList());
|
||||
private volatile List<E> tailList = null;
|
||||
|
||||
public BitList(List<E> originList) {
|
||||
|
|
@ -93,23 +93,23 @@ public class BitList<E> extends AbstractList<E> implements Cloneable {
|
|||
}
|
||||
|
||||
// Provided by BitList only
|
||||
public synchronized List<E> getOriginList() {
|
||||
public List<E> getOriginList() {
|
||||
return originList;
|
||||
}
|
||||
|
||||
public synchronized void addIndex(int index) {
|
||||
public void addIndex(int index) {
|
||||
this.rootSet.set(index);
|
||||
}
|
||||
|
||||
public synchronized int totalSetSize() {
|
||||
public int totalSetSize() {
|
||||
return this.originList.size();
|
||||
}
|
||||
|
||||
public synchronized boolean indexExist(int index) {
|
||||
public boolean indexExist(int index) {
|
||||
return this.rootSet.get(index);
|
||||
}
|
||||
|
||||
public synchronized E getByIndex(int index) {
|
||||
public E getByIndex(int index) {
|
||||
return this.originList.get(index);
|
||||
}
|
||||
|
||||
|
|
@ -120,7 +120,7 @@ public class BitList<E> extends AbstractList<E> implements Cloneable {
|
|||
* @param target target bitList
|
||||
* @return this bitList only contains those elements contain in both two list and source bitList's tailList
|
||||
*/
|
||||
public synchronized BitList<E> and(BitList<E> target) {
|
||||
public BitList<E> and(BitList<E> target) {
|
||||
rootSet.and(target.rootSet);
|
||||
if (target.getTailList() != null) {
|
||||
target.getTailList().forEach(this::addToTailList);
|
||||
|
|
@ -128,28 +128,28 @@ public class BitList<E> extends AbstractList<E> implements Cloneable {
|
|||
return this;
|
||||
}
|
||||
|
||||
public synchronized BitList<E> or(BitList<E> target) {
|
||||
public BitList<E> or(BitList<E> target) {
|
||||
BitSet resultSet = (BitSet) rootSet.clone();
|
||||
resultSet.or(target.rootSet);
|
||||
return new BitList<>(originList, resultSet, tailList);
|
||||
}
|
||||
|
||||
public synchronized boolean hasMoreElementInTailList() {
|
||||
public boolean hasMoreElementInTailList() {
|
||||
return CollectionUtils.isNotEmpty(tailList);
|
||||
}
|
||||
|
||||
public synchronized List<E> getTailList() {
|
||||
public List<E> getTailList() {
|
||||
return tailList;
|
||||
}
|
||||
|
||||
public synchronized void addToTailList(E e) {
|
||||
public void addToTailList(E e) {
|
||||
if (tailList == null) {
|
||||
tailList = new LinkedList<>();
|
||||
}
|
||||
tailList.add(e);
|
||||
}
|
||||
|
||||
public synchronized E randomSelectOne() {
|
||||
public E randomSelectOne() {
|
||||
int originSize = originList.size();
|
||||
int tailSize = tailList != null ? tailList.size() : 0;
|
||||
int totalSize = originSize + tailSize;
|
||||
|
|
@ -181,18 +181,18 @@ public class BitList<E> extends AbstractList<E> implements Cloneable {
|
|||
|
||||
// Provided by JDK List interface
|
||||
@Override
|
||||
public synchronized int size() {
|
||||
public int size() {
|
||||
return rootSet.cardinality() + (CollectionUtils.isNotEmpty(tailList) ? tailList.size() : 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean contains(Object o) {
|
||||
public boolean contains(Object o) {
|
||||
int idx = originList.indexOf(o);
|
||||
return (idx >= 0 && rootSet.get(idx)) || (CollectionUtils.isNotEmpty(tailList) && tailList.contains(o));
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Iterator<E> iterator() {
|
||||
public Iterator<E> iterator() {
|
||||
return new BitListIterator<>(this, 0);
|
||||
}
|
||||
|
||||
|
|
@ -205,7 +205,7 @@ public class BitList<E> extends AbstractList<E> implements Cloneable {
|
|||
* Notice: It is not recommended adding duplicated element.
|
||||
*/
|
||||
@Override
|
||||
public synchronized boolean add(E e) {
|
||||
public boolean add(E e) {
|
||||
int index = originList.indexOf(e);
|
||||
if (index > -1) {
|
||||
rootSet.set(index);
|
||||
|
|
@ -225,7 +225,7 @@ public class BitList<E> extends AbstractList<E> implements Cloneable {
|
|||
* If the element is not contained in originList, try to remove from tailList.
|
||||
*/
|
||||
@Override
|
||||
public synchronized boolean remove(Object o) {
|
||||
public boolean remove(Object o) {
|
||||
int idx = originList.indexOf(o);
|
||||
if (idx > -1 && rootSet.get(idx)) {
|
||||
rootSet.set(idx, false);
|
||||
|
|
@ -242,7 +242,7 @@ public class BitList<E> extends AbstractList<E> implements Cloneable {
|
|||
* This may change the default behaviour when adding new element later.
|
||||
*/
|
||||
@Override
|
||||
public synchronized void clear() {
|
||||
public void clear() {
|
||||
rootSet.clear();
|
||||
// to remove references
|
||||
originList = Collections.emptyList();
|
||||
|
|
@ -252,7 +252,7 @@ public class BitList<E> extends AbstractList<E> implements Cloneable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public synchronized E get(int index) {
|
||||
public E get(int index) {
|
||||
int bitIndex = -1;
|
||||
if (index < 0) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
|
|
@ -272,7 +272,7 @@ public class BitList<E> extends AbstractList<E> implements Cloneable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public synchronized E remove(int index) {
|
||||
public E remove(int index) {
|
||||
int bitIndex = -1;
|
||||
if (index >= rootSet.cardinality()) {
|
||||
if (CollectionUtils.isNotEmpty(tailList)) {
|
||||
|
|
@ -290,7 +290,7 @@ public class BitList<E> extends AbstractList<E> implements Cloneable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public synchronized int indexOf(Object o) {
|
||||
public int indexOf(Object o) {
|
||||
int bitIndex = -1;
|
||||
for (int i = 0; i < rootSet.cardinality(); i++) {
|
||||
bitIndex = rootSet.nextSetBit(bitIndex + 1);
|
||||
|
|
@ -311,7 +311,7 @@ public class BitList<E> extends AbstractList<E> implements Cloneable {
|
|||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public synchronized boolean addAll(Collection<? extends E> c) {
|
||||
public boolean addAll(Collection<? extends E> c) {
|
||||
if (c instanceof BitList) {
|
||||
rootSet.or(((BitList<? extends E>) c).rootSet);
|
||||
if (((BitList<? extends E>) c).hasMoreElementInTailList()) {
|
||||
|
|
@ -325,7 +325,7 @@ public class BitList<E> extends AbstractList<E> implements Cloneable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public synchronized int lastIndexOf(Object o) {
|
||||
public int lastIndexOf(Object o) {
|
||||
int bitIndex = -1;
|
||||
int index = -1;
|
||||
if (CollectionUtils.isNotEmpty(tailList)) {
|
||||
|
|
@ -344,22 +344,22 @@ public class BitList<E> extends AbstractList<E> implements Cloneable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isEmpty() {
|
||||
public boolean isEmpty() {
|
||||
return this.rootSet.isEmpty() && CollectionUtils.isEmpty(tailList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized ListIterator<E> listIterator() {
|
||||
public ListIterator<E> listIterator() {
|
||||
return new BitListIterator<>(this, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized ListIterator<E> listIterator(int index) {
|
||||
public ListIterator<E> listIterator(int index) {
|
||||
return new BitListIterator<>(this, index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized BitList<E> subList(int fromIndex, int toIndex) {
|
||||
public BitList<E> subList(int fromIndex, int toIndex) {
|
||||
BitSet resultSet = (BitSet) rootSet.clone();
|
||||
List<E> copiedTailList = tailList == null ? null : new LinkedList<>(tailList);
|
||||
if (toIndex < size()) {
|
||||
|
|
@ -367,8 +367,7 @@ public class BitList<E> extends AbstractList<E> implements Cloneable {
|
|||
copiedTailList = null;
|
||||
resultSet.set(toIndex, resultSet.length(), false);
|
||||
} else {
|
||||
copiedTailList =
|
||||
copiedTailList == null ? null : copiedTailList.subList(0, toIndex - rootSet.cardinality());
|
||||
copiedTailList = copiedTailList == null ? null : copiedTailList.subList(0, toIndex - rootSet.cardinality());
|
||||
}
|
||||
}
|
||||
if (fromIndex > 0) {
|
||||
|
|
@ -376,9 +375,7 @@ public class BitList<E> extends AbstractList<E> implements Cloneable {
|
|||
resultSet.set(0, fromIndex, false);
|
||||
} else {
|
||||
resultSet.clear();
|
||||
copiedTailList = copiedTailList == null
|
||||
? null
|
||||
: copiedTailList.subList(fromIndex - rootSet.cardinality(), copiedTailList.size());
|
||||
copiedTailList = copiedTailList == null ? null : copiedTailList.subList(fromIndex - rootSet.cardinality(), copiedTailList.size());
|
||||
}
|
||||
}
|
||||
return new BitList<>(originList, resultSet, copiedTailList);
|
||||
|
|
@ -414,7 +411,7 @@ public class BitList<E> extends AbstractList<E> implements Cloneable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean hasNext() {
|
||||
public boolean hasNext() {
|
||||
if (isInTailList) {
|
||||
return tailListIterator.hasNext();
|
||||
} else {
|
||||
|
|
@ -428,7 +425,7 @@ public class BitList<E> extends AbstractList<E> implements Cloneable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public synchronized E next() {
|
||||
public E next() {
|
||||
if (isInTailList) {
|
||||
if (tailListIterator.hasNext()) {
|
||||
index += 1;
|
||||
|
|
@ -457,7 +454,7 @@ public class BitList<E> extends AbstractList<E> implements Cloneable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean hasPrevious() {
|
||||
public boolean hasPrevious() {
|
||||
if (isInTailList) {
|
||||
boolean hasPreviousInTailList = tailListIterator.hasPrevious();
|
||||
if (hasPreviousInTailList) {
|
||||
|
|
@ -471,7 +468,7 @@ public class BitList<E> extends AbstractList<E> implements Cloneable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public synchronized E previous() {
|
||||
public E previous() {
|
||||
if (isInTailList) {
|
||||
boolean hasPreviousInTailList = tailListIterator.hasPrevious();
|
||||
if (hasPreviousInTailList) {
|
||||
|
|
@ -503,17 +500,17 @@ public class BitList<E> extends AbstractList<E> implements Cloneable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public synchronized int nextIndex() {
|
||||
public int nextIndex() {
|
||||
return hasNext() ? index + 1 : index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized int previousIndex() {
|
||||
public int previousIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void remove() {
|
||||
public void remove() {
|
||||
if (lastReturnedIndex == -1) {
|
||||
throw new IllegalStateException();
|
||||
} else {
|
||||
|
|
@ -533,17 +530,17 @@ public class BitList<E> extends AbstractList<E> implements Cloneable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public synchronized void set(E e) {
|
||||
public void set(E e) {
|
||||
throw new UnsupportedOperationException("Set method is not supported in BitListIterator!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void add(E e) {
|
||||
public void add(E e) {
|
||||
throw new UnsupportedOperationException("Add method is not supported in BitListIterator!");
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized ArrayList<E> cloneToArrayList() {
|
||||
public ArrayList<E> cloneToArrayList() {
|
||||
if (rootSet.cardinality() == originList.size() && (CollectionUtils.isEmpty(tailList))) {
|
||||
return new ArrayList<>(originList);
|
||||
}
|
||||
|
|
@ -553,8 +550,7 @@ public class BitList<E> extends AbstractList<E> implements Cloneable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public synchronized BitList<E> clone() {
|
||||
return new BitList<>(
|
||||
originList, (BitSet) rootSet.clone(), tailList == null ? null : new LinkedList<>(tailList));
|
||||
public BitList<E> clone() {
|
||||
return new BitList<>(originList, (BitSet) rootSet.clone(), tailList == null ? null : new LinkedList<>(tailList));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,8 +32,7 @@ public abstract class CacheableStateRouterFactory implements StateRouterFactory
|
|||
|
||||
@Override
|
||||
public <T> StateRouter<T> getRouter(Class<T> interfaceClass, URL url) {
|
||||
return ConcurrentHashMapUtils.computeIfAbsent(
|
||||
routerMap, url.getServiceKey(), k -> createRouter(interfaceClass, url));
|
||||
return ConcurrentHashMapUtils.computeIfAbsent(routerMap, url.getServiceKey(), k -> createRouter(interfaceClass, url));
|
||||
}
|
||||
|
||||
protected abstract <T> StateRouter<T> createRouter(Class<T> interfaceClass, URL url);
|
||||
|
|
|
|||
|
|
@ -48,32 +48,29 @@ public class RouterGroupingState<T> {
|
|||
@Override
|
||||
public String toString() {
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
stringBuilder
|
||||
.append(routerName)
|
||||
.append(' ')
|
||||
.append(" Total: ")
|
||||
.append(total)
|
||||
.append("\n");
|
||||
stringBuilder.append(routerName)
|
||||
.append(' ')
|
||||
.append(" Total: ")
|
||||
.append(total)
|
||||
.append("\n");
|
||||
|
||||
for (Map.Entry<String, BitList<Invoker<T>>> entry : grouping.entrySet()) {
|
||||
BitList<Invoker<T>> invokers = entry.getValue();
|
||||
stringBuilder
|
||||
.append("[ ")
|
||||
.append(entry.getKey())
|
||||
.append(" -> ")
|
||||
.append(
|
||||
invokers.isEmpty()
|
||||
? "Empty"
|
||||
: invokers.stream()
|
||||
.limit(5)
|
||||
.map(Invoker::getUrl)
|
||||
.map(URL::getAddress)
|
||||
.collect(Collectors.joining(",")))
|
||||
.append(invokers.size() > 5 ? "..." : "")
|
||||
.append(" (Total: ")
|
||||
.append(invokers.size())
|
||||
.append(") ]")
|
||||
.append("\n");
|
||||
stringBuilder.append("[ ")
|
||||
.append(entry.getKey())
|
||||
.append(" -> ")
|
||||
.append(invokers.isEmpty() ?
|
||||
"Empty" :
|
||||
invokers.stream()
|
||||
.limit(5)
|
||||
.map(Invoker::getUrl)
|
||||
.map(URL::getAddress)
|
||||
.collect(Collectors.joining(",")))
|
||||
.append(invokers.size() > 5 ? "..." : "")
|
||||
.append(" (Total: ")
|
||||
.append(invokers.size())
|
||||
.append(") ]")
|
||||
.append("\n");
|
||||
}
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,13 +55,8 @@ public interface StateRouter<T> {
|
|||
* @return state with route result
|
||||
* @since 3.0
|
||||
*/
|
||||
BitList<Invoker<T>> route(
|
||||
BitList<Invoker<T>> invokers,
|
||||
URL url,
|
||||
Invocation invocation,
|
||||
boolean needToPrintMessage,
|
||||
Holder<RouterSnapshotNode<T>> nodeHolder)
|
||||
throws RpcException;
|
||||
BitList<Invoker<T>> route(BitList<Invoker<T>> invokers, URL url, Invocation invocation,
|
||||
boolean needToPrintMessage, Holder<RouterSnapshotNode<T>> nodeHolder) throws RpcException;
|
||||
|
||||
/**
|
||||
* To decide whether this router need to execute every time an RPC comes or should only execute when addresses or
|
||||
|
|
@ -97,7 +92,7 @@ public interface StateRouter<T> {
|
|||
String buildSnapshot();
|
||||
|
||||
default void stop() {
|
||||
// do nothing by default
|
||||
//do nothing by default
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -31,10 +31,14 @@ public class TailStateRouter<T> implements StateRouter<T> {
|
|||
return INSTANCE;
|
||||
}
|
||||
|
||||
private TailStateRouter() {}
|
||||
private TailStateRouter() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNextRouter(StateRouter<T> nextRouter) {}
|
||||
public void setNextRouter(StateRouter<T> nextRouter) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL getUrl() {
|
||||
|
|
@ -42,13 +46,7 @@ public class TailStateRouter<T> implements StateRouter<T> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public BitList<Invoker<T>> route(
|
||||
BitList<Invoker<T>> invokers,
|
||||
URL url,
|
||||
Invocation invocation,
|
||||
boolean needToPrintMessage,
|
||||
Holder<RouterSnapshotNode<T>> nodeHolder)
|
||||
throws RpcException {
|
||||
public BitList<Invoker<T>> route(BitList<Invoker<T>> invokers, URL url, Invocation invocation, boolean needToPrintMessage, Holder<RouterSnapshotNode<T>> nodeHolder) throws RpcException {
|
||||
return invokers;
|
||||
}
|
||||
|
||||
|
|
@ -63,7 +61,9 @@ public class TailStateRouter<T> implements StateRouter<T> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void notify(BitList<Invoker<T>> invokers) {}
|
||||
public void notify(BitList<Invoker<T>> invokers) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String buildSnapshot() {
|
||||
|
|
|
|||
|
|
@ -61,8 +61,7 @@ import static org.apache.dubbo.rpc.cluster.Constants.DEFAULT_CLUSTER_STICKY;
|
|||
*/
|
||||
public abstract class AbstractClusterInvoker<T> implements ClusterInvoker<T> {
|
||||
|
||||
private static final ErrorTypeAwareLogger logger =
|
||||
LoggerFactory.getErrorTypeAwareLogger(AbstractClusterInvoker.class);
|
||||
private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(AbstractClusterInvoker.class);
|
||||
|
||||
protected Directory<T> directory;
|
||||
|
||||
|
|
@ -76,7 +75,8 @@ public abstract class AbstractClusterInvoker<T> implements ClusterInvoker<T> {
|
|||
|
||||
private volatile Invoker<T> stickyInvoker = null;
|
||||
|
||||
public AbstractClusterInvoker() {}
|
||||
public AbstractClusterInvoker() {
|
||||
}
|
||||
|
||||
public AbstractClusterInvoker(Directory<T> directory) {
|
||||
this(directory, directory.getUrl());
|
||||
|
|
@ -88,7 +88,7 @@ public abstract class AbstractClusterInvoker<T> implements ClusterInvoker<T> {
|
|||
}
|
||||
|
||||
this.directory = directory;
|
||||
// sticky: invoker.isAvailable() should always be checked before using when availablecheck is true.
|
||||
//sticky: invoker.isAvailable() should always be checked before using when availablecheck is true.
|
||||
this.availableCheck = url.getParameter(CLUSTER_AVAILABLE_CHECK_KEY, DEFAULT_CLUSTER_AVAILABLE_CHECK);
|
||||
Configuration configuration = ConfigurationUtils.getGlobalConfiguration(url.getOrDefaultModuleModel());
|
||||
this.reselectCount = configuration.getInt(RESELECT_COUNT, DEFAULT_RESELECT_COUNT);
|
||||
|
|
@ -152,23 +152,22 @@ public abstract class AbstractClusterInvoker<T> implements ClusterInvoker<T> {
|
|||
* @return the invoker which will final to do invoke.
|
||||
* @throws RpcException exception
|
||||
*/
|
||||
protected Invoker<T> select(
|
||||
LoadBalance loadbalance, Invocation invocation, List<Invoker<T>> invokers, List<Invoker<T>> selected)
|
||||
throws RpcException {
|
||||
protected Invoker<T> select(LoadBalance loadbalance, Invocation invocation,
|
||||
List<Invoker<T>> invokers, List<Invoker<T>> selected) throws RpcException {
|
||||
|
||||
if (CollectionUtils.isEmpty(invokers)) {
|
||||
return null;
|
||||
}
|
||||
String methodName = invocation == null ? StringUtils.EMPTY_STRING : RpcUtils.getMethodName(invocation);
|
||||
|
||||
boolean sticky =
|
||||
invokers.get(0).getUrl().getMethodParameter(methodName, CLUSTER_STICKY_KEY, DEFAULT_CLUSTER_STICKY);
|
||||
boolean sticky = invokers.get(0).getUrl()
|
||||
.getMethodParameter(methodName, CLUSTER_STICKY_KEY, DEFAULT_CLUSTER_STICKY);
|
||||
|
||||
// ignore overloaded method
|
||||
//ignore overloaded method
|
||||
if (stickyInvoker != null && !invokers.contains(stickyInvoker)) {
|
||||
stickyInvoker = null;
|
||||
}
|
||||
// ignore concurrency problem
|
||||
//ignore concurrency problem
|
||||
if (sticky && stickyInvoker != null && (selected == null || !selected.contains(stickyInvoker))) {
|
||||
if (availableCheck && stickyInvoker.isAvailable()) {
|
||||
return stickyInvoker;
|
||||
|
|
@ -184,9 +183,8 @@ public abstract class AbstractClusterInvoker<T> implements ClusterInvoker<T> {
|
|||
return invoker;
|
||||
}
|
||||
|
||||
private Invoker<T> doSelect(
|
||||
LoadBalance loadbalance, Invocation invocation, List<Invoker<T>> invokers, List<Invoker<T>> selected)
|
||||
throws RpcException {
|
||||
private Invoker<T> doSelect(LoadBalance loadbalance, Invocation invocation,
|
||||
List<Invoker<T>> invokers, List<Invoker<T>> selected) throws RpcException {
|
||||
|
||||
if (CollectionUtils.isEmpty(invokers)) {
|
||||
return null;
|
||||
|
|
@ -198,7 +196,7 @@ public abstract class AbstractClusterInvoker<T> implements ClusterInvoker<T> {
|
|||
}
|
||||
Invoker<T> invoker = loadbalance.select(invokers, getUrl(), invocation);
|
||||
|
||||
// If the `invoker` is in the `selected` or invoker is unavailable && availablecheck is true, reselect.
|
||||
//If the `invoker` is in the `selected` or invoker is unavailable && availablecheck is true, reselect.
|
||||
boolean isSelected = selected != null && selected.contains(invoker);
|
||||
boolean isUnavailable = availableCheck && !invoker.isAvailable() && getUrl() != null;
|
||||
|
||||
|
|
@ -211,28 +209,17 @@ public abstract class AbstractClusterInvoker<T> implements ClusterInvoker<T> {
|
|||
if (rInvoker != null) {
|
||||
invoker = rInvoker;
|
||||
} else {
|
||||
// Check the index of current selected invoker, if it's not the last one, choose the one at index+1.
|
||||
//Check the index of current selected invoker, if it's not the last one, choose the one at index+1.
|
||||
int index = invokers.indexOf(invoker);
|
||||
try {
|
||||
// Avoid collision
|
||||
//Avoid collision
|
||||
invoker = invokers.get((index + 1) % invokers.size());
|
||||
} catch (Exception e) {
|
||||
logger.warn(
|
||||
CLUSTER_FAILED_RESELECT_INVOKERS,
|
||||
"select invokers exception",
|
||||
"",
|
||||
e.getMessage() + " may because invokers list dynamic change, ignore.",
|
||||
e);
|
||||
logger.warn(CLUSTER_FAILED_RESELECT_INVOKERS,"select invokers exception","",e.getMessage() + " may because invokers list dynamic change, ignore.",e);
|
||||
}
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
logger.error(
|
||||
CLUSTER_FAILED_RESELECT_INVOKERS,
|
||||
"failed to reselect invokers",
|
||||
"",
|
||||
"cluster reselect fail reason is :" + t.getMessage()
|
||||
+ " if can not solve, you can set cluster.availablecheck=false in url",
|
||||
t);
|
||||
logger.error(CLUSTER_FAILED_RESELECT_INVOKERS,"failed to reselect invokers","","cluster reselect fail reason is :" + t.getMessage() + " if can not solve, you can set cluster.availablecheck=false in url",t);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -251,13 +238,8 @@ public abstract class AbstractClusterInvoker<T> implements ClusterInvoker<T> {
|
|||
* @return the reselect result to do invoke
|
||||
* @throws RpcException exception
|
||||
*/
|
||||
private Invoker<T> reselect(
|
||||
LoadBalance loadbalance,
|
||||
Invocation invocation,
|
||||
List<Invoker<T>> invokers,
|
||||
List<Invoker<T>> selected,
|
||||
boolean availableCheck)
|
||||
throws RpcException {
|
||||
private Invoker<T> reselect(LoadBalance loadbalance, Invocation invocation,
|
||||
List<Invoker<T>> invokers, List<Invoker<T>> selected, boolean availableCheck) throws RpcException {
|
||||
|
||||
// Allocating one in advance, this list is certain to be used.
|
||||
List<Invoker<T>> reselectInvokers = new ArrayList<>(Math.min(invokers.size(), reselectCount));
|
||||
|
|
@ -265,12 +247,9 @@ public abstract class AbstractClusterInvoker<T> implements ClusterInvoker<T> {
|
|||
// 1. Try picking some invokers not in `selected`.
|
||||
// 1.1. If all selectable invokers' size is smaller than reselectCount, just add all
|
||||
// 1.2. If all selectable invokers' size is greater than reselectCount, randomly select reselectCount.
|
||||
// The result size of invokers might smaller than reselectCount due to disAvailable or de-duplication
|
||||
// (might be zero).
|
||||
// This means there is probable that reselectInvokers is empty however all invoker list may contain
|
||||
// available invokers.
|
||||
// Use reselectCount can reduce retry times if invokers' size is huge, which may lead to long time
|
||||
// hang up.
|
||||
// The result size of invokers might smaller than reselectCount due to disAvailable or de-duplication (might be zero).
|
||||
// This means there is probable that reselectInvokers is empty however all invoker list may contain available invokers.
|
||||
// Use reselectCount can reduce retry times if invokers' size is huge, which may lead to long time hang up.
|
||||
if (reselectCount >= invokers.size()) {
|
||||
for (Invoker<T> invoker : invokers) {
|
||||
// check if available
|
||||
|
|
@ -311,7 +290,7 @@ public abstract class AbstractClusterInvoker<T> implements ClusterInvoker<T> {
|
|||
if (selected != null) {
|
||||
for (Invoker<T> invoker : selected) {
|
||||
if ((invoker.isAvailable()) // available first
|
||||
&& !reselectInvokers.contains(invoker)) {
|
||||
&& !reselectInvokers.contains(invoker)) {
|
||||
reselectInvokers.add(invoker);
|
||||
}
|
||||
}
|
||||
|
|
@ -346,10 +325,10 @@ public abstract class AbstractClusterInvoker<T> implements ClusterInvoker<T> {
|
|||
checkWhetherDestroyed();
|
||||
|
||||
// binding attachments into invocation.
|
||||
// Map<String, Object> contextAttachments = RpcContext.getClientAttachment().getObjectAttachments();
|
||||
// if (contextAttachments != null && contextAttachments.size() != 0) {
|
||||
// ((RpcInvocation) invocation).addObjectAttachmentsIfAbsent(contextAttachments);
|
||||
// }
|
||||
// Map<String, Object> contextAttachments = RpcContext.getClientAttachment().getObjectAttachments();
|
||||
// if (contextAttachments != null && contextAttachments.size() != 0) {
|
||||
// ((RpcInvocation) invocation).addObjectAttachmentsIfAbsent(contextAttachments);
|
||||
// }
|
||||
|
||||
InvocationProfilerUtils.enterDetailProfiler(invocation, () -> "Router route.");
|
||||
List<Invoker<T>> invokers = list(invocation);
|
||||
|
|
@ -360,8 +339,7 @@ public abstract class AbstractClusterInvoker<T> implements ClusterInvoker<T> {
|
|||
LoadBalance loadbalance = initLoadBalance(invokers, invocation);
|
||||
RpcUtils.attachInvocationIdIfAsync(getUrl(), invocation);
|
||||
|
||||
InvocationProfilerUtils.enterDetailProfiler(
|
||||
invocation, () -> "Cluster " + this.getClass().getName() + " invoke.");
|
||||
InvocationProfilerUtils.enterDetailProfiler(invocation, () -> "Cluster " + this.getClass().getName() + " invoke.");
|
||||
try {
|
||||
return doInvoke(invocation, invokers, loadbalance);
|
||||
} finally {
|
||||
|
|
@ -371,10 +349,9 @@ public abstract class AbstractClusterInvoker<T> implements ClusterInvoker<T> {
|
|||
|
||||
protected void checkWhetherDestroyed() {
|
||||
if (destroyed.get()) {
|
||||
throw new RpcException(
|
||||
"Rpc cluster invoker for " + getInterface() + " on consumer " + NetUtils.getLocalHost()
|
||||
+ " use dubbo version " + Version.getVersion()
|
||||
+ " is now destroyed! Can not invoke any more.");
|
||||
throw new RpcException("Rpc cluster invoker for " + getInterface() + " on consumer " + NetUtils.getLocalHost()
|
||||
+ " use dubbo version " + Version.getVersion()
|
||||
+ " is now destroyed! Can not invoke any more.");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -385,17 +362,13 @@ public abstract class AbstractClusterInvoker<T> implements ClusterInvoker<T> {
|
|||
|
||||
protected void checkInvokers(List<Invoker<T>> invokers, Invocation invocation) {
|
||||
if (CollectionUtils.isEmpty(invokers)) {
|
||||
throw new RpcException(
|
||||
RpcException.NO_INVOKER_AVAILABLE_AFTER_FILTER,
|
||||
"Failed to invoke the method "
|
||||
+ RpcUtils.getMethodName(invocation) + " in the service "
|
||||
+ getInterface().getName()
|
||||
+ ". No provider available for the service "
|
||||
+ getDirectory().getConsumerUrl().getServiceKey()
|
||||
+ " from registry " + getDirectory()
|
||||
+ " on the consumer " + NetUtils.getLocalHost()
|
||||
+ " using the dubbo version " + Version.getVersion()
|
||||
+ ". Please check if the providers have been started and registered.");
|
||||
throw new RpcException(RpcException.NO_INVOKER_AVAILABLE_AFTER_FILTER, "Failed to invoke the method "
|
||||
+ RpcUtils.getMethodName(invocation) + " in the service " + getInterface().getName()
|
||||
+ ". No provider available for the service " + getDirectory().getConsumerUrl().getServiceKey()
|
||||
+ " from registry " + getDirectory()
|
||||
+ " on the consumer " + NetUtils.getLocalHost()
|
||||
+ " using the dubbo version " + Version.getVersion()
|
||||
+ ". Please check if the providers have been started and registered.");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -404,9 +377,7 @@ public abstract class AbstractClusterInvoker<T> implements ClusterInvoker<T> {
|
|||
Result result;
|
||||
try {
|
||||
if (ProfilerSwitch.isEnableSimpleProfiler()) {
|
||||
InvocationProfilerUtils.enterProfiler(
|
||||
invocation,
|
||||
"Invoker invoke. Target Address: " + invoker.getUrl().getAddress());
|
||||
InvocationProfilerUtils.enterProfiler(invocation, "Invoker invoke. Target Address: " + invoker.getUrl().getAddress());
|
||||
}
|
||||
setRemote(invoker, invocation);
|
||||
result = invoker.invoke(invocation);
|
||||
|
|
@ -445,8 +416,8 @@ public abstract class AbstractClusterInvoker<T> implements ClusterInvoker<T> {
|
|||
return result;
|
||||
}
|
||||
|
||||
protected abstract Result doInvoke(Invocation invocation, List<Invoker<T>> invokers, LoadBalance loadbalance)
|
||||
throws RpcException;
|
||||
protected abstract Result doInvoke(Invocation invocation, List<Invoker<T>> invokers,
|
||||
LoadBalance loadbalance) throws RpcException;
|
||||
|
||||
protected List<Invoker<T>> list(Invocation invocation) throws RpcException {
|
||||
return getDirectory().list(invocation);
|
||||
|
|
@ -466,17 +437,17 @@ public abstract class AbstractClusterInvoker<T> implements ClusterInvoker<T> {
|
|||
protected LoadBalance initLoadBalance(List<Invoker<T>> invokers, Invocation invocation) {
|
||||
ApplicationModel applicationModel = ScopeModelUtil.getApplicationModel(invocation.getModuleModel());
|
||||
if (CollectionUtils.isNotEmpty(invokers)) {
|
||||
return applicationModel
|
||||
.getExtensionLoader(LoadBalance.class)
|
||||
.getExtension(invokers.get(0)
|
||||
.getUrl()
|
||||
.getMethodParameter(
|
||||
RpcUtils.getMethodName(invocation), LOADBALANCE_KEY, DEFAULT_LOADBALANCE));
|
||||
return applicationModel.getExtensionLoader(LoadBalance.class).getExtension(
|
||||
invokers.get(0).getUrl().getMethodParameter(
|
||||
RpcUtils.getMethodName(invocation), LOADBALANCE_KEY, DEFAULT_LOADBALANCE
|
||||
)
|
||||
);
|
||||
} else {
|
||||
return applicationModel.getExtensionLoader(LoadBalance.class).getExtension(DEFAULT_LOADBALANCE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private Invoker<T> setContext(Invoker<T> invoker) {
|
||||
return setContext(invoker, null);
|
||||
}
|
||||
|
|
@ -485,10 +456,7 @@ public abstract class AbstractClusterInvoker<T> implements ClusterInvoker<T> {
|
|||
RpcServiceContext context = RpcContext.getServiceContext();
|
||||
Invoker<?> originInvoker = context.getInvoker();
|
||||
context.setInvoker(invoker)
|
||||
.setConsumerUrl(
|
||||
null != consumerUrl
|
||||
? consumerUrl
|
||||
: RpcContext.getServiceContext().getConsumerUrl());
|
||||
.setConsumerUrl(null != consumerUrl ? consumerUrl : RpcContext.getServiceContext().getConsumerUrl());
|
||||
return (Invoker<T>) originInvoker;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,8 +36,7 @@ public class AvailableClusterInvoker<T> extends AbstractClusterInvoker<T> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Result doInvoke(Invocation invocation, List<Invoker<T>> invokers, LoadBalance loadbalance)
|
||||
throws RpcException {
|
||||
public Result doInvoke(Invocation invocation, List<Invoker<T>> invokers, LoadBalance loadbalance) throws RpcException {
|
||||
for (Invoker<T> invoker : invokers) {
|
||||
if (invoker.isAvailable()) {
|
||||
return invokeWithContext(invoker, invocation);
|
||||
|
|
@ -45,4 +44,5 @@ public class AvailableClusterInvoker<T> extends AbstractClusterInvoker<T> {
|
|||
}
|
||||
throw new RpcException("No provider available in " + invokers);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,4 +30,5 @@ public class BroadcastCluster extends AbstractCluster {
|
|||
public <T> AbstractClusterInvoker<T> doJoin(Directory<T> directory) throws RpcException {
|
||||
return new BroadcastClusterInvoker<>(directory);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,8 +39,7 @@ import static org.apache.dubbo.common.constants.LoggerCodeConstants.CLUSTER_ERRO
|
|||
*/
|
||||
public class BroadcastClusterInvoker<T> extends AbstractClusterInvoker<T> {
|
||||
|
||||
private static final ErrorTypeAwareLogger logger =
|
||||
LoggerFactory.getErrorTypeAwareLogger(BroadcastClusterInvoker.class);
|
||||
private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(BroadcastClusterInvoker.class);
|
||||
private static final String BROADCAST_FAIL_PERCENT_KEY = "broadcast.fail.percent";
|
||||
private static final int MAX_BROADCAST_FAIL_PERCENT = 100;
|
||||
private static final int MIN_BROADCAST_FAIL_PERCENT = 0;
|
||||
|
|
@ -51,23 +50,19 @@ public class BroadcastClusterInvoker<T> extends AbstractClusterInvoker<T> {
|
|||
|
||||
@Override
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
public Result doInvoke(final Invocation invocation, List<Invoker<T>> invokers, LoadBalance loadbalance)
|
||||
throws RpcException {
|
||||
public Result doInvoke(final Invocation invocation, List<Invoker<T>> invokers, LoadBalance loadbalance) throws RpcException {
|
||||
RpcContext.getServiceContext().setInvokers((List) invokers);
|
||||
RpcException exception = null;
|
||||
Result result = null;
|
||||
URL url = getUrl();
|
||||
// The value range of broadcast.fail.threshold must be 0~100.
|
||||
// 100 means that an exception will be thrown last, and 0 means that as long as an exception occurs, it will be
|
||||
// thrown.
|
||||
// 100 means that an exception will be thrown last, and 0 means that as long as an exception occurs, it will be thrown.
|
||||
// see https://github.com/apache/dubbo/pull/7174
|
||||
int broadcastFailPercent = url.getParameter(BROADCAST_FAIL_PERCENT_KEY, MAX_BROADCAST_FAIL_PERCENT);
|
||||
|
||||
if (broadcastFailPercent < MIN_BROADCAST_FAIL_PERCENT || broadcastFailPercent > MAX_BROADCAST_FAIL_PERCENT) {
|
||||
logger.info(String.format(
|
||||
"The value corresponding to the broadcast.fail.percent parameter must be between 0 and 100. "
|
||||
+ "The current setting is %s, which is reset to 100.",
|
||||
broadcastFailPercent));
|
||||
logger.info(String.format("The value corresponding to the broadcast.fail.percent parameter must be between 0 and 100. " +
|
||||
"The current setting is %s, which is reset to 100.", broadcastFailPercent));
|
||||
broadcastFailPercent = MAX_BROADCAST_FAIL_PERCENT;
|
||||
}
|
||||
|
||||
|
|
@ -77,29 +72,17 @@ public class BroadcastClusterInvoker<T> extends AbstractClusterInvoker<T> {
|
|||
Invoker<T> invoker = invokers.get(i);
|
||||
RpcContext.RestoreContext restoreContext = new RpcContext.RestoreContext();
|
||||
try {
|
||||
RpcInvocation subInvocation = new RpcInvocation(
|
||||
invocation.getTargetServiceUniqueName(),
|
||||
invocation.getServiceModel(),
|
||||
invocation.getMethodName(),
|
||||
invocation.getServiceName(),
|
||||
invocation.getProtocolServiceKey(),
|
||||
invocation.getParameterTypes(),
|
||||
invocation.getArguments(),
|
||||
invocation.copyObjectAttachments(),
|
||||
invocation.getInvoker(),
|
||||
Collections.synchronizedMap(new HashMap<>(invocation.getAttributes())),
|
||||
invocation instanceof RpcInvocation ? ((RpcInvocation) invocation).getInvokeMode() : null);
|
||||
RpcInvocation subInvocation = new RpcInvocation(invocation.getTargetServiceUniqueName(),
|
||||
invocation.getServiceModel(), invocation.getMethodName(), invocation.getServiceName(), invocation.getProtocolServiceKey(),
|
||||
invocation.getParameterTypes(), invocation.getArguments(), invocation.copyObjectAttachments(),
|
||||
invocation.getInvoker(), Collections.synchronizedMap(new HashMap<>(invocation.getAttributes())),
|
||||
invocation instanceof RpcInvocation ? ((RpcInvocation) invocation).getInvokeMode() : null);
|
||||
result = invokeWithContext(invoker, subInvocation);
|
||||
if (null != result && result.hasException()) {
|
||||
Throwable resultException = result.getException();
|
||||
if (null != resultException) {
|
||||
exception = getRpcException(result.getException());
|
||||
logger.warn(
|
||||
CLUSTER_ERROR_RESPONSE,
|
||||
"provider return error response",
|
||||
"",
|
||||
exception.getMessage(),
|
||||
exception);
|
||||
logger.warn(CLUSTER_ERROR_RESPONSE,"provider return error response","",exception.getMessage(),exception);
|
||||
failIndex++;
|
||||
if (failIndex == failThresholdIndex) {
|
||||
break;
|
||||
|
|
@ -108,12 +91,7 @@ public class BroadcastClusterInvoker<T> extends AbstractClusterInvoker<T> {
|
|||
}
|
||||
} catch (Throwable e) {
|
||||
exception = getRpcException(e);
|
||||
logger.warn(
|
||||
CLUSTER_ERROR_RESPONSE,
|
||||
"provider return error response",
|
||||
"",
|
||||
exception.getMessage(),
|
||||
exception);
|
||||
logger.warn(CLUSTER_ERROR_RESPONSE,"provider return error response","",exception.getMessage(),exception);
|
||||
failIndex++;
|
||||
if (failIndex == failThresholdIndex) {
|
||||
break;
|
||||
|
|
@ -128,15 +106,14 @@ public class BroadcastClusterInvoker<T> extends AbstractClusterInvoker<T> {
|
|||
if (exception != null) {
|
||||
if (failIndex == failThresholdIndex) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(String.format(
|
||||
"The number of BroadcastCluster call failures has reached the threshold %s",
|
||||
failThresholdIndex));
|
||||
logger.debug(
|
||||
String.format("The number of BroadcastCluster call failures has reached the threshold %s", failThresholdIndex));
|
||||
|
||||
}
|
||||
} else {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(String.format(
|
||||
"The number of BroadcastCluster call failures has not reached the threshold %s, fail size is %s",
|
||||
failThresholdIndex, failIndex));
|
||||
logger.debug(String.format("The number of BroadcastCluster call failures has not reached the threshold %s, fail size is %s",
|
||||
failThresholdIndex, failIndex));
|
||||
}
|
||||
}
|
||||
throw exception;
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ import java.util.Map;
|
|||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.URL_MERGE_PROCESSOR_KEY;
|
||||
|
||||
|
||||
/**
|
||||
* ClusterUtils
|
||||
*/
|
||||
|
|
@ -44,13 +45,9 @@ public class ClusterUtils implements ScopeModelAware {
|
|||
ProviderURLMergeProcessor providerUrlMergeProcessor;
|
||||
|
||||
if (StringUtils.isNotEmpty(ump)) {
|
||||
providerUrlMergeProcessor = applicationModel
|
||||
.getExtensionLoader(ProviderURLMergeProcessor.class)
|
||||
.getExtension(ump);
|
||||
providerUrlMergeProcessor = applicationModel.getExtensionLoader(ProviderURLMergeProcessor.class).getExtension(ump);
|
||||
} else {
|
||||
providerUrlMergeProcessor = applicationModel
|
||||
.getExtensionLoader(ProviderURLMergeProcessor.class)
|
||||
.getExtension("default");
|
||||
providerUrlMergeProcessor = applicationModel.getExtensionLoader(ProviderURLMergeProcessor.class).getExtension("default");
|
||||
}
|
||||
|
||||
return providerUrlMergeProcessor.mergeUrl(remoteUrl, localMap);
|
||||
|
|
@ -61,15 +58,13 @@ public class ClusterUtils implements ScopeModelAware {
|
|||
ProviderURLMergeProcessor providerUrlMergeProcessor;
|
||||
|
||||
if (StringUtils.isNotEmpty(ump)) {
|
||||
providerUrlMergeProcessor = applicationModel
|
||||
.getExtensionLoader(ProviderURLMergeProcessor.class)
|
||||
.getExtension(ump);
|
||||
providerUrlMergeProcessor = applicationModel.getExtensionLoader(ProviderURLMergeProcessor.class).getExtension(ump);
|
||||
} else {
|
||||
providerUrlMergeProcessor = applicationModel
|
||||
.getExtensionLoader(ProviderURLMergeProcessor.class)
|
||||
.getExtension("default");
|
||||
providerUrlMergeProcessor = applicationModel.getExtensionLoader(ProviderURLMergeProcessor.class).getExtension("default");
|
||||
}
|
||||
|
||||
return providerUrlMergeProcessor.mergeLocalParams(localMap);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,10 +26,11 @@ import org.apache.dubbo.rpc.cluster.support.wrapper.AbstractCluster;
|
|||
*/
|
||||
public class FailbackCluster extends AbstractCluster {
|
||||
|
||||
public static final String NAME = "failback";
|
||||
public final static String NAME = "failback";
|
||||
|
||||
@Override
|
||||
public <T> AbstractClusterInvoker<T> doJoin(Directory<T> directory) throws RpcException {
|
||||
return new FailbackClusterInvoker<>(directory);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,8 +53,7 @@ import static org.apache.dubbo.rpc.cluster.Constants.FAIL_BACK_TASKS_KEY;
|
|||
*/
|
||||
public class FailbackClusterInvoker<T> extends AbstractClusterInvoker<T> {
|
||||
|
||||
private static final ErrorTypeAwareLogger logger =
|
||||
LoggerFactory.getErrorTypeAwareLogger(FailbackClusterInvoker.class);
|
||||
private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(FailbackClusterInvoker.class);
|
||||
|
||||
private static final long RETRY_FAILED_PERIOD = 5;
|
||||
|
||||
|
|
@ -82,41 +81,27 @@ public class FailbackClusterInvoker<T> extends AbstractClusterInvoker<T> {
|
|||
failbackTasks = failbackTasksConfig;
|
||||
}
|
||||
|
||||
private void addFailed(
|
||||
LoadBalance loadbalance,
|
||||
Invocation invocation,
|
||||
List<Invoker<T>> invokers,
|
||||
Invoker<T> lastInvoker,
|
||||
URL consumerUrl) {
|
||||
private void addFailed(LoadBalance loadbalance, Invocation invocation, List<Invoker<T>> invokers, Invoker<T> lastInvoker, URL consumerUrl) {
|
||||
if (failTimer == null) {
|
||||
synchronized (this) {
|
||||
if (failTimer == null) {
|
||||
failTimer = new HashedWheelTimer(
|
||||
new NamedThreadFactory("failback-cluster-timer", true),
|
||||
1,
|
||||
TimeUnit.SECONDS,
|
||||
32,
|
||||
failbackTasks);
|
||||
new NamedThreadFactory("failback-cluster-timer", true),
|
||||
1,
|
||||
TimeUnit.SECONDS, 32, failbackTasks);
|
||||
}
|
||||
}
|
||||
}
|
||||
RetryTimerTask retryTimerTask = new RetryTimerTask(
|
||||
loadbalance, invocation, invokers, lastInvoker, retries, RETRY_FAILED_PERIOD, consumerUrl);
|
||||
RetryTimerTask retryTimerTask = new RetryTimerTask(loadbalance, invocation, invokers, lastInvoker, retries, RETRY_FAILED_PERIOD, consumerUrl);
|
||||
try {
|
||||
failTimer.newTimeout(retryTimerTask, RETRY_FAILED_PERIOD, TimeUnit.SECONDS);
|
||||
} catch (Throwable e) {
|
||||
logger.error(
|
||||
CLUSTER_TIMER_RETRY_FAILED,
|
||||
"add newTimeout exception",
|
||||
"",
|
||||
"Failback background works error, invocation->" + invocation + ", exception: " + e.getMessage(),
|
||||
e);
|
||||
logger.error(CLUSTER_TIMER_RETRY_FAILED,"add newTimeout exception","","Failback background works error, invocation->" + invocation + ", exception: " + e.getMessage(),e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Result doInvoke(Invocation invocation, List<Invoker<T>> invokers, LoadBalance loadbalance)
|
||||
throws RpcException {
|
||||
protected Result doInvoke(Invocation invocation, List<Invoker<T>> invokers, LoadBalance loadbalance) throws RpcException {
|
||||
Invoker<T> invoker = null;
|
||||
URL consumerUrl = RpcContext.getServiceContext().getConsumerUrl();
|
||||
try {
|
||||
|
|
@ -125,14 +110,10 @@ public class FailbackClusterInvoker<T> extends AbstractClusterInvoker<T> {
|
|||
// Then the serviceContext will be cleared after the call is completed.
|
||||
return invokeWithContextAsync(invoker, invocation, consumerUrl);
|
||||
} catch (Throwable e) {
|
||||
logger.error(
|
||||
CLUSTER_FAILED_INVOKE_SERVICE,
|
||||
"Failback to invoke method and start to retries",
|
||||
"",
|
||||
"Failback to invoke method " + RpcUtils.getMethodName(invocation)
|
||||
+ ", wait for retry in background. Ignored exception: "
|
||||
+ e.getMessage() + ", ",
|
||||
e);
|
||||
logger.error(CLUSTER_FAILED_INVOKE_SERVICE,"Failback to invoke method and start to retries",
|
||||
"","Failback to invoke method " + RpcUtils.getMethodName(invocation) +
|
||||
", wait for retry in background. Ignored exception: "
|
||||
+ e.getMessage() + ", ",e);
|
||||
if (retries > 0) {
|
||||
addFailed(loadbalance, invocation, invokers, invoker, consumerUrl);
|
||||
}
|
||||
|
|
@ -169,14 +150,8 @@ public class FailbackClusterInvoker<T> extends AbstractClusterInvoker<T> {
|
|||
*/
|
||||
private int retriedTimes = 0;
|
||||
|
||||
RetryTimerTask(
|
||||
LoadBalance loadbalance,
|
||||
Invocation invocation,
|
||||
List<Invoker<T>> invokers,
|
||||
Invoker<T> lastInvoker,
|
||||
int retries,
|
||||
long tick,
|
||||
URL consumerUrl) {
|
||||
RetryTimerTask(LoadBalance loadbalance, Invocation invocation, List<Invoker<T>> invokers, Invoker<T> lastInvoker,
|
||||
int retries, long tick, URL consumerUrl) {
|
||||
this.loadbalance = loadbalance;
|
||||
this.invocation = invocation;
|
||||
this.invokers = invokers;
|
||||
|
|
@ -189,28 +164,15 @@ public class FailbackClusterInvoker<T> extends AbstractClusterInvoker<T> {
|
|||
@Override
|
||||
public void run(Timeout timeout) {
|
||||
try {
|
||||
logger.info("Attempt to retry to invoke method " + RpcUtils.getMethodName(invocation)
|
||||
+ ". The total will retry " + retries + " times, the current is the " + retriedTimes
|
||||
+ " retry");
|
||||
Invoker<T> retryInvoker =
|
||||
select(loadbalance, invocation, invokers, Collections.singletonList(lastInvoker));
|
||||
logger.info("Attempt to retry to invoke method " + RpcUtils.getMethodName(invocation) +
|
||||
". The total will retry " + retries + " times, the current is the " + retriedTimes + " retry");
|
||||
Invoker<T> retryInvoker = select(loadbalance, invocation, invokers, Collections.singletonList(lastInvoker));
|
||||
lastInvoker = retryInvoker;
|
||||
invokeWithContextAsync(retryInvoker, invocation, consumerUrl);
|
||||
} catch (Throwable e) {
|
||||
logger.error(
|
||||
CLUSTER_FAILED_INVOKE_SERVICE,
|
||||
"Failed retry to invoke method",
|
||||
"",
|
||||
"Failed retry to invoke method " + RpcUtils.getMethodName(invocation) + ", waiting again.",
|
||||
e);
|
||||
logger.error(CLUSTER_FAILED_INVOKE_SERVICE,"Failed retry to invoke method","","Failed retry to invoke method " + RpcUtils.getMethodName(invocation) + ", waiting again.",e);
|
||||
if ((++retriedTimes) >= retries) {
|
||||
logger.error(
|
||||
CLUSTER_FAILED_INVOKE_SERVICE,
|
||||
"Failed retry to invoke method and retry times exceed threshold",
|
||||
"",
|
||||
"Failed retry times exceed threshold (" + retries + "), We have to abandon, invocation->"
|
||||
+ invocation,
|
||||
e);
|
||||
logger.error(CLUSTER_FAILED_INVOKE_SERVICE,"Failed retry to invoke method and retry times exceed threshold","","Failed retry times exceed threshold (" + retries + "), We have to abandon, invocation->" + invocation,e);
|
||||
} else {
|
||||
rePut(timeout);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,10 +26,11 @@ import org.apache.dubbo.rpc.cluster.support.wrapper.AbstractCluster;
|
|||
*/
|
||||
public class FailfastCluster extends AbstractCluster {
|
||||
|
||||
public static final String NAME = "failfast";
|
||||
public final static String NAME = "failfast";
|
||||
|
||||
@Override
|
||||
public <T> AbstractClusterInvoker<T> doJoin(Directory<T> directory) throws RpcException {
|
||||
return new FailfastClusterInvoker<>(directory);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,8 +41,7 @@ public class FailfastClusterInvoker<T> extends AbstractClusterInvoker<T> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Result doInvoke(Invocation invocation, List<Invoker<T>> invokers, LoadBalance loadbalance)
|
||||
throws RpcException {
|
||||
public Result doInvoke(Invocation invocation, List<Invoker<T>> invokers, LoadBalance loadbalance) throws RpcException {
|
||||
Invoker<T> invoker = select(loadbalance, invocation, invokers, null);
|
||||
try {
|
||||
return invokeWithContext(invoker, invocation);
|
||||
|
|
@ -50,16 +49,13 @@ public class FailfastClusterInvoker<T> extends AbstractClusterInvoker<T> {
|
|||
if (e instanceof RpcException && ((RpcException) e).isBiz()) { // biz exception.
|
||||
throw (RpcException) e;
|
||||
}
|
||||
throw new RpcException(
|
||||
e instanceof RpcException ? ((RpcException) e).getCode() : 0,
|
||||
"Failfast invoke providers " + invoker.getUrl() + " "
|
||||
+ loadbalance.getClass().getSimpleName()
|
||||
+ " for service " + getInterface().getName()
|
||||
+ " method " + RpcUtils.getMethodName(invocation) + " on consumer "
|
||||
+ NetUtils.getLocalHost()
|
||||
+ " use dubbo version " + Version.getVersion()
|
||||
+ ", but no luck to perform the invocation. Last error is: " + e.getMessage(),
|
||||
e.getCause() != null ? e.getCause() : e);
|
||||
throw new RpcException(e instanceof RpcException ? ((RpcException) e).getCode() : 0,
|
||||
"Failfast invoke providers " + invoker.getUrl() + " " + loadbalance.getClass().getSimpleName()
|
||||
+ " for service " + getInterface().getName()
|
||||
+ " method " + RpcUtils.getMethodName(invocation) + " on consumer " + NetUtils.getLocalHost()
|
||||
+ " use dubbo version " + Version.getVersion()
|
||||
+ ", but no luck to perform the invocation. Last error is: " + e.getMessage(),
|
||||
e.getCause() != null ? e.getCause() : e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,10 +26,11 @@ import org.apache.dubbo.rpc.cluster.support.wrapper.AbstractCluster;
|
|||
*/
|
||||
public class FailoverCluster extends AbstractCluster {
|
||||
|
||||
public static final String NAME = "failover";
|
||||
public final static String NAME = "failover";
|
||||
|
||||
@Override
|
||||
public <T> AbstractClusterInvoker<T> doJoin(Directory<T> directory) throws RpcException {
|
||||
return new FailoverClusterInvoker<>(directory);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,8 +47,7 @@ import static org.apache.dubbo.common.constants.LoggerCodeConstants.CLUSTER_FAIL
|
|||
*/
|
||||
public class FailoverClusterInvoker<T> extends AbstractClusterInvoker<T> {
|
||||
|
||||
private static final ErrorTypeAwareLogger logger =
|
||||
LoggerFactory.getErrorTypeAwareLogger(FailoverClusterInvoker.class);
|
||||
private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(FailoverClusterInvoker.class);
|
||||
|
||||
public FailoverClusterInvoker(Directory<T> directory) {
|
||||
super(directory);
|
||||
|
|
@ -56,18 +55,17 @@ public class FailoverClusterInvoker<T> extends AbstractClusterInvoker<T> {
|
|||
|
||||
@Override
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
public Result doInvoke(Invocation invocation, final List<Invoker<T>> invokers, LoadBalance loadbalance)
|
||||
throws RpcException {
|
||||
public Result doInvoke(Invocation invocation, final List<Invoker<T>> invokers, LoadBalance loadbalance) throws RpcException {
|
||||
List<Invoker<T>> copyInvokers = invokers;
|
||||
String methodName = RpcUtils.getMethodName(invocation);
|
||||
int len = calculateInvokeTimes(methodName);
|
||||
// retry loop.
|
||||
RpcException le = null; // last exception.
|
||||
List<Invoker<T>> invoked = new ArrayList<>(copyInvokers.size()); // invoked invokers.
|
||||
Set<String> providers = new HashSet<>(len);
|
||||
List<Invoker<T>> invoked = new ArrayList<Invoker<T>>(copyInvokers.size()); // invoked invokers.
|
||||
Set<String> providers = new HashSet<String>(len);
|
||||
for (int i = 0; i < len; i++) {
|
||||
// Reselect before retry to avoid a change of candidate `invokers`.
|
||||
// NOTE: if `invokers` changed, then `invoked` also lose accuracy.
|
||||
//Reselect before retry to avoid a change of candidate `invokers`.
|
||||
//NOTE: if `invokers` changed, then `invoked` also lose accuracy.
|
||||
if (i > 0) {
|
||||
checkWhetherDestroyed();
|
||||
copyInvokers = list(invocation);
|
||||
|
|
@ -81,22 +79,15 @@ public class FailoverClusterInvoker<T> extends AbstractClusterInvoker<T> {
|
|||
try {
|
||||
Result result = invokeWithContext(invoker, invocation);
|
||||
if (le != null && logger.isWarnEnabled()) {
|
||||
logger.warn(
|
||||
CLUSTER_FAILED_MULTIPLE_RETRIES,
|
||||
"failed to retry do invoke",
|
||||
"",
|
||||
"Although retry the method " + methodName
|
||||
+ " in the service " + getInterface().getName()
|
||||
+ " was successful by the provider "
|
||||
+ invoker.getUrl().getAddress()
|
||||
+ ", but there have been failed providers " + providers
|
||||
+ " (" + providers.size() + "/" + copyInvokers.size()
|
||||
+ ") from the registry "
|
||||
+ directory.getUrl().getAddress()
|
||||
+ " on the consumer " + NetUtils.getLocalHost()
|
||||
+ " using the dubbo version " + Version.getVersion() + ". Last error is: "
|
||||
+ le.getMessage(),
|
||||
le);
|
||||
logger.warn(CLUSTER_FAILED_MULTIPLE_RETRIES,"failed to retry do invoke","","Although retry the method " + methodName
|
||||
+ " in the service " + getInterface().getName()
|
||||
+ " was successful by the provider " + invoker.getUrl().getAddress()
|
||||
+ ", but there have been failed providers " + providers
|
||||
+ " (" + providers.size() + "/" + copyInvokers.size()
|
||||
+ ") from the registry " + directory.getUrl().getAddress()
|
||||
+ " on the consumer " + NetUtils.getLocalHost()
|
||||
+ " using the dubbo version " + Version.getVersion() + ". Last error is: "
|
||||
+ le.getMessage(),le);
|
||||
}
|
||||
success = true;
|
||||
return result;
|
||||
|
|
@ -113,17 +104,14 @@ public class FailoverClusterInvoker<T> extends AbstractClusterInvoker<T> {
|
|||
}
|
||||
}
|
||||
}
|
||||
throw new RpcException(
|
||||
le.getCode(),
|
||||
"Failed to invoke the method "
|
||||
+ methodName + " in the service " + getInterface().getName()
|
||||
+ ". Tried " + len + " times of the providers " + providers
|
||||
+ " (" + providers.size() + "/" + copyInvokers.size()
|
||||
+ ") from the registry " + directory.getUrl().getAddress()
|
||||
+ " on the consumer " + NetUtils.getLocalHost() + " using the dubbo version "
|
||||
+ Version.getVersion() + ". Last error is: "
|
||||
+ le.getMessage(),
|
||||
le.getCause() != null ? le.getCause() : le);
|
||||
throw new RpcException(le.getCode(), "Failed to invoke the method "
|
||||
+ methodName + " in the service " + getInterface().getName()
|
||||
+ ". Tried " + len + " times of the providers " + providers
|
||||
+ " (" + providers.size() + "/" + copyInvokers.size()
|
||||
+ ") from the registry " + directory.getUrl().getAddress()
|
||||
+ " on the consumer " + NetUtils.getLocalHost() + " using the dubbo version "
|
||||
+ Version.getVersion() + ". Last error is: "
|
||||
+ le.getMessage(), le.getCause() != null ? le.getCause() : le);
|
||||
}
|
||||
|
||||
private int calculateInvokeTimes(String methodName) {
|
||||
|
|
@ -140,4 +128,5 @@ public class FailoverClusterInvoker<T> extends AbstractClusterInvoker<T> {
|
|||
|
||||
return len;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,10 +26,11 @@ import org.apache.dubbo.rpc.cluster.support.wrapper.AbstractCluster;
|
|||
*/
|
||||
public class FailsafeCluster extends AbstractCluster {
|
||||
|
||||
public static final String NAME = "failsafe";
|
||||
public final static String NAME = "failsafe";
|
||||
|
||||
@Override
|
||||
public <T> AbstractClusterInvoker<T> doJoin(Directory<T> directory) throws RpcException {
|
||||
return new FailsafeClusterInvoker<>(directory);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,26 +38,19 @@ import static org.apache.dubbo.common.constants.LoggerCodeConstants.CLUSTER_ERRO
|
|||
*
|
||||
*/
|
||||
public class FailsafeClusterInvoker<T> extends AbstractClusterInvoker<T> {
|
||||
private static final ErrorTypeAwareLogger logger =
|
||||
LoggerFactory.getErrorTypeAwareLogger(FailsafeClusterInvoker.class);
|
||||
private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(FailsafeClusterInvoker.class);
|
||||
|
||||
public FailsafeClusterInvoker(Directory<T> directory) {
|
||||
super(directory);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result doInvoke(Invocation invocation, List<Invoker<T>> invokers, LoadBalance loadbalance)
|
||||
throws RpcException {
|
||||
public Result doInvoke(Invocation invocation, List<Invoker<T>> invokers, LoadBalance loadbalance) throws RpcException {
|
||||
try {
|
||||
Invoker<T> invoker = select(loadbalance, invocation, invokers, null);
|
||||
return invokeWithContext(invoker, invocation);
|
||||
} catch (Throwable e) {
|
||||
logger.error(
|
||||
CLUSTER_ERROR_RESPONSE,
|
||||
"Failsafe for provider exception",
|
||||
"",
|
||||
"Failsafe ignore exception: " + e.getMessage(),
|
||||
e);
|
||||
logger.error(CLUSTER_ERROR_RESPONSE,"Failsafe for provider exception","","Failsafe ignore exception: " + e.getMessage(),e);
|
||||
return AsyncRpcResult.newDefaultAsyncResult(null, null, invocation); // ignore
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue