Merge remote-tracking branch 'upstream/master' into rocketmq

# Conflicts:
#	pom.xml
#	spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/RocketMQBinderUtils.java
#	spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/RocketMQMessageChannelBinder.java
#	spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/config/RocketMQComponent4BinderAutoConfiguration.java
#	spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/consuming/RocketMQListenerBindingContainer.java
#	spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/properties/RocketMQBinderConfigurationProperties.java
#	spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/test/java/com/alibaba/cloud/stream/binder/rocketmq/RocketMQAutoConfigurationTests.java
pull/2302/head
zkzlx 3 years ago
commit afdee2807d

@ -15,7 +15,7 @@ Spring Cloud Alibaba 致力于提供微服务开发的一站式解决方案。
## 主要功能
* **服务限流降级**:默认支持 WebServlet、WebFlux, OpenFeign、RestTemplate、Spring Cloud Gateway, Zuul, Dubbo 和 RocketMQ 限流降级功能的接入,可以在运行时通过控制台实时修改限流降级规则,还支持查看限流降级 Metrics 监控。
* **服务限流降级**:默认支持 WebServlet、WebFlux、OpenFeign、RestTemplate、Spring Cloud Gateway、Zuul、Dubbo 和 RocketMQ 限流降级功能的接入,可以在运行时通过控制台实时修改限流降级规则,还支持查看限流降级 Metrics 监控。
* **服务注册与发现**:适配 Spring Cloud 服务注册与发现标准,默认集成了 Ribbon 的支持。
* **分布式配置管理**:支持分布式系统中的外部化配置,配置更改时自动刷新。
* **消息驱动能力**:基于 Spring Cloud Stream 为微服务应用构建消息驱动能力。
@ -56,7 +56,7 @@ Spring Cloud Alibaba 致力于提供微服务开发的一站式解决方案。
Spring Cloud 使用 Maven 来构建,最快的使用方式是将本项目 clone 到本地,然后执行以下命令:
```bash
./mvnw install
./mvnw install
```
执行完毕后,项目将被安装到本地 Maven 仓库。
@ -66,17 +66,17 @@ Spring Cloud 使用 Maven 来构建,最快的使用方式是将本项目 clone
如果需要使用已发布的版本,在 `dependencyManagement` 中添加如下配置。
```xml
<dependencyManagement>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.2.5.RELEASE</version>
<version>2.2.6.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</dependencyManagement>
```
然后在 `dependencies` 中添加自己所需使用的依赖即可使用。

@ -59,7 +59,7 @@ For more features please refer to [Roadmap](https://github.com/alibaba/spring-cl
Spring Cloud uses Maven for most build-related activities, and you should be able to get off the ground quite quickly by cloning the project you are interested in and typing:
```bash
./mvnw install
./mvnw install
```
## How to Use
@ -68,17 +68,17 @@ Spring Cloud uses Maven for most build-related activities, and you should be abl
These artifacts are available from Maven Central and Spring Release repository via BOM:
```xml
<dependencyManagement>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.2.5.RELEASE</version>
<version>2.2.6.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</dependencyManagement>
```
add the module in `dependencies`.

@ -80,18 +80,18 @@
<properties>
<!-- Project revision -->
<revision>2.2.6-SNAPSHOT</revision>
<revision>2.2.7-SNAPSHOT</revision>
<!-- Spring Cloud -->
<spring.cloud.version>Hoxton.SR9</spring.cloud.version>
<!-- Apache Dubbo -->
<dubbo.version>2.7.8</dubbo.version>
<dubbo.version>2.7.13</dubbo.version>
<curator.version>4.0.1</curator.version>
<!-- Apache RocketMQ -->
<rocketmq.starter.version>2.0.4</rocketmq.starter.version>
<rocketmq.version>4.6.1</rocketmq.version>
<rocketmq.starter.version>2.0.2</rocketmq.starter.version>
<!-- Maven Plugin Versions -->
<maven-compiler-plugin.version>3.7.0</maven-compiler-plugin.version>

@ -18,10 +18,10 @@
<description>Spring Cloud Alibaba Dependencies</description>
<properties>
<revision>2.2.6-SNAPSHOT</revision>
<revision>2.2.7-SNAPSHOT</revision>
<sentinel.version>1.8.1</sentinel.version>
<seata.version>1.3.0</seata.version>
<nacos.client.version>1.4.2</nacos.client.version>
<nacos.client.version>2.0.3</nacos.client.version>
<nacos.config.version>0.8.0</nacos.config.version>
<spring.context.support.version>1.0.10</spring.context.support.version>

@ -348,13 +348,7 @@ Nacos Config 目前提供了三种配置能力从 Nacos 拉取相关的配置
* B: 通过 `spring.cloud.nacos.config.ext-config[n].data-id` 的方式支持多个扩展 Data Id 的配置
* C: 通过内部相关规则(应用名、应用名+ Profile )自动生成相关的 Data Id 配置
当三种方式共同使用时,他们的一个优先级关系是:
->A为优先级最高的
->B的优先级低于A
->C的优先级是最低的
当三种方式共同使用时,他们的一个优先级关系是: A < B < C
=== Nacos Config 对外暴露的 Endpoint

@ -249,6 +249,11 @@ spring.cloud.stream.rocketmq.binder.customized-trace-topic::
消息轨迹开启后存储的 topic 名称。
+
Default: `RMQ_SYS_TRACE_TOPIC`.
+
spring.cloud.stream.rocketmq.binder.access-channel::
商业版rocketmq消息轨迹topic自适应值为CLOUD
+
Default: null.
==== RocketMQ Consumer Properties
@ -346,6 +351,7 @@ NOTE: 0.1.2 & 0.2.2 & 0.9.0 才支持该功能
spring.cloud.stream.rocketmq.binder.access-key=YourAccessKey
spring.cloud.stream.rocketmq.binder.secret-key=YourSecretKey
spring.cloud.stream.rocketmq.binder.name-server=NameServerInMQ
spring.cloud.stream.rocketmq.binder.access-channel=CLOUD
```
NOTE: topic 和 group 请以 实例id% 为前缀进行配置。比如 topic 为 "test",需要配置成 "实例id%test"

@ -246,7 +246,11 @@ spring.cloud.stream.rocketmq.binder.customized-trace-topic::
The trace topic for message trace.
+
Default: `RMQ_SYS_TRACE_TOPIC`.
+
spring.cloud.stream.rocketmq.binder.access-channel::
The commercial version of rocketmq message trajectory topic is adaptive,the value is CLOUD
+
Default: null.
==== RocketMQ Consumer Properties

@ -53,6 +53,7 @@ import static com.alibaba.nacos.api.PropertyKeyConst.ENDPOINT_PORT;
import static com.alibaba.nacos.api.PropertyKeyConst.MAX_RETRY;
import static com.alibaba.nacos.api.PropertyKeyConst.NAMESPACE;
import static com.alibaba.nacos.api.PropertyKeyConst.PASSWORD;
import static com.alibaba.nacos.api.PropertyKeyConst.RAM_ROLE_NAME;
import static com.alibaba.nacos.api.PropertyKeyConst.SECRET_KEY;
import static com.alibaba.nacos.api.PropertyKeyConst.SERVER_ADDR;
import static com.alibaba.nacos.api.PropertyKeyConst.USERNAME;
@ -202,6 +203,11 @@ public class NacosConfigProperties {
*/
private String secretKey;
/**
* access key for namespace.
*/
private String ramRoleName;
/**
* context path for nacos config server.
*/
@ -356,6 +362,14 @@ public class NacosConfigProperties {
this.secretKey = secretKey;
}
public String getRamRoleName() {
return ramRoleName;
}
public void setRamRoleName(String ramRoleName) {
this.ramRoleName = ramRoleName;
}
public String getEncode() {
return encode;
}
@ -548,6 +562,7 @@ public class NacosConfigProperties {
properties.put(NAMESPACE, Objects.toString(this.namespace, ""));
properties.put(ACCESS_KEY, Objects.toString(this.accessKey, ""));
properties.put(SECRET_KEY, Objects.toString(this.secretKey, ""));
properties.put(RAM_ROLE_NAME, Objects.toString(this.ramRoleName, ""));
properties.put(CLUSTER_NAME, Objects.toString(this.clusterName, ""));
properties.put(MAX_RETRY, Objects.toString(this.maxRetry, ""));
properties.put(CONFIG_LONG_POLL_TIMEOUT,
@ -560,8 +575,7 @@ public class NacosConfigProperties {
int index = endpoint.indexOf(":");
properties.put(ENDPOINT, endpoint.substring(0, index));
properties.put(ENDPOINT_PORT, endpoint.substring(index + 1));
}
else {
} else {
properties.put(ENDPOINT, endpoint);
}
@ -597,6 +611,7 @@ public class NacosConfigProperties {
+ ", enableRemoteSyncConfig=" + enableRemoteSyncConfig + ", endpoint='"
+ endpoint + '\'' + ", namespace='" + namespace + '\'' + ", accessKey='"
+ accessKey + '\'' + ", secretKey='" + secretKey + '\''
+ ", ramRoleName='" + ramRoleName + '\''
+ ", contextPath='" + contextPath + '\'' + ", clusterName='" + clusterName
+ '\'' + ", name='" + name + '\'' + '\'' + ", shares=" + sharedConfigs
+ ", extensions=" + extensionConfigs + ", refreshEnabled="

@ -35,6 +35,7 @@ import com.alibaba.nacos.api.naming.pojo.Instance;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.cloud.client.discovery.event.HeartbeatEvent;
import org.springframework.context.ApplicationEventPublisher;
@ -45,8 +46,9 @@ import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
/**
* @author xiaojing
* @author yuhuangbin
* @author pengfei.lu
*/
public class NacosWatch implements ApplicationEventPublisherAware, SmartLifecycle {
public class NacosWatch implements ApplicationEventPublisherAware, SmartLifecycle, DisposableBean {
private static final Logger log = LoggerFactory.getLogger(NacosWatch.class);
@ -199,4 +201,8 @@ public class NacosWatch implements ApplicationEventPublisherAware, SmartLifecycl
}
@Override
public void destroy() {
this.stop();
}
}

@ -40,7 +40,8 @@ import org.springframework.test.context.junit4.SpringRunner;
*/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = NacosRibbonClientPropertyOverrideTests.TestConfiguration.class,
properties = { "spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848",
properties = { "spring.cloud.nacos.server-addr=127.0.0.1:8848",
"spring.cloud.nacos.username=nacos", "spring.cloud.nacos.password=nacos",
"spring.cloud.nacos.discovery.port=18080",
"spring.cloud.nacos.discovery.service=remoteApp",
"localApp.ribbon.NIWSServerListClassName="

@ -0,0 +1,26 @@
/*
* Copyright 2013-2018 the original author or authors.
*
* Licensed 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
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.cloud.sidecar;
/**
* @author yuhuangbin
*/
public interface CustomHealthCheckHandler {
void handler(String applicationName, SidecarInstanceInfo sidecarInstanceInfo);
}

@ -25,6 +25,8 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import reactor.core.scheduler.Schedulers;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.boot.actuate.health.Status;
import org.springframework.core.env.ConfigurableEnvironment;
@ -37,7 +39,7 @@ public class SidecarHealthChecker {
private static final Logger log = LoggerFactory.getLogger(SidecarHealthChecker.class);
private final Map<String, SidecarInstanceCache> sidecarInstanceCacheMap = new ConcurrentHashMap<>();
private final Map<String, SidecarInstanceInfo> sidecarInstanceCacheMap = new ConcurrentHashMap<>();
private final SidecarDiscoveryClient sidecarDiscoveryClient;
@ -47,6 +49,9 @@ public class SidecarHealthChecker {
private final ConfigurableEnvironment environment;
@Autowired
private ObjectProvider<CustomHealthCheckHandler> customHealthCheckHandlerObjectProvider;
public SidecarHealthChecker(SidecarDiscoveryClient sidecarDiscoveryClient,
HealthIndicator healthIndicator, SidecarProperties sidecarProperties,
ConfigurableEnvironment environment) {
@ -64,9 +69,10 @@ public class SidecarHealthChecker {
Status status = healthIndicator.health().getStatus();
instanceCache(applicationName, ip, port, status);
SidecarInstanceInfo sidecarInstanceInfo = instanceCache(applicationName, ip,
port, status);
if (status.equals(Status.UP)) {
if (needRegister(applicationName, ip, port, status)) {
if (needRegister(applicationName, sidecarInstanceInfo)) {
this.sidecarDiscoveryClient.registerInstance(applicationName, ip,
port);
log.info(
@ -84,30 +90,37 @@ public class SidecarHealthChecker {
buildCache(ip, port, status));
}
try {
customHealthCheckHandlerObjectProvider
.ifAvailable(customHealthCheckHandler -> customHealthCheckHandler
.handler(applicationName, sidecarInstanceInfo));
}
catch (Exception e) {
// ignore
}
}, 0, sidecarProperties.getHealthCheckInterval(), TimeUnit.MILLISECONDS);
}
private void instanceCache(String applicationName, String ip, Integer port,
Status status) {
sidecarInstanceCacheMap.putIfAbsent(applicationName,
buildCache(ip, port, status));
private SidecarInstanceInfo instanceCache(String applicationName, String ip,
Integer port, Status status) {
SidecarInstanceInfo sidecarInstanceInfo = buildCache(ip, port, status);
sidecarInstanceCacheMap.putIfAbsent(applicationName, sidecarInstanceInfo);
return sidecarInstanceInfo;
}
private boolean needRegister(String applicationName, String ip, Integer port,
Status status) {
SidecarInstanceCache cacheRecord = sidecarInstanceCacheMap.get(applicationName);
SidecarInstanceCache cache = buildCache(ip, port, status);
if (!Objects.equals(cache, cacheRecord)) {
private boolean needRegister(String applicationName,
SidecarInstanceInfo sidecarInstanceInfo) {
SidecarInstanceInfo cacheRecord = sidecarInstanceCacheMap.get(applicationName);
if (!Objects.equals(sidecarInstanceInfo, cacheRecord)) {
// modify the cache info
sidecarInstanceCacheMap.put(applicationName, cache);
sidecarInstanceCacheMap.put(applicationName, sidecarInstanceInfo);
return true;
}
return false;
}
private SidecarInstanceCache buildCache(String ip, Integer port, Status status) {
SidecarInstanceCache cache = new SidecarInstanceCache();
private SidecarInstanceInfo buildCache(String ip, Integer port, Status status) {
SidecarInstanceInfo cache = new SidecarInstanceInfo();
cache.setIp(ip);
cache.setPort(port);
cache.setStatus(status);

@ -23,7 +23,7 @@ import org.springframework.boot.actuate.health.Status;
/**
* @author yuhuangbin
*/
public class SidecarInstanceCache {
public class SidecarInstanceInfo {
private String ip;
@ -63,7 +63,7 @@ public class SidecarInstanceCache {
if (o == null || getClass() != o.getClass()) {
return false;
}
SidecarInstanceCache that = (SidecarInstanceCache) o;
SidecarInstanceInfo that = (SidecarInstanceInfo) o;
return Objects.equals(ip, that.ip) && Objects.equals(port, that.port)
&& Objects.equals(status, that.status);
}
Loading…
Cancel
Save