├── .gitignore ├── LICENSE ├── README.md ├── _config.yml ├── spring-cloud-bus ├── README.md ├── spring-cloud-bus-a │ ├── .gitignore │ ├── .mvn │ │ └── wrapper │ │ │ ├── MavenWrapperDownloader.java │ │ │ ├── maven-wrapper.jar │ │ │ └── maven-wrapper.properties │ ├── mvnw │ ├── mvnw.cmd │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── bluersw │ │ │ │ └── s │ │ │ │ └── c │ │ │ │ └── b │ │ │ │ └── a │ │ │ │ └── SpringCloudBusAApplication.java │ │ └── resources │ │ │ └── application.properties │ │ └── test │ │ └── java │ │ └── com │ │ └── bluersw │ │ └── s │ │ └── c │ │ └── b │ │ └── a │ │ └── SpringCloudBusAApplicationTests.java ├── spring-cloud-bus-b │ ├── .gitignore │ ├── .mvn │ │ └── wrapper │ │ │ ├── MavenWrapperDownloader.java │ │ │ ├── maven-wrapper.jar │ │ │ └── maven-wrapper.properties │ ├── mvnw │ ├── mvnw.cmd │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── bluersw │ │ │ │ └── s │ │ │ │ └── c │ │ │ │ └── b │ │ │ │ └── b │ │ │ │ └── SpringCloudBusBApplication.java │ │ └── resources │ │ │ └── application.properties │ │ └── test │ │ └── java │ │ └── com │ │ └── bluersw │ │ └── s │ │ └── c │ │ └── b │ │ └── b │ │ └── SpringCloudBusBApplicationTests.java └── spring-cloud-bus-shared-library │ ├── .gitignore │ ├── .mvn │ └── wrapper │ │ ├── MavenWrapperDownloader.java │ │ ├── maven-wrapper.jar │ │ └── maven-wrapper.properties │ ├── mvnw │ ├── mvnw.cmd │ ├── pom.xml │ └── src │ ├── main │ ├── .DS_Store │ ├── java │ │ ├── .DS_Store │ │ └── com │ │ │ ├── .DS_Store │ │ │ └── bluersw │ │ │ ├── .DS_Store │ │ │ └── s │ │ │ ├── .DS_Store │ │ │ └── c │ │ │ ├── .DS_Store │ │ │ └── b │ │ │ └── sl │ │ │ ├── BusChatConfiguration.java │ │ │ ├── ChatListener.java │ │ │ ├── ChatRemoteApplicationEvent.java │ │ │ └── SpringCloudBusSharedLibraryApplication.java │ └── resources │ │ └── application.properties │ └── test │ └── java │ └── com │ └── bluersw │ └── s │ └── c │ └── b │ └── sl │ └── SpringCloudBusSharedLibraryApplicationTests.java ├── spring-cloud-config-client ├── .gitignore ├── .mvn │ └── wrapper │ │ ├── MavenWrapperDownloader.java │ │ ├── maven-wrapper.jar │ │ └── maven-wrapper.properties ├── mvnw ├── mvnw.cmd ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── bluersw │ │ │ └── config │ │ │ └── client │ │ │ ├── SpringCloudConfigClientApplication.java │ │ │ └── controller │ │ │ └── ConfigTestController.java │ └── resources │ │ ├── application.properties │ │ └── bootstrap.properties │ └── test │ └── java │ └── com │ └── bluersw │ └── config │ └── client │ └── SpringCloudConfigClientApplicationTests.java ├── spring-cloud-config-server ├── .gitignore ├── .mvn │ └── wrapper │ │ ├── MavenWrapperDownloader.java │ │ ├── maven-wrapper.jar │ │ └── maven-wrapper.properties ├── AutoRefresh.md ├── ConfigClient.md ├── ConfigServer.md ├── ManualRefresh.md ├── README.md ├── mvnw ├── mvnw.cmd ├── pom.xml └── src │ ├── main │ ├── .DS_Store │ ├── java │ │ └── com │ │ │ └── bluersw │ │ │ └── config │ │ │ └── server │ │ │ ├── BusRefreshFilter.java │ │ │ ├── EmptyRequestWrapper.java │ │ │ └── SpringCloudConfigServerApplication.java │ └── resources │ │ └── application.properties │ └── test │ └── java │ └── com │ └── bluersw │ └── config │ └── server │ └── SpringCloudConfigServerApplicationTests.java ├── spring-cloud-consul-client ├── .gitignore ├── .mvn │ └── wrapper │ │ ├── MavenWrapperDownloader.java │ │ ├── maven-wrapper.jar │ │ └── maven-wrapper.properties ├── ConsulClusterServerClientMode.md ├── ConsulClusterServerMode.md ├── ConsumerService.md ├── CreateProject.md ├── InstallConsul.md ├── README.md ├── mvnw ├── mvnw.cmd ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── bluersw │ │ │ └── consul │ │ │ └── client │ │ │ ├── SpringCloudConsulClientApplication.java │ │ │ ├── controller │ │ │ └── TestConsul.java │ │ │ └── service │ │ │ ├── GatewayRemote.java │ │ │ └── ServiceProviderRemote.java │ └── resources │ │ └── application.properties │ └── test │ └── java │ └── com │ └── bluersw │ └── consul │ └── client │ └── SpringCloudConsulClientApplicationTests.java ├── spring-cloud-gateway ├── .gitignore ├── .mvn │ └── wrapper │ │ ├── MavenWrapperDownloader.java │ │ ├── maven-wrapper.jar │ │ └── maven-wrapper.properties ├── ConsulClusterServerClientGatewayMode.md ├── CreateProject.md ├── Fuse.md ├── README.md ├── RegisteredConsul.md ├── mvnw ├── mvnw.cmd ├── pom.xml └── src │ ├── main │ ├── .DS_Store │ ├── java │ │ └── com │ │ │ └── bluersw │ │ │ └── cloud │ │ │ └── gateway │ │ │ ├── SpringCloudGatewayApplication.java │ │ │ └── controller │ │ │ └── ErrorHandle.java │ └── resources │ │ └── application.yml │ └── test │ └── java │ └── com │ └── bluersw │ └── cloud │ └── gateway │ └── SpringCloudGatewayApplicationTests.java ├── spring-cloud-provider-second ├── .gitignore ├── .mvn │ └── wrapper │ │ ├── MavenWrapperDownloader.java │ │ ├── maven-wrapper.jar │ │ └── maven-wrapper.properties ├── mvnw ├── mvnw.cmd ├── pom.xml └── src │ ├── main │ ├── .DS_Store │ ├── java │ │ └── com │ │ │ └── bluersw │ │ │ └── provider │ │ │ └── second │ │ │ ├── SpringCloudProviderSecondApplication.java │ │ │ └── controller │ │ │ └── HelloWorld.java │ └── resources │ │ └── application.properties │ └── test │ └── java │ └── com │ └── bluersw │ └── provider │ └── second │ └── SpringCloudProviderSecondApplicationTests.java ├── spring-cloud-provider ├── .gitignore ├── .mvn │ └── wrapper │ │ ├── MavenWrapperDownloader.java │ │ ├── maven-wrapper.jar │ │ └── maven-wrapper.properties ├── CreateProject.md ├── README.md ├── RegistrationService.md ├── mvnw ├── mvnw.cmd ├── pom.xml └── src │ ├── main │ ├── .DS_Store │ ├── java │ │ ├── .DS_Store │ │ └── com │ │ │ ├── .DS_Store │ │ │ └── bluersw │ │ │ ├── .DS_Store │ │ │ └── cloud │ │ │ ├── .DS_Store │ │ │ └── provider │ │ │ ├── SpringCloudProviderApplication.java │ │ │ └── controller │ │ │ └── HelloWorld.java │ └── resources │ │ └── application.properties │ └── test │ └── java │ └── com │ └── bluersw │ └── cloud │ └── provider │ └── SpringCloudProviderApplicationTests.java └── spring-cloud-stream ├── README.md ├── spring-cloud-stream-a ├── .gitignore ├── .mvn │ └── wrapper │ │ ├── MavenWrapperDownloader.java │ │ ├── maven-wrapper.jar │ │ └── maven-wrapper.properties ├── mvnw ├── mvnw.cmd ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── bluersw │ │ │ └── s │ │ │ └── c │ │ │ └── s │ │ │ └── a │ │ │ ├── AClient.java │ │ │ ├── ChatInput.java │ │ │ ├── ChatMessage.java │ │ │ ├── ChatOutput.java │ │ │ └── SpringCloudStreamAApplication.java │ └── resources │ │ └── application.properties │ └── test │ └── java │ └── com │ └── bluersw │ └── s │ └── c │ └── s │ └── a │ └── SpringCloudStreamAApplicationTests.java └── spring-cloud-stream-b ├── .gitignore ├── .mvn └── wrapper │ ├── MavenWrapperDownloader.java │ ├── maven-wrapper.jar │ └── maven-wrapper.properties ├── mvnw ├── mvnw.cmd ├── pom.xml └── src ├── main ├── java │ └── com │ │ └── bluersw │ │ └── s │ │ └── c │ │ └── s │ │ └── b │ │ ├── BClient.java │ │ ├── ChatMessage.java │ │ ├── ChatProcessor.java │ │ └── SpringCloudStreamBApplication.java └── resources │ └── application.properties └── test └── java └── com └── bluersw └── s └── c └── s └── b └── SpringCloudStreamBApplicationTests.java /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | !.mvn/wrapper/maven-wrapper.jar 3 | !**/src/main/** 4 | !**/src/test/** 5 | 6 | ### STS ### 7 | .apt_generated 8 | .classpath 9 | .factorypath 10 | .project 11 | .settings 12 | .springBeans 13 | .sts4-cache 14 | 15 | ### IntelliJ IDEA ### 16 | .idea 17 | *.iws 18 | *.iml 19 | *.ipr 20 | 21 | ### NetBeans ### 22 | /nbproject/private/ 23 | /nbbuild/ 24 | /dist/ 25 | /nbdist/ 26 | /.nb-gradle/ 27 | build/ 28 | 29 | ### VS Code ### 30 | .vscode/ 31 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 sunweisheng 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 目录 2 | 3 | * [创建微服务项目(Spring Boot)](./spring-cloud-provider/CreateProject.md) 4 | * [安装Consul服务中心](./spring-cloud-consul-client/InstallConsul.md) 5 | * [注册服务到服务中心(Consul)](./spring-cloud-provider/RegistrationService.md) 6 | * [创建Consul客户端项目](./spring-cloud-consul-client/CreateProject.md) 7 | * [调用Consul服务(消费服务)](./spring-cloud-consul-client/ConsumerService.md) 8 | * [创建网关项目](./spring-cloud-gateway/CreateProject.md) 9 | * [Spring Cloud Gateway注册到服务器中心(Consul)](./spring-cloud-gateway/RegisteredConsul.md) 10 | * [网关中加入熔断机制](./spring-cloud-gateway/Fuse.md) 11 | * [Consul集群Server模式](./spring-cloud-consul-client/ConsulClusterServerMode.md) 12 | * [Consul集群Server+Client模式](./spring-cloud-consul-client/ConsulClusterServerClientMode.md) 13 | * [Consul集群加入网关服务](./spring-cloud-gateway/ConsulClusterServerClientGatewayMode.md) 14 | * [创建配置中心服务端](./spring-cloud-config-server/ConfigServer.md) 15 | * [创建客户端项目并读取服务化的配置中心](./spring-cloud-config-server/ConfigClient.md) 16 | * [手动刷新客户端配置内容](./spring-cloud-config-server/ManualRefresh.md) 17 | * [通过总线机制实现自动刷新客户端配置](./spring-cloud-config-server/AutoRefresh.md) 18 | * [细聊Spring Cloud Bus](./spring-cloud-bus/README.md) 19 | * [Spring Cloud Stream](./spring-cloud-stream/README.md) 20 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-minimal -------------------------------------------------------------------------------- /spring-cloud-bus/spring-cloud-bus-a/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | .DS_Store 4 | !.mvn/wrapper/maven-wrapper.jar 5 | !**/src/main/** 6 | !**/src/test/** 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | 17 | ### IntelliJ IDEA ### 18 | .idea 19 | *.iws 20 | *.iml 21 | *.ipr 22 | 23 | ### NetBeans ### 24 | /nbproject/private/ 25 | /nbbuild/ 26 | /dist/ 27 | /nbdist/ 28 | /.nb-gradle/ 29 | build/ 30 | 31 | ### VS Code ### 32 | .vscode/ 33 | -------------------------------------------------------------------------------- /spring-cloud-bus/spring-cloud-bus-a/.mvn/wrapper/MavenWrapperDownloader.java: -------------------------------------------------------------------------------- 1 | /* 2 | Licensed to the Apache Software Foundation (ASF) under one 3 | or more contributor license agreements. See the NOTICE file 4 | distributed with this work for additional information 5 | regarding copyright ownership. The ASF licenses this file 6 | to you under the Apache License, Version 2.0 (the 7 | "License"); you may not use this file except in compliance 8 | with the License. You may obtain a copy of the License at 9 | 10 | https://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, 13 | software distributed under the License is distributed on an 14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | KIND, either express or implied. See the License for the 16 | specific language governing permissions and limitations 17 | under the License. 18 | */ 19 | 20 | import java.io.File; 21 | import java.io.FileInputStream; 22 | import java.io.FileOutputStream; 23 | import java.io.IOException; 24 | import java.net.URL; 25 | import java.nio.channels.Channels; 26 | import java.nio.channels.ReadableByteChannel; 27 | import java.util.Properties; 28 | 29 | public class MavenWrapperDownloader { 30 | 31 | /** 32 | * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. 33 | */ 34 | private static final String DEFAULT_DOWNLOAD_URL = 35 | "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar"; 36 | 37 | /** 38 | * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to 39 | * use instead of the default one. 40 | */ 41 | private static final String MAVEN_WRAPPER_PROPERTIES_PATH = 42 | ".mvn/wrapper/maven-wrapper.properties"; 43 | 44 | /** 45 | * Path where the maven-wrapper.jar will be saved to. 46 | */ 47 | private static final String MAVEN_WRAPPER_JAR_PATH = 48 | ".mvn/wrapper/maven-wrapper.jar"; 49 | 50 | /** 51 | * Name of the property which should be used to override the default download url for the wrapper. 52 | */ 53 | private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; 54 | 55 | public static void main(String args[]) { 56 | System.out.println("- Downloader started"); 57 | File baseDirectory = new File(args[0]); 58 | System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); 59 | 60 | // If the maven-wrapper.properties exists, read it and check if it contains a custom 61 | // wrapperUrl parameter. 62 | File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); 63 | String url = DEFAULT_DOWNLOAD_URL; 64 | if(mavenWrapperPropertyFile.exists()) { 65 | FileInputStream mavenWrapperPropertyFileInputStream = null; 66 | try { 67 | mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); 68 | Properties mavenWrapperProperties = new Properties(); 69 | mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); 70 | url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); 71 | } catch (IOException e) { 72 | System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); 73 | } finally { 74 | try { 75 | if(mavenWrapperPropertyFileInputStream != null) { 76 | mavenWrapperPropertyFileInputStream.close(); 77 | } 78 | } catch (IOException e) { 79 | // Ignore ... 80 | } 81 | } 82 | } 83 | System.out.println("- Downloading from: : " + url); 84 | 85 | File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); 86 | if(!outputFile.getParentFile().exists()) { 87 | if(!outputFile.getParentFile().mkdirs()) { 88 | System.out.println( 89 | "- ERROR creating output direcrory '" + outputFile.getParentFile().getAbsolutePath() + "'"); 90 | } 91 | } 92 | System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); 93 | try { 94 | downloadFileFromURL(url, outputFile); 95 | System.out.println("Done"); 96 | System.exit(0); 97 | } catch (Throwable e) { 98 | System.out.println("- Error downloading"); 99 | e.printStackTrace(); 100 | System.exit(1); 101 | } 102 | } 103 | 104 | private static void downloadFileFromURL(String urlString, File destination) throws Exception { 105 | URL website = new URL(urlString); 106 | ReadableByteChannel rbc; 107 | rbc = Channels.newChannel(website.openStream()); 108 | FileOutputStream fos = new FileOutputStream(destination); 109 | fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); 110 | fos.close(); 111 | rbc.close(); 112 | } 113 | 114 | } 115 | -------------------------------------------------------------------------------- /spring-cloud-bus/spring-cloud-bus-a/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunweisheng/spring-cloud-example/29ede89ea30037025ce3644380edbe9b5738f696/spring-cloud-bus/spring-cloud-bus-a/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /spring-cloud-bus/spring-cloud-bus-a/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.0/apache-maven-3.6.0-bin.zip 2 | -------------------------------------------------------------------------------- /spring-cloud-bus/spring-cloud-bus-a/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.1.9.RELEASE 9 | 10 | 11 | com.bluersw 12 | spring-cloud-bus-a 13 | 0.0.1-SNAPSHOT 14 | spring-cloud-bus-a 15 | Demo project for Spring Cloud Bus A 16 | 17 | 18 | 1.8 19 | Greenwich.SR3 20 | 21 | 22 | 23 | 24 | org.springframework.boot 25 | spring-boot-starter-actuator 26 | 27 | 28 | org.springframework.cloud 29 | spring-cloud-bus 30 | 31 | 32 | 33 | org.springframework.boot 34 | spring-boot-starter-test 35 | test 36 | 37 | 38 | com.bluersw 39 | spring-cloud-bus-shared-library 40 | 0.0.1-SNAPSHOT 41 | 42 | 43 | 44 | 45 | 46 | 47 | org.springframework.cloud 48 | spring-cloud-dependencies 49 | ${spring-cloud.version} 50 | pom 51 | import 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | org.springframework.boot 60 | spring-boot-maven-plugin 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /spring-cloud-bus/spring-cloud-bus-a/src/main/java/com/bluersw/s/c/b/a/SpringCloudBusAApplication.java: -------------------------------------------------------------------------------- 1 | package com.bluersw.s.c.b.a; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.context.annotation.ComponentScan; 6 | 7 | @SpringBootApplication 8 | @ComponentScan(value = "com.bluersw") 9 | public class SpringCloudBusAApplication { 10 | 11 | public static void main(String[] args) { 12 | SpringApplication.run(SpringCloudBusAApplication.class, args); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /spring-cloud-bus/spring-cloud-bus-a/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.application.name=spring-cloud-bus-a 2 | server.port=9008 3 | # 开启消息跟踪 4 | spring.cloud.bus.trace.enabled=true 5 | spring.rabbitmq.host=127.0.0.1 6 | spring.rabbitmq.port=5672 7 | spring.rabbitmq.username=guest 8 | spring.rabbitmq.password=guest 9 | 10 | #显示的暴露接入点 11 | management.endpoints.web.exposure.include=* 12 | -------------------------------------------------------------------------------- /spring-cloud-bus/spring-cloud-bus-a/src/test/java/com/bluersw/s/c/b/a/SpringCloudBusAApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.bluersw.s.c.b.a; 2 | 3 | import com.bluersw.s.c.b.sl.ChatRemoteApplicationEvent; 4 | import org.junit.Test; 5 | import org.junit.runner.RunWith; 6 | 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.boot.test.context.SpringBootTest; 9 | import org.springframework.cloud.bus.BusProperties; 10 | import org.springframework.context.ApplicationEventPublisher; 11 | import org.springframework.test.context.junit4.SpringRunner; 12 | 13 | @RunWith(SpringRunner.class) 14 | @SpringBootTest 15 | public class SpringCloudBusAApplicationTests { 16 | 17 | @Autowired 18 | private ApplicationEventPublisher context; 19 | 20 | @Autowired 21 | private BusProperties bp; 22 | 23 | @Test 24 | public void AChat() { 25 | context.publishEvent(new ChatRemoteApplicationEvent(this,bp.getId(),null,"hi!B应用,我是A应用,。")); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /spring-cloud-bus/spring-cloud-bus-b/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | .DS_Store 4 | !.mvn/wrapper/maven-wrapper.jar 5 | !**/src/main/** 6 | !**/src/test/** 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | 17 | ### IntelliJ IDEA ### 18 | .idea 19 | *.iws 20 | *.iml 21 | *.ipr 22 | 23 | ### NetBeans ### 24 | /nbproject/private/ 25 | /nbbuild/ 26 | /dist/ 27 | /nbdist/ 28 | /.nb-gradle/ 29 | build/ 30 | 31 | ### VS Code ### 32 | .vscode/ 33 | -------------------------------------------------------------------------------- /spring-cloud-bus/spring-cloud-bus-b/.mvn/wrapper/MavenWrapperDownloader.java: -------------------------------------------------------------------------------- 1 | /* 2 | Licensed to the Apache Software Foundation (ASF) under one 3 | or more contributor license agreements. See the NOTICE file 4 | distributed with this work for additional information 5 | regarding copyright ownership. The ASF licenses this file 6 | to you under the Apache License, Version 2.0 (the 7 | "License"); you may not use this file except in compliance 8 | with the License. You may obtain a copy of the License at 9 | 10 | https://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, 13 | software distributed under the License is distributed on an 14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | KIND, either express or implied. See the License for the 16 | specific language governing permissions and limitations 17 | under the License. 18 | */ 19 | 20 | import java.io.File; 21 | import java.io.FileInputStream; 22 | import java.io.FileOutputStream; 23 | import java.io.IOException; 24 | import java.net.URL; 25 | import java.nio.channels.Channels; 26 | import java.nio.channels.ReadableByteChannel; 27 | import java.util.Properties; 28 | 29 | public class MavenWrapperDownloader { 30 | 31 | /** 32 | * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. 33 | */ 34 | private static final String DEFAULT_DOWNLOAD_URL = 35 | "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar"; 36 | 37 | /** 38 | * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to 39 | * use instead of the default one. 40 | */ 41 | private static final String MAVEN_WRAPPER_PROPERTIES_PATH = 42 | ".mvn/wrapper/maven-wrapper.properties"; 43 | 44 | /** 45 | * Path where the maven-wrapper.jar will be saved to. 46 | */ 47 | private static final String MAVEN_WRAPPER_JAR_PATH = 48 | ".mvn/wrapper/maven-wrapper.jar"; 49 | 50 | /** 51 | * Name of the property which should be used to override the default download url for the wrapper. 52 | */ 53 | private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; 54 | 55 | public static void main(String args[]) { 56 | System.out.println("- Downloader started"); 57 | File baseDirectory = new File(args[0]); 58 | System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); 59 | 60 | // If the maven-wrapper.properties exists, read it and check if it contains a custom 61 | // wrapperUrl parameter. 62 | File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); 63 | String url = DEFAULT_DOWNLOAD_URL; 64 | if(mavenWrapperPropertyFile.exists()) { 65 | FileInputStream mavenWrapperPropertyFileInputStream = null; 66 | try { 67 | mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); 68 | Properties mavenWrapperProperties = new Properties(); 69 | mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); 70 | url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); 71 | } catch (IOException e) { 72 | System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); 73 | } finally { 74 | try { 75 | if(mavenWrapperPropertyFileInputStream != null) { 76 | mavenWrapperPropertyFileInputStream.close(); 77 | } 78 | } catch (IOException e) { 79 | // Ignore ... 80 | } 81 | } 82 | } 83 | System.out.println("- Downloading from: : " + url); 84 | 85 | File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); 86 | if(!outputFile.getParentFile().exists()) { 87 | if(!outputFile.getParentFile().mkdirs()) { 88 | System.out.println( 89 | "- ERROR creating output direcrory '" + outputFile.getParentFile().getAbsolutePath() + "'"); 90 | } 91 | } 92 | System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); 93 | try { 94 | downloadFileFromURL(url, outputFile); 95 | System.out.println("Done"); 96 | System.exit(0); 97 | } catch (Throwable e) { 98 | System.out.println("- Error downloading"); 99 | e.printStackTrace(); 100 | System.exit(1); 101 | } 102 | } 103 | 104 | private static void downloadFileFromURL(String urlString, File destination) throws Exception { 105 | URL website = new URL(urlString); 106 | ReadableByteChannel rbc; 107 | rbc = Channels.newChannel(website.openStream()); 108 | FileOutputStream fos = new FileOutputStream(destination); 109 | fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); 110 | fos.close(); 111 | rbc.close(); 112 | } 113 | 114 | } 115 | -------------------------------------------------------------------------------- /spring-cloud-bus/spring-cloud-bus-b/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunweisheng/spring-cloud-example/29ede89ea30037025ce3644380edbe9b5738f696/spring-cloud-bus/spring-cloud-bus-b/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /spring-cloud-bus/spring-cloud-bus-b/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.0/apache-maven-3.6.0-bin.zip 2 | -------------------------------------------------------------------------------- /spring-cloud-bus/spring-cloud-bus-b/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.1.9.RELEASE 9 | 10 | 11 | com.bluersw 12 | spring-cloud-bus-b 13 | 0.0.1-SNAPSHOT 14 | spring-cloud-bus-b 15 | Demo project for Spring Cloud Bus B 16 | 17 | 18 | 1.8 19 | Greenwich.SR3 20 | 21 | 22 | 23 | 24 | org.springframework.boot 25 | spring-boot-starter-actuator 26 | 27 | 28 | org.springframework.cloud 29 | spring-cloud-bus 30 | 31 | 32 | 33 | org.springframework.boot 34 | spring-boot-starter-test 35 | test 36 | 37 | 38 | com.bluersw 39 | spring-cloud-bus-shared-library 40 | 0.0.1-SNAPSHOT 41 | 42 | 43 | 44 | 45 | 46 | 47 | org.springframework.cloud 48 | spring-cloud-dependencies 49 | ${spring-cloud.version} 50 | pom 51 | import 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | org.springframework.boot 60 | spring-boot-maven-plugin 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /spring-cloud-bus/spring-cloud-bus-b/src/main/java/com/bluersw/s/c/b/b/SpringCloudBusBApplication.java: -------------------------------------------------------------------------------- 1 | package com.bluersw.s.c.b.b; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.context.annotation.ComponentScan; 6 | 7 | @SpringBootApplication 8 | @ComponentScan(value = "com.bluersw") 9 | public class SpringCloudBusBApplication { 10 | 11 | public static void main(String[] args) { 12 | SpringApplication.run(SpringCloudBusBApplication.class, args); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /spring-cloud-bus/spring-cloud-bus-b/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.application.name=spring-cloud-bus-b 2 | server.port=9009 3 | # 开启消息跟踪 4 | spring.cloud.bus.trace.enabled=true 5 | spring.rabbitmq.host=127.0.0.1 6 | spring.rabbitmq.port=5672 7 | spring.rabbitmq.username=guest 8 | spring.rabbitmq.password=guest 9 | 10 | #显示的暴露接入点 11 | management.endpoints.web.exposure.include=* 12 | -------------------------------------------------------------------------------- /spring-cloud-bus/spring-cloud-bus-b/src/test/java/com/bluersw/s/c/b/b/SpringCloudBusBApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.bluersw.s.c.b.b; 2 | 3 | import com.bluersw.s.c.b.sl.ChatRemoteApplicationEvent; 4 | import org.junit.Test; 5 | import org.junit.runner.RunWith; 6 | 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.boot.test.context.SpringBootTest; 9 | import org.springframework.cloud.bus.BusProperties; 10 | import org.springframework.context.ApplicationEventPublisher; 11 | import org.springframework.test.context.junit4.SpringRunner; 12 | 13 | @RunWith(SpringRunner.class) 14 | @SpringBootTest 15 | public class SpringCloudBusBApplicationTests { 16 | 17 | @Autowired 18 | private ApplicationEventPublisher context; 19 | 20 | @Autowired 21 | private BusProperties bp; 22 | 23 | @Test 24 | public void BChat() { 25 | context.publishEvent(new ChatRemoteApplicationEvent(this,bp.getId(),"spring-cloud-bus-a:9008","hi!我是B应用,这样才能不被其他应用接收到。")); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /spring-cloud-bus/spring-cloud-bus-shared-library/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | .DS_Store 4 | !.mvn/wrapper/maven-wrapper.jar 5 | !**/src/main/** 6 | !**/src/test/** 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | 17 | ### IntelliJ IDEA ### 18 | .idea 19 | *.iws 20 | *.iml 21 | *.ipr 22 | 23 | ### NetBeans ### 24 | /nbproject/private/ 25 | /nbbuild/ 26 | /dist/ 27 | /nbdist/ 28 | /.nb-gradle/ 29 | build/ 30 | 31 | ### VS Code ### 32 | .vscode/ 33 | -------------------------------------------------------------------------------- /spring-cloud-bus/spring-cloud-bus-shared-library/.mvn/wrapper/MavenWrapperDownloader.java: -------------------------------------------------------------------------------- 1 | /* 2 | Licensed to the Apache Software Foundation (ASF) under one 3 | or more contributor license agreements. See the NOTICE file 4 | distributed with this work for additional information 5 | regarding copyright ownership. The ASF licenses this file 6 | to you under the Apache License, Version 2.0 (the 7 | "License"); you may not use this file except in compliance 8 | with the License. You may obtain a copy of the License at 9 | 10 | https://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, 13 | software distributed under the License is distributed on an 14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | KIND, either express or implied. See the License for the 16 | specific language governing permissions and limitations 17 | under the License. 18 | */ 19 | 20 | import java.io.File; 21 | import java.io.FileInputStream; 22 | import java.io.FileOutputStream; 23 | import java.io.IOException; 24 | import java.net.URL; 25 | import java.nio.channels.Channels; 26 | import java.nio.channels.ReadableByteChannel; 27 | import java.util.Properties; 28 | 29 | public class MavenWrapperDownloader { 30 | 31 | /** 32 | * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. 33 | */ 34 | private static final String DEFAULT_DOWNLOAD_URL = 35 | "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar"; 36 | 37 | /** 38 | * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to 39 | * use instead of the default one. 40 | */ 41 | private static final String MAVEN_WRAPPER_PROPERTIES_PATH = 42 | ".mvn/wrapper/maven-wrapper.properties"; 43 | 44 | /** 45 | * Path where the maven-wrapper.jar will be saved to. 46 | */ 47 | private static final String MAVEN_WRAPPER_JAR_PATH = 48 | ".mvn/wrapper/maven-wrapper.jar"; 49 | 50 | /** 51 | * Name of the property which should be used to override the default download url for the wrapper. 52 | */ 53 | private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; 54 | 55 | public static void main(String args[]) { 56 | System.out.println("- Downloader started"); 57 | File baseDirectory = new File(args[0]); 58 | System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); 59 | 60 | // If the maven-wrapper.properties exists, read it and check if it contains a custom 61 | // wrapperUrl parameter. 62 | File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); 63 | String url = DEFAULT_DOWNLOAD_URL; 64 | if(mavenWrapperPropertyFile.exists()) { 65 | FileInputStream mavenWrapperPropertyFileInputStream = null; 66 | try { 67 | mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); 68 | Properties mavenWrapperProperties = new Properties(); 69 | mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); 70 | url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); 71 | } catch (IOException e) { 72 | System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); 73 | } finally { 74 | try { 75 | if(mavenWrapperPropertyFileInputStream != null) { 76 | mavenWrapperPropertyFileInputStream.close(); 77 | } 78 | } catch (IOException e) { 79 | // Ignore ... 80 | } 81 | } 82 | } 83 | System.out.println("- Downloading from: : " + url); 84 | 85 | File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); 86 | if(!outputFile.getParentFile().exists()) { 87 | if(!outputFile.getParentFile().mkdirs()) { 88 | System.out.println( 89 | "- ERROR creating output direcrory '" + outputFile.getParentFile().getAbsolutePath() + "'"); 90 | } 91 | } 92 | System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); 93 | try { 94 | downloadFileFromURL(url, outputFile); 95 | System.out.println("Done"); 96 | System.exit(0); 97 | } catch (Throwable e) { 98 | System.out.println("- Error downloading"); 99 | e.printStackTrace(); 100 | System.exit(1); 101 | } 102 | } 103 | 104 | private static void downloadFileFromURL(String urlString, File destination) throws Exception { 105 | URL website = new URL(urlString); 106 | ReadableByteChannel rbc; 107 | rbc = Channels.newChannel(website.openStream()); 108 | FileOutputStream fos = new FileOutputStream(destination); 109 | fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); 110 | fos.close(); 111 | rbc.close(); 112 | } 113 | 114 | } 115 | -------------------------------------------------------------------------------- /spring-cloud-bus/spring-cloud-bus-shared-library/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunweisheng/spring-cloud-example/29ede89ea30037025ce3644380edbe9b5738f696/spring-cloud-bus/spring-cloud-bus-shared-library/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /spring-cloud-bus/spring-cloud-bus-shared-library/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.0/apache-maven-3.6.0-bin.zip 2 | -------------------------------------------------------------------------------- /spring-cloud-bus/spring-cloud-bus-shared-library/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.1.9.RELEASE 9 | 10 | 11 | com.bluersw 12 | spring-cloud-bus-shared-library 13 | 0.0.1-SNAPSHOT 14 | spring-cloud-bus-shared-library 15 | Demo project for Spring Cloud Bus SL 16 | 17 | 18 | 1.8 19 | Greenwich.SR3 20 | 21 | 22 | 23 | 24 | org.springframework.cloud 25 | spring-cloud-starter-bus-amqp 26 | 27 | 28 | org.springframework.boot 29 | spring-boot-starter-actuator 30 | 31 | 32 | org.springframework.boot 33 | spring-boot-starter-test 34 | test 35 | 36 | 37 | 38 | 39 | 40 | 41 | org.springframework.cloud 42 | spring-cloud-dependencies 43 | ${spring-cloud.version} 44 | pom 45 | import 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /spring-cloud-bus/spring-cloud-bus-shared-library/src/main/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunweisheng/spring-cloud-example/29ede89ea30037025ce3644380edbe9b5738f696/spring-cloud-bus/spring-cloud-bus-shared-library/src/main/.DS_Store -------------------------------------------------------------------------------- /spring-cloud-bus/spring-cloud-bus-shared-library/src/main/java/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunweisheng/spring-cloud-example/29ede89ea30037025ce3644380edbe9b5738f696/spring-cloud-bus/spring-cloud-bus-shared-library/src/main/java/.DS_Store -------------------------------------------------------------------------------- /spring-cloud-bus/spring-cloud-bus-shared-library/src/main/java/com/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunweisheng/spring-cloud-example/29ede89ea30037025ce3644380edbe9b5738f696/spring-cloud-bus/spring-cloud-bus-shared-library/src/main/java/com/.DS_Store -------------------------------------------------------------------------------- /spring-cloud-bus/spring-cloud-bus-shared-library/src/main/java/com/bluersw/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunweisheng/spring-cloud-example/29ede89ea30037025ce3644380edbe9b5738f696/spring-cloud-bus/spring-cloud-bus-shared-library/src/main/java/com/bluersw/.DS_Store -------------------------------------------------------------------------------- /spring-cloud-bus/spring-cloud-bus-shared-library/src/main/java/com/bluersw/s/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunweisheng/spring-cloud-example/29ede89ea30037025ce3644380edbe9b5738f696/spring-cloud-bus/spring-cloud-bus-shared-library/src/main/java/com/bluersw/s/.DS_Store -------------------------------------------------------------------------------- /spring-cloud-bus/spring-cloud-bus-shared-library/src/main/java/com/bluersw/s/c/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunweisheng/spring-cloud-example/29ede89ea30037025ce3644380edbe9b5738f696/spring-cloud-bus/spring-cloud-bus-shared-library/src/main/java/com/bluersw/s/c/.DS_Store -------------------------------------------------------------------------------- /spring-cloud-bus/spring-cloud-bus-shared-library/src/main/java/com/bluersw/s/c/b/sl/BusChatConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.bluersw.s.c.b.sl; 2 | 3 | import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 4 | import org.springframework.cloud.bus.jackson.RemoteApplicationEventScan; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Configuration; 7 | 8 | @Configuration 9 | @ConditionalOnClass(ChatListener.class) 10 | @RemoteApplicationEventScan(basePackageClasses=ChatRemoteApplicationEvent.class) 11 | public class BusChatConfiguration { 12 | 13 | @Bean 14 | public ChatListener ChatListener(){ 15 | return new ChatListener(); 16 | } 17 | } 18 | 19 | -------------------------------------------------------------------------------- /spring-cloud-bus/spring-cloud-bus-shared-library/src/main/java/com/bluersw/s/c/b/sl/ChatListener.java: -------------------------------------------------------------------------------- 1 | package com.bluersw.s.c.b.sl; 2 | 3 | import org.apache.commons.logging.Log; 4 | import org.apache.commons.logging.LogFactory; 5 | 6 | import org.springframework.context.ApplicationListener; 7 | 8 | /** 9 | * 聊天事件监听 10 | */ 11 | public class ChatListener implements ApplicationListener { 12 | 13 | private static Log log = LogFactory.getLog(ChatListener.class); 14 | 15 | public ChatListener(){} 16 | 17 | @Override 18 | public void onApplicationEvent(ChatRemoteApplicationEvent event){ 19 | log.info(String.format("应用%s对应用%s悄悄的说:\"%s\"", 20 | event.getOriginService(), 21 | event.getDestinationService(), 22 | event.getMessage())); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /spring-cloud-bus/spring-cloud-bus-shared-library/src/main/java/com/bluersw/s/c/b/sl/ChatRemoteApplicationEvent.java: -------------------------------------------------------------------------------- 1 | package com.bluersw.s.c.b.sl; 2 | 3 | import org.springframework.cloud.bus.event.RemoteApplicationEvent; 4 | 5 | /** 6 | * 聊天事件 7 | */ 8 | public class ChatRemoteApplicationEvent extends RemoteApplicationEvent { 9 | 10 | private String message; 11 | 12 | private ChatRemoteApplicationEvent(){} 13 | 14 | public ChatRemoteApplicationEvent(Object source, String originService, 15 | String destinationService,String message){ 16 | super(source, originService, destinationService); 17 | 18 | this.message = message; 19 | } 20 | 21 | public void setMessage(String message){ 22 | this.message = message; 23 | } 24 | 25 | public String getMessage(){ 26 | return this.message; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /spring-cloud-bus/spring-cloud-bus-shared-library/src/main/java/com/bluersw/s/c/b/sl/SpringCloudBusSharedLibraryApplication.java: -------------------------------------------------------------------------------- 1 | package com.bluersw.s.c.b.sl; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.context.annotation.ComponentScan; 6 | 7 | @SpringBootApplication 8 | public class SpringCloudBusSharedLibraryApplication { 9 | 10 | public static void main(String[] args) { 11 | SpringApplication.run(SpringCloudBusSharedLibraryApplication.class, args); 12 | 13 | } 14 | } 15 | 16 | 17 | -------------------------------------------------------------------------------- /spring-cloud-bus/spring-cloud-bus-shared-library/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.application.name=spring-cloud-bus-shared-library 2 | server.port=9007 3 | # 开启消息跟踪 4 | spring.cloud.bus.trace.enabled=true 5 | spring.rabbitmq.host=127.0.0.1 6 | spring.rabbitmq.port=5672 7 | spring.rabbitmq.username=guest 8 | spring.rabbitmq.password=guest 9 | 10 | #显示的暴露接入点 11 | management.endpoints.web.exposure.include=* -------------------------------------------------------------------------------- /spring-cloud-bus/spring-cloud-bus-shared-library/src/test/java/com/bluersw/s/c/b/sl/SpringCloudBusSharedLibraryApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.bluersw.s.c.b.sl; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.boot.test.context.SpringBootTest; 8 | import org.springframework.cloud.bus.BusProperties; 9 | import org.springframework.context.ApplicationEventPublisher; 10 | import org.springframework.test.context.junit4.SpringRunner; 11 | 12 | @RunWith(SpringRunner.class) 13 | @SpringBootTest 14 | public class SpringCloudBusSharedLibraryApplicationTests { 15 | 16 | @Autowired 17 | private ApplicationEventPublisher context; 18 | 19 | @Autowired 20 | private BusProperties bp; 21 | 22 | @Test 23 | public void PublishEventTest() { 24 | context.publishEvent(new ChatRemoteApplicationEvent(this,bp.getId(),null,"测试群聊")); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /spring-cloud-config-client/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/** 5 | !**/src/test/** 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | 30 | ### VS Code ### 31 | .vscode/ 32 | -------------------------------------------------------------------------------- /spring-cloud-config-client/.mvn/wrapper/MavenWrapperDownloader.java: -------------------------------------------------------------------------------- 1 | /* 2 | Licensed to the Apache Software Foundation (ASF) under one 3 | or more contributor license agreements. See the NOTICE file 4 | distributed with this work for additional information 5 | regarding copyright ownership. The ASF licenses this file 6 | to you under the Apache License, Version 2.0 (the 7 | "License"); you may not use this file except in compliance 8 | with the License. You may obtain a copy of the License at 9 | 10 | https://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, 13 | software distributed under the License is distributed on an 14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | KIND, either express or implied. See the License for the 16 | specific language governing permissions and limitations 17 | under the License. 18 | */ 19 | 20 | import java.io.File; 21 | import java.io.FileInputStream; 22 | import java.io.FileOutputStream; 23 | import java.io.IOException; 24 | import java.net.URL; 25 | import java.nio.channels.Channels; 26 | import java.nio.channels.ReadableByteChannel; 27 | import java.util.Properties; 28 | 29 | public class MavenWrapperDownloader { 30 | 31 | /** 32 | * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. 33 | */ 34 | private static final String DEFAULT_DOWNLOAD_URL = 35 | "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar"; 36 | 37 | /** 38 | * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to 39 | * use instead of the default one. 40 | */ 41 | private static final String MAVEN_WRAPPER_PROPERTIES_PATH = 42 | ".mvn/wrapper/maven-wrapper.properties"; 43 | 44 | /** 45 | * Path where the maven-wrapper.jar will be saved to. 46 | */ 47 | private static final String MAVEN_WRAPPER_JAR_PATH = 48 | ".mvn/wrapper/maven-wrapper.jar"; 49 | 50 | /** 51 | * Name of the property which should be used to override the default download url for the wrapper. 52 | */ 53 | private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; 54 | 55 | public static void main(String args[]) { 56 | System.out.println("- Downloader started"); 57 | File baseDirectory = new File(args[0]); 58 | System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); 59 | 60 | // If the maven-wrapper.properties exists, read it and check if it contains a custom 61 | // wrapperUrl parameter. 62 | File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); 63 | String url = DEFAULT_DOWNLOAD_URL; 64 | if(mavenWrapperPropertyFile.exists()) { 65 | FileInputStream mavenWrapperPropertyFileInputStream = null; 66 | try { 67 | mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); 68 | Properties mavenWrapperProperties = new Properties(); 69 | mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); 70 | url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); 71 | } catch (IOException e) { 72 | System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); 73 | } finally { 74 | try { 75 | if(mavenWrapperPropertyFileInputStream != null) { 76 | mavenWrapperPropertyFileInputStream.close(); 77 | } 78 | } catch (IOException e) { 79 | // Ignore ... 80 | } 81 | } 82 | } 83 | System.out.println("- Downloading from: : " + url); 84 | 85 | File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); 86 | if(!outputFile.getParentFile().exists()) { 87 | if(!outputFile.getParentFile().mkdirs()) { 88 | System.out.println( 89 | "- ERROR creating output direcrory '" + outputFile.getParentFile().getAbsolutePath() + "'"); 90 | } 91 | } 92 | System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); 93 | try { 94 | downloadFileFromURL(url, outputFile); 95 | System.out.println("Done"); 96 | System.exit(0); 97 | } catch (Throwable e) { 98 | System.out.println("- Error downloading"); 99 | e.printStackTrace(); 100 | System.exit(1); 101 | } 102 | } 103 | 104 | private static void downloadFileFromURL(String urlString, File destination) throws Exception { 105 | URL website = new URL(urlString); 106 | ReadableByteChannel rbc; 107 | rbc = Channels.newChannel(website.openStream()); 108 | FileOutputStream fos = new FileOutputStream(destination); 109 | fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); 110 | fos.close(); 111 | rbc.close(); 112 | } 113 | 114 | } 115 | -------------------------------------------------------------------------------- /spring-cloud-config-client/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunweisheng/spring-cloud-example/29ede89ea30037025ce3644380edbe9b5738f696/spring-cloud-config-client/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /spring-cloud-config-client/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.0/apache-maven-3.6.0-bin.zip 2 | -------------------------------------------------------------------------------- /spring-cloud-config-client/mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM https://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Maven2 Start Up Batch script 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM M2_HOME - location of maven2's installed home dir 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | @REM e.g. to debug Maven itself, use 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | @REM ---------------------------------------------------------------------------- 35 | 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 37 | @echo off 38 | @REM set title of command window 39 | title %0 40 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' 41 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 42 | 43 | @REM set %HOME% to equivalent of $HOME 44 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 45 | 46 | @REM Execute a user defined script before this one 47 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 48 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 49 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" 50 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" 51 | :skipRcPre 52 | 53 | @setlocal 54 | 55 | set ERROR_CODE=0 56 | 57 | @REM To isolate internal variables from possible post scripts, we use another setlocal 58 | @setlocal 59 | 60 | @REM ==== START VALIDATION ==== 61 | if not "%JAVA_HOME%" == "" goto OkJHome 62 | 63 | echo. 64 | echo Error: JAVA_HOME not found in your environment. >&2 65 | echo Please set the JAVA_HOME variable in your environment to match the >&2 66 | echo location of your Java installation. >&2 67 | echo. 68 | goto error 69 | 70 | :OkJHome 71 | if exist "%JAVA_HOME%\bin\java.exe" goto init 72 | 73 | echo. 74 | echo Error: JAVA_HOME is set to an invalid directory. >&2 75 | echo JAVA_HOME = "%JAVA_HOME%" >&2 76 | echo Please set the JAVA_HOME variable in your environment to match the >&2 77 | echo location of your Java installation. >&2 78 | echo. 79 | goto error 80 | 81 | @REM ==== END VALIDATION ==== 82 | 83 | :init 84 | 85 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 86 | @REM Fallback to current working directory if not found. 87 | 88 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 89 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 90 | 91 | set EXEC_DIR=%CD% 92 | set WDIR=%EXEC_DIR% 93 | :findBaseDir 94 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 95 | cd .. 96 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 97 | set WDIR=%CD% 98 | goto findBaseDir 99 | 100 | :baseDirFound 101 | set MAVEN_PROJECTBASEDIR=%WDIR% 102 | cd "%EXEC_DIR%" 103 | goto endDetectBaseDir 104 | 105 | :baseDirNotFound 106 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 107 | cd "%EXEC_DIR%" 108 | 109 | :endDetectBaseDir 110 | 111 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 112 | 113 | @setlocal EnableExtensions EnableDelayedExpansion 114 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 115 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 116 | 117 | :endReadAdditionalConfig 118 | 119 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 120 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" 121 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 122 | 123 | set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar" 124 | FOR /F "tokens=1,2 delims==" %%A IN (%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties) DO ( 125 | IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B 126 | ) 127 | 128 | @REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 129 | @REM This allows using the maven wrapper in projects that prohibit checking in binary data. 130 | if exist %WRAPPER_JAR% ( 131 | echo Found %WRAPPER_JAR% 132 | ) else ( 133 | echo Couldn't find %WRAPPER_JAR%, downloading it ... 134 | echo Downloading from: %DOWNLOAD_URL% 135 | powershell -Command "(New-Object Net.WebClient).DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')" 136 | echo Finished downloading %WRAPPER_JAR% 137 | ) 138 | @REM End of extension 139 | 140 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 141 | if ERRORLEVEL 1 goto error 142 | goto end 143 | 144 | :error 145 | set ERROR_CODE=1 146 | 147 | :end 148 | @endlocal & set ERROR_CODE=%ERROR_CODE% 149 | 150 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost 151 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 152 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" 153 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" 154 | :skipRcPost 155 | 156 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 157 | if "%MAVEN_BATCH_PAUSE%" == "on" pause 158 | 159 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% 160 | 161 | exit /B %ERROR_CODE% 162 | -------------------------------------------------------------------------------- /spring-cloud-config-client/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.1.8.RELEASE 9 | 10 | 11 | com.bluersw 12 | spring-cloud-config-client 13 | 0.0.1-SNAPSHOT 14 | spring-cloud-config-client 15 | Demo project for Spring Cloud Config Client 16 | 17 | 18 | 1.8 19 | Greenwich.SR3 20 | 21 | 22 | 23 | 24 | org.springframework.boot 25 | spring-boot-starter-web 26 | 27 | 28 | 29 | org.springframework.boot 30 | spring-boot-starter-actuator 31 | 32 | 33 | org.springframework.cloud 34 | spring-cloud-starter-config 35 | 36 | 37 | org.springframework.cloud 38 | spring-cloud-starter-consul-discovery 39 | 40 | 41 | org.springframework.cloud 42 | spring-cloud-starter-bus-amqp 43 | 44 | 45 | org.springframework.boot 46 | spring-boot-starter-test 47 | test 48 | 49 | 50 | 51 | 52 | 53 | 54 | org.springframework.cloud 55 | spring-cloud-dependencies 56 | ${spring-cloud.version} 57 | pom 58 | import 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | org.springframework.boot 67 | spring-boot-maven-plugin 68 | 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /spring-cloud-config-client/src/main/java/com/bluersw/config/client/SpringCloudConfigClientApplication.java: -------------------------------------------------------------------------------- 1 | package com.bluersw.config.client; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class SpringCloudConfigClientApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(SpringCloudConfigClientApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /spring-cloud-config-client/src/main/java/com/bluersw/config/client/controller/ConfigTestController.java: -------------------------------------------------------------------------------- 1 | package com.bluersw.config.client.controller; 2 | 3 | import org.springframework.beans.factory.annotation.Value; 4 | import org.springframework.cloud.context.config.annotation.RefreshScope; 5 | import org.springframework.web.bind.annotation.RequestMapping; 6 | import org.springframework.web.bind.annotation.RestController; 7 | 8 | @RestController 9 | //刷新触发地址/actuator/refresh 10 | @RefreshScope 11 | public class ConfigTestController { 12 | 13 | //配置信息通过@Value注解读取,配置项用${配置项}读取 14 | @Value("${bluersw.config}") 15 | private String configBluersw; 16 | 17 | @RequestMapping("/ConfigTest") 18 | public String ConfigTest(){ 19 | return this.configBluersw; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /spring-cloud-config-client/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.application.name=spring-cloud-config-client 2 | server.port=9006 3 | spring.cloud.consul.host=127.0.0.1 4 | spring.cloud.consul.port=8500 5 | #设置不需要注册到 consul 中 6 | spring.cloud.consul.discovery.register=false 7 | 8 | # 开启消息跟踪 9 | spring.cloud.bus.trace.enabled=true 10 | spring.rabbitmq.host=127.0.0.1 11 | spring.rabbitmq.port=5672 12 | spring.rabbitmq.username=guest 13 | spring.rabbitmq.password=guest 14 | 15 | #显示的暴露接入点 16 | management.endpoints.web.exposure.include=* -------------------------------------------------------------------------------- /spring-cloud-config-client/src/main/resources/bootstrap.properties: -------------------------------------------------------------------------------- 1 | #配置文件名称中定义的配置项目名称 2 | spring.cloud.config.name=ConfigDepot 3 | #配置文件名称中定义的环境名称 4 | spring.cloud.config.profile=Test 5 | spring.cloud.config.label=master 6 | #开启配置中心的服务发现 7 | spring.cloud.config.discovery.enabled=true 8 | #配置中心注册在服务中心的名字 9 | spring.cloud.config.discovery.serviceId=spring-cloud-config 10 | spring.cloud.config.fail-fast=true -------------------------------------------------------------------------------- /spring-cloud-config-client/src/test/java/com/bluersw/config/client/SpringCloudConfigClientApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.bluersw.config.client; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class SpringCloudConfigClientApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /spring-cloud-config-server/.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | !.mvn/wrapper/maven-wrapper.jar 3 | !**/src/main/** 4 | !**/src/test/** 5 | 6 | ### STS ### 7 | .apt_generated 8 | .classpath 9 | .factorypath 10 | .project 11 | .settings 12 | .springBeans 13 | .sts4-cache 14 | 15 | ### IntelliJ IDEA ### 16 | .idea 17 | *.iws 18 | *.iml 19 | *.ipr 20 | 21 | ### NetBeans ### 22 | /nbproject/private/ 23 | /nbbuild/ 24 | /dist/ 25 | /nbdist/ 26 | /.nb-gradle/ 27 | build/ 28 | 29 | ### VS Code ### 30 | .vscode/ 31 | -------------------------------------------------------------------------------- /spring-cloud-config-server/.mvn/wrapper/MavenWrapperDownloader.java: -------------------------------------------------------------------------------- 1 | /* 2 | Licensed to the Apache Software Foundation (ASF) under one 3 | or more contributor license agreements. See the NOTICE file 4 | distributed with this work for additional information 5 | regarding copyright ownership. The ASF licenses this file 6 | to you under the Apache License, Version 2.0 (the 7 | "License"); you may not use this file except in compliance 8 | with the License. You may obtain a copy of the License at 9 | 10 | https://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, 13 | software distributed under the License is distributed on an 14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | KIND, either express or implied. See the License for the 16 | specific language governing permissions and limitations 17 | under the License. 18 | */ 19 | 20 | import java.io.File; 21 | import java.io.FileInputStream; 22 | import java.io.FileOutputStream; 23 | import java.io.IOException; 24 | import java.net.URL; 25 | import java.nio.channels.Channels; 26 | import java.nio.channels.ReadableByteChannel; 27 | import java.util.Properties; 28 | 29 | public class MavenWrapperDownloader { 30 | 31 | /** 32 | * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. 33 | */ 34 | private static final String DEFAULT_DOWNLOAD_URL = 35 | "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar"; 36 | 37 | /** 38 | * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to 39 | * use instead of the default one. 40 | */ 41 | private static final String MAVEN_WRAPPER_PROPERTIES_PATH = 42 | ".mvn/wrapper/maven-wrapper.properties"; 43 | 44 | /** 45 | * Path where the maven-wrapper.jar will be saved to. 46 | */ 47 | private static final String MAVEN_WRAPPER_JAR_PATH = 48 | ".mvn/wrapper/maven-wrapper.jar"; 49 | 50 | /** 51 | * Name of the property which should be used to override the default download url for the wrapper. 52 | */ 53 | private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; 54 | 55 | public static void main(String args[]) { 56 | System.out.println("- Downloader started"); 57 | File baseDirectory = new File(args[0]); 58 | System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); 59 | 60 | // If the maven-wrapper.properties exists, read it and check if it contains a custom 61 | // wrapperUrl parameter. 62 | File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); 63 | String url = DEFAULT_DOWNLOAD_URL; 64 | if(mavenWrapperPropertyFile.exists()) { 65 | FileInputStream mavenWrapperPropertyFileInputStream = null; 66 | try { 67 | mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); 68 | Properties mavenWrapperProperties = new Properties(); 69 | mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); 70 | url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); 71 | } catch (IOException e) { 72 | System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); 73 | } finally { 74 | try { 75 | if(mavenWrapperPropertyFileInputStream != null) { 76 | mavenWrapperPropertyFileInputStream.close(); 77 | } 78 | } catch (IOException e) { 79 | // Ignore ... 80 | } 81 | } 82 | } 83 | System.out.println("- Downloading from: : " + url); 84 | 85 | File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); 86 | if(!outputFile.getParentFile().exists()) { 87 | if(!outputFile.getParentFile().mkdirs()) { 88 | System.out.println( 89 | "- ERROR creating output direcrory '" + outputFile.getParentFile().getAbsolutePath() + "'"); 90 | } 91 | } 92 | System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); 93 | try { 94 | downloadFileFromURL(url, outputFile); 95 | System.out.println("Done"); 96 | System.exit(0); 97 | } catch (Throwable e) { 98 | System.out.println("- Error downloading"); 99 | e.printStackTrace(); 100 | System.exit(1); 101 | } 102 | } 103 | 104 | private static void downloadFileFromURL(String urlString, File destination) throws Exception { 105 | URL website = new URL(urlString); 106 | ReadableByteChannel rbc; 107 | rbc = Channels.newChannel(website.openStream()); 108 | FileOutputStream fos = new FileOutputStream(destination); 109 | fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); 110 | fos.close(); 111 | rbc.close(); 112 | } 113 | 114 | } 115 | -------------------------------------------------------------------------------- /spring-cloud-config-server/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunweisheng/spring-cloud-example/29ede89ea30037025ce3644380edbe9b5738f696/spring-cloud-config-server/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /spring-cloud-config-server/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.0/apache-maven-3.6.0-bin.zip 2 | -------------------------------------------------------------------------------- /spring-cloud-config-server/ConfigClient.md: -------------------------------------------------------------------------------- 1 | # 创建客户端项目并读取服务化的配置中心 2 | 3 | ## 将配置中心注册到服务中心(Consul) 4 | 5 | POM文件添加依赖: 6 | 7 | ```xml 8 | 9 | org.springframework.boot 10 | spring-boot-starter-actuator 11 | 12 | 13 | org.springframework.cloud 14 | spring-cloud-starter-consul-discovery 15 | 2.1.3.RELEASE 16 | 17 | ``` 18 | 19 | 配置文件添加内容: 20 | 21 | ```text 22 | spring.cloud.consul.host=127.0.0.1 23 | spring.cloud.consul.port=8500 24 | #注册到consul的服务名称 25 | spring.cloud.consul.discovery.serviceName=spring-cloud-config 26 | ``` 27 | 28 | 启动Consul服务发现: 29 | 30 | ```java 31 | @SpringBootApplication 32 | //启动配置中心 33 | @EnableConfigServer 34 | //启动服务发现 35 | @EnableDiscoveryClient 36 | public class SpringCloudConfigServerApplication { 37 | 38 | public static void main(String[] args) { 39 | SpringApplication.run(SpringCloudConfigServerApplication.class, args); 40 | } 41 | 42 | } 43 | ``` 44 | 45 | 启动配置中心服务端,并查看Consul后台: 46 | ![Alt text](http://static.bluersw.com/images/spring-cloud-config-client/spring-cloud-config-client-01.png) 47 | 48 | ## 注册部署两个配置中心 49 | 50 | 利用命令后和配置文件参数启动两个配置中心并注册同一个服务名称形成高可用,在spring-cloud-config-server项目根目录下执行: 51 | 52 | ```shell 53 | mvn install 54 | ``` 55 | 56 | 将spring-cloud-config-server项目内application.properties文件拷贝到/spring-cloud-config-server/target/目录下两份,并重命名为application-1.properties和application-2.properties,然后修改配置文件内的端口号和应用名称: 57 | 58 | ```text 59 | 60 | server.port=9004 61 | spring.application.name=spring-cloud-config-server-01 62 | 63 | ``` 64 | 65 | ```text 66 | server.port=9005 67 | spring.application.name=spring-cloud-config-server-02 68 | 69 | ``` 70 | 71 | 在/target/目录下执行以下命令启动两个配置中心: 72 | 73 | ```shell 74 | java -jar spring-cloud-config-server-0.0.1-SNAPSHOT.jar --spring.config.location=application-1.properties 75 | ``` 76 | 77 | ```shell 78 | java -jar spring-cloud-config-server-0.0.1-SNAPSHOT.jar --spring.config.location=application-2.properties 79 | ``` 80 | 81 | 启动配置中心服务端,并查看Consul后台: 82 | ![Alt text](http://static.bluersw.com/images/spring-cloud-config-client/spring-cloud-config-client-02.png) 83 | 84 | ## 创建读取配置中心的客户端项目 85 | 86 | ![Alt text](http://static.bluersw.com/images/spring-cloud-config-client/spring-cloud-config-client-03.png) 87 | ![Alt text](http://static.bluersw.com/images/spring-cloud-config-client/spring-cloud-config-client-04.png) 88 | ![Alt text](http://static.bluersw.com/images/spring-cloud-config-client/spring-cloud-config-client-05.png) 89 | ![Alt text](http://static.bluersw.com/images/spring-cloud-config-client/spring-cloud-config-client-06.png) 90 | 91 | 修改配置文件application.properties: 92 | 93 | ```text 94 | spring.application.name=spring-cloud-config-client 95 | server.port=9006 96 | spring.cloud.consul.host=127.0.0.1 97 | spring.cloud.consul.port=8500 98 | #设置不需要注册到 consul 中 99 | spring.cloud.consul.discovery.register=false 100 | 101 | ``` 102 | 103 | 新建配置文件bootstrap.properties: 104 | 105 | ```text 106 | #配置文件名称中定义的配置项目名称 107 | spring.cloud.config.name=ConfigDepot 108 | #配置文件名称中定义的环境名称 109 | spring.cloud.config.profile=Test 110 | spring.cloud.config.label=master 111 | #开启配置中心的服务发现 112 | spring.cloud.config.discovery.enabled=true 113 | #配置中心注册在服务中心的名字 114 | spring.cloud.config.discovery.serviceId=spring-cloud-config 115 | ``` 116 | 117 | 配置中心的内容要求先于application.properties被加载,所以关于配置中心的配置信息要写在bootstrap.properties配置文件中,因为bootstrap.properties配置文件会先于application.properties被加载。 118 | 119 | 添加读取配置的接口类: 120 | 121 | ```java 122 | @RestController 123 | public class ConfigTestController { 124 | 125 | //配置信息通过@Value注解读取,配置项用${配置项}读取 126 | @Value("${bluersw.config}") 127 | private String configBluersw; 128 | 129 | @RequestMapping("/ConfigTest") 130 | public String ConfigTest(){ 131 | return this.configBluersw; 132 | } 133 | } 134 | ``` 135 | 136 | ## 启动客户端测试 137 | 138 | 访问127.0.0.1:9006/ConfigTest,得到配置的信息Test-3(我中间改了几次): 139 | ![Alt text](http://static.bluersw.com/images/spring-cloud-config-client/spring-cloud-config-client-07.png) 140 | 141 | 此时修改Git仓库中配置的内容,再刷新页面,页面的内容是不会改变的,因为配置内容是在程序启动的时候加载,配置中心内容改变是不会自动反映到客户端程序中,但可以通过调用客户端的刷新接口实现重新加载配置内容,这个内容我们放在总线部分演示。 142 | -------------------------------------------------------------------------------- /spring-cloud-config-server/ConfigServer.md: -------------------------------------------------------------------------------- 1 | # 创建配置中心服务端 2 | 3 | ![Alt text](http://static.bluersw.com/images/spring-cloud-config-server/spring-cloud-config-server-01.png) 4 | ![Alt text](http://static.bluersw.com/images/spring-cloud-config-server/spring-cloud-config-server-02.png) 5 | ![Alt text](http://static.bluersw.com/images/spring-cloud-config-server/spring-cloud-config-server-03.png) 6 | ![Alt text](http://static.bluersw.com/images/spring-cloud-config-server/spring-cloud-config-server-04.png) 7 | 8 | ## 创建好项目后添加配置文件内容 9 | 10 | ```text 11 | server.port=9004 12 | spring.application.name=spring-cloud-config-server-01 13 | #git仓库地址 14 | spring.cloud.config.server.git.uri=http://git.home/test/config-depot.git 15 | #仓库内的相对路径 16 | spring.cloud.config.server.git.search-paths=/config 17 | #git用户名 18 | spring.cloud.config.server.git.username=sunweisheng 19 | #git密码 20 | spring.cloud.config.server.git.password=Passw0rd 21 | ``` 22 | 23 | ## 添加开启配置中心的注解(SpringCloudConfigServerApplication.java) 24 | 25 | ```java 26 | @SpringBootApplication 27 | //启动配置中心 28 | @EnableConfigServer 29 | public class SpringCloudConfigServerApplication { 30 | 31 | public static void main(String[] args) { 32 | SpringApplication.run(SpringCloudConfigServerApplication.class, args); 33 | } 34 | 35 | } 36 | ``` 37 | 38 | ## 在git仓库里添加配置文件 39 | 40 | Git仓库名称:config-depot,仓库根目录下创建文件夹config,在config目录下创建配置文件ConfigDepot-Test.properties,配置文件内容:bluersw.config=Test-1 41 | ![Alt text](http://static.bluersw.com/images/spring-cloud-config-server/spring-cloud-config-server-05.png) 42 | ![Alt text](http://static.bluersw.com/images/spring-cloud-config-server/spring-cloud-config-server-06.png) 43 | 44 | ## 测试配置中心 45 | 46 | 在浏览器中访问127.0.0.1:9004/ConfigDepot/Test,返回Json格式的配置文件内容,证明配置中心读取Git仓库内容成功。 47 | ![Alt text](http://static.bluersw.com/images/spring-cloud-config-server/spring-cloud-config-server-07.png) 48 | 49 | ```json 50 | { 51 | "name":"ConfigDepot", 52 | "profiles":["Test"], 53 | "label":null, 54 | "version":"e3fdd0937bba0ad2df3eefe09ac3ab33ca09397b", 55 | "state":null, 56 | "propertySources":[{ 57 | "name":"http://git.home/test/config-depot.git/config/ConfigDepot-Test.properties", 58 | "source":{ 59 | "bluersw.config":"Test-1" 60 | } 61 | }] 62 | } 63 | ``` 64 | 65 | 仓库里的配置文件路径可以转化为REST接口在配置中心中访问,转化规则: 66 | 67 | * /{application}/{profile}[/{label}] 68 | * /{application}-{profile}.yml 69 | * /{label}/{application}-{profile}.yml 70 | * /{application}-{profile}.properties 71 | * /{label}/{application}-{profile}.properties 72 | 73 | PS:配置中心读取Git仓库信息没有缓存,如果配置文件的内容改为Test-3,直接刷新页面就可以看到刚改的值(Test-3)。 74 | -------------------------------------------------------------------------------- /spring-cloud-config-server/ManualRefresh.md: -------------------------------------------------------------------------------- 1 | # 手动刷新客户端配置内容 2 | 3 | ## 客户端项目增加依赖项 4 | 5 | ```xml 6 | 7 | org.springframework.boot 8 | spring-boot-starter-actuator 9 | 10 | ``` 11 | 12 | ## 客户端项目修改配置文件 13 | 14 | 增加management.endpoints.web.exposure.include=refresh,health,info 15 | 16 | ```text 17 | spring.application.name=spring-cloud-config-client 18 | server.port=9006 19 | spring.cloud.consul.host=127.0.0.1 20 | spring.cloud.consul.port=8500 21 | #设置不需要注册到 consul 中 22 | spring.cloud.consul.discovery.register=false 23 | #显示的暴露接入点 24 | management.endpoints.web.exposure.include=refresh,health,info 25 | ``` 26 | 27 | ## 客户端程序增加支持刷新注解 28 | 29 | 在使用配置中心的类上添加@RefreshScope注解: 30 | 31 | ```java 32 | @RestController 33 | //刷新触发地址/actuator/refresh 34 | @RefreshScope 35 | public class ConfigTestController { 36 | 37 | //配置信息通过@Value注解读取,配置项用${配置项}读取 38 | @Value("${bluersw.config}") 39 | private String configBluersw; 40 | 41 | @RequestMapping("/ConfigTest") 42 | public String ConfigTest(){ 43 | return this.configBluersw; 44 | } 45 | } 46 | ``` 47 | 48 | ## 测试刷新效果 49 | 50 | 将Git仓库里的配置内容改外Test-5(bluersw.config=Test-5),启动客户端程序(spring-cloud-config-client),刷新客户端页面127.0.0.1:9006/ConfigTest,发现显示内容还是Test-3,然后执行: 51 | 52 | ```shell 53 | curl -X POST http://127.0.0.1:9006/actuat/refresh 54 | ``` 55 | 56 | 再次刷新页面127.0.0.1:9006/ConfigTest,页面内容显示为Test-5,说明客户端程序内的配置信息读取了最新的值。 57 | -------------------------------------------------------------------------------- /spring-cloud-config-server/README.md: -------------------------------------------------------------------------------- 1 | # 目录 2 | 3 | * [创建配置中心服务端](ConfigServer.md) 4 | * [创建客户端项目并读取服务化的配置中心](ConfigClient.md) 5 | * [手动刷新客户端配置内容](ManualRefresh.md) 6 | * [通过总线机制实现自动刷新客户端配置](AutoRefresh.md) 7 | -------------------------------------------------------------------------------- /spring-cloud-config-server/mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM https://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Maven2 Start Up Batch script 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM M2_HOME - location of maven2's installed home dir 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | @REM e.g. to debug Maven itself, use 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | @REM ---------------------------------------------------------------------------- 35 | 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 37 | @echo off 38 | @REM set title of command window 39 | title %0 40 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' 41 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 42 | 43 | @REM set %HOME% to equivalent of $HOME 44 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 45 | 46 | @REM Execute a user defined script before this one 47 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 48 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 49 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" 50 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" 51 | :skipRcPre 52 | 53 | @setlocal 54 | 55 | set ERROR_CODE=0 56 | 57 | @REM To isolate internal variables from possible post scripts, we use another setlocal 58 | @setlocal 59 | 60 | @REM ==== START VALIDATION ==== 61 | if not "%JAVA_HOME%" == "" goto OkJHome 62 | 63 | echo. 64 | echo Error: JAVA_HOME not found in your environment. >&2 65 | echo Please set the JAVA_HOME variable in your environment to match the >&2 66 | echo location of your Java installation. >&2 67 | echo. 68 | goto error 69 | 70 | :OkJHome 71 | if exist "%JAVA_HOME%\bin\java.exe" goto init 72 | 73 | echo. 74 | echo Error: JAVA_HOME is set to an invalid directory. >&2 75 | echo JAVA_HOME = "%JAVA_HOME%" >&2 76 | echo Please set the JAVA_HOME variable in your environment to match the >&2 77 | echo location of your Java installation. >&2 78 | echo. 79 | goto error 80 | 81 | @REM ==== END VALIDATION ==== 82 | 83 | :init 84 | 85 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 86 | @REM Fallback to current working directory if not found. 87 | 88 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 89 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 90 | 91 | set EXEC_DIR=%CD% 92 | set WDIR=%EXEC_DIR% 93 | :findBaseDir 94 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 95 | cd .. 96 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 97 | set WDIR=%CD% 98 | goto findBaseDir 99 | 100 | :baseDirFound 101 | set MAVEN_PROJECTBASEDIR=%WDIR% 102 | cd "%EXEC_DIR%" 103 | goto endDetectBaseDir 104 | 105 | :baseDirNotFound 106 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 107 | cd "%EXEC_DIR%" 108 | 109 | :endDetectBaseDir 110 | 111 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 112 | 113 | @setlocal EnableExtensions EnableDelayedExpansion 114 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 115 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 116 | 117 | :endReadAdditionalConfig 118 | 119 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 120 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" 121 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 122 | 123 | set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar" 124 | FOR /F "tokens=1,2 delims==" %%A IN (%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties) DO ( 125 | IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B 126 | ) 127 | 128 | @REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 129 | @REM This allows using the maven wrapper in projects that prohibit checking in binary data. 130 | if exist %WRAPPER_JAR% ( 131 | echo Found %WRAPPER_JAR% 132 | ) else ( 133 | echo Couldn't find %WRAPPER_JAR%, downloading it ... 134 | echo Downloading from: %DOWNLOAD_URL% 135 | powershell -Command "(New-Object Net.WebClient).DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')" 136 | echo Finished downloading %WRAPPER_JAR% 137 | ) 138 | @REM End of extension 139 | 140 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 141 | if ERRORLEVEL 1 goto error 142 | goto end 143 | 144 | :error 145 | set ERROR_CODE=1 146 | 147 | :end 148 | @endlocal & set ERROR_CODE=%ERROR_CODE% 149 | 150 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost 151 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 152 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" 153 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" 154 | :skipRcPost 155 | 156 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 157 | if "%MAVEN_BATCH_PAUSE%" == "on" pause 158 | 159 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% 160 | 161 | exit /B %ERROR_CODE% 162 | -------------------------------------------------------------------------------- /spring-cloud-config-server/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.1.8.RELEASE 9 | 10 | 11 | com.bluersw 12 | spring-cloud-config-server 13 | 0.0.1-SNAPSHOT 14 | spring-cloud-config-server 15 | Demo project for Spring Cloud Config Server 16 | 17 | 18 | 1.8 19 | Greenwich.SR3 20 | 21 | 22 | 23 | 24 | org.springframework.cloud 25 | spring-cloud-config-server 26 | 27 | 28 | 29 | org.springframework.boot 30 | spring-boot-starter-actuator 31 | 32 | 33 | org.springframework.cloud 34 | spring-cloud-starter-consul-discovery 35 | 36 | 37 | org.springframework.cloud 38 | spring-cloud-starter-bus-amqp 39 | 40 | 41 | org.springframework.boot 42 | spring-boot-starter-test 43 | test 44 | 45 | 46 | 47 | 48 | 49 | 50 | org.springframework.cloud 51 | spring-cloud-dependencies 52 | ${spring-cloud.version} 53 | pom 54 | import 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | org.springframework.boot 63 | spring-boot-maven-plugin 64 | 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /spring-cloud-config-server/src/main/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunweisheng/spring-cloud-example/29ede89ea30037025ce3644380edbe9b5738f696/spring-cloud-config-server/src/main/.DS_Store -------------------------------------------------------------------------------- /spring-cloud-config-server/src/main/java/com/bluersw/config/server/BusRefreshFilter.java: -------------------------------------------------------------------------------- 1 | package com.bluersw.config.server; 2 | 3 | import org.springframework.core.annotation.Order; 4 | 5 | import javax.servlet.*; 6 | import javax.servlet.annotation.WebFilter; 7 | import javax.servlet.http.HttpServletRequest; 8 | import java.io.IOException; 9 | 10 | @WebFilter(filterName = "bodyFilter", urlPatterns = "/*") 11 | @Order(1) 12 | //Git在进行webhood post请求的同时默认会在body加上这么一串载荷(payload),Spring Boot 无法并行化。 13 | public class BusRefreshFilter implements Filter { 14 | 15 | @Override 16 | public void init(FilterConfig filterConfig) throws ServletException { 17 | 18 | } 19 | 20 | @Override 21 | public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { 22 | HttpServletRequest httpServletRequest = (HttpServletRequest)servletRequest; 23 | 24 | String url = new String(httpServletRequest.getRequestURI()); 25 | 26 | //只过滤/actuator/bus-refresh请求 27 | if (!url.endsWith("/bus-refresh")) { 28 | filterChain.doFilter(servletRequest, servletResponse); 29 | return; 30 | } 31 | 32 | //使用HttpServletRequest包装原始请求达到修改post请求中body内容的目的 33 | EmptyRequestWrapper requestWrapper = new EmptyRequestWrapper(httpServletRequest); 34 | 35 | filterChain.doFilter(requestWrapper, servletResponse); 36 | } 37 | 38 | @Override 39 | public void destroy() { 40 | 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /spring-cloud-config-server/src/main/java/com/bluersw/config/server/EmptyRequestWrapper.java: -------------------------------------------------------------------------------- 1 | package com.bluersw.config.server; 2 | 3 | import javax.servlet.ReadListener; 4 | import javax.servlet.ServletInputStream; 5 | import javax.servlet.http.HttpServletRequest; 6 | import javax.servlet.http.HttpServletRequestWrapper; 7 | import java.io.ByteArrayInputStream; 8 | import java.io.IOException; 9 | 10 | //清空请求中的Body 11 | public class EmptyRequestWrapper extends HttpServletRequestWrapper{ 12 | 13 | public EmptyRequestWrapper(HttpServletRequest request) { 14 | super(request); 15 | } 16 | 17 | @Override 18 | public ServletInputStream getInputStream() throws IOException { 19 | byte[] bytes = new byte[0]; 20 | ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes); 21 | 22 | return new ServletInputStream() { 23 | @Override 24 | public boolean isFinished() { 25 | return byteArrayInputStream.read() == -1 ? true:false; 26 | } 27 | 28 | @Override 29 | public boolean isReady() { 30 | return false; 31 | } 32 | 33 | @Override 34 | public void setReadListener(ReadListener readListener) { 35 | 36 | } 37 | 38 | @Override 39 | public int read() throws IOException { 40 | return byteArrayInputStream.read(); 41 | } 42 | }; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /spring-cloud-config-server/src/main/java/com/bluersw/config/server/SpringCloudConfigServerApplication.java: -------------------------------------------------------------------------------- 1 | package com.bluersw.config.server; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.boot.web.servlet.ServletComponentScan; 6 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 7 | import org.springframework.cloud.config.server.EnableConfigServer; 8 | 9 | @SpringBootApplication 10 | //启动配置中心 11 | @EnableConfigServer 12 | //启动服务发现 13 | @EnableDiscoveryClient 14 | @ServletComponentScan 15 | public class SpringCloudConfigServerApplication { 16 | 17 | public static void main(String[] args) { 18 | SpringApplication.run(SpringCloudConfigServerApplication.class, args); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /spring-cloud-config-server/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | server.port=9004 2 | spring.application.name=spring-cloud-config-server-01 3 | #git仓库地址 4 | spring.cloud.config.server.git.uri=http://git.home/test/config-depot.git 5 | #仓库内的相对路径 6 | spring.cloud.config.server.git.search-paths=/config 7 | #git用户名 8 | spring.cloud.config.server.git.username=sunweisheng 9 | #git密码 10 | spring.cloud.config.server.git.password=Passw0rd 11 | 12 | spring.cloud.consul.host=127.0.0.1 13 | spring.cloud.consul.port=8500 14 | #注册到consul的服务名称 15 | spring.cloud.consul.discovery.serviceName=spring-cloud-config 16 | 17 | # 开启消息跟踪 18 | spring.cloud.bus.trace.enabled=true 19 | spring.rabbitmq.host=127.0.0.1 20 | spring.rabbitmq.port=5672 21 | spring.rabbitmq.username=guest 22 | spring.rabbitmq.password=guest 23 | 24 | #显示的暴露接入点 25 | management.endpoints.web.exposure.include=* -------------------------------------------------------------------------------- /spring-cloud-config-server/src/test/java/com/bluersw/config/server/SpringCloudConfigServerApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.bluersw.config.server; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class SpringCloudConfigServerApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /spring-cloud-consul-client/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/** 5 | !**/src/test/** 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | 30 | ### VS Code ### 31 | .vscode/ 32 | -------------------------------------------------------------------------------- /spring-cloud-consul-client/.mvn/wrapper/MavenWrapperDownloader.java: -------------------------------------------------------------------------------- 1 | /* 2 | Licensed to the Apache Software Foundation (ASF) under one 3 | or more contributor license agreements. See the NOTICE file 4 | distributed with this work for additional information 5 | regarding copyright ownership. The ASF licenses this file 6 | to you under the Apache License, Version 2.0 (the 7 | "License"); you may not use this file except in compliance 8 | with the License. You may obtain a copy of the License at 9 | 10 | https://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, 13 | software distributed under the License is distributed on an 14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | KIND, either express or implied. See the License for the 16 | specific language governing permissions and limitations 17 | under the License. 18 | */ 19 | 20 | import java.io.File; 21 | import java.io.FileInputStream; 22 | import java.io.FileOutputStream; 23 | import java.io.IOException; 24 | import java.net.URL; 25 | import java.nio.channels.Channels; 26 | import java.nio.channels.ReadableByteChannel; 27 | import java.util.Properties; 28 | 29 | public class MavenWrapperDownloader { 30 | 31 | /** 32 | * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. 33 | */ 34 | private static final String DEFAULT_DOWNLOAD_URL = 35 | "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar"; 36 | 37 | /** 38 | * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to 39 | * use instead of the default one. 40 | */ 41 | private static final String MAVEN_WRAPPER_PROPERTIES_PATH = 42 | ".mvn/wrapper/maven-wrapper.properties"; 43 | 44 | /** 45 | * Path where the maven-wrapper.jar will be saved to. 46 | */ 47 | private static final String MAVEN_WRAPPER_JAR_PATH = 48 | ".mvn/wrapper/maven-wrapper.jar"; 49 | 50 | /** 51 | * Name of the property which should be used to override the default download url for the wrapper. 52 | */ 53 | private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; 54 | 55 | public static void main(String args[]) { 56 | System.out.println("- Downloader started"); 57 | File baseDirectory = new File(args[0]); 58 | System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); 59 | 60 | // If the maven-wrapper.properties exists, read it and check if it contains a custom 61 | // wrapperUrl parameter. 62 | File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); 63 | String url = DEFAULT_DOWNLOAD_URL; 64 | if(mavenWrapperPropertyFile.exists()) { 65 | FileInputStream mavenWrapperPropertyFileInputStream = null; 66 | try { 67 | mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); 68 | Properties mavenWrapperProperties = new Properties(); 69 | mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); 70 | url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); 71 | } catch (IOException e) { 72 | System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); 73 | } finally { 74 | try { 75 | if(mavenWrapperPropertyFileInputStream != null) { 76 | mavenWrapperPropertyFileInputStream.close(); 77 | } 78 | } catch (IOException e) { 79 | // Ignore ... 80 | } 81 | } 82 | } 83 | System.out.println("- Downloading from: : " + url); 84 | 85 | File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); 86 | if(!outputFile.getParentFile().exists()) { 87 | if(!outputFile.getParentFile().mkdirs()) { 88 | System.out.println( 89 | "- ERROR creating output direcrory '" + outputFile.getParentFile().getAbsolutePath() + "'"); 90 | } 91 | } 92 | System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); 93 | try { 94 | downloadFileFromURL(url, outputFile); 95 | System.out.println("Done"); 96 | System.exit(0); 97 | } catch (Throwable e) { 98 | System.out.println("- Error downloading"); 99 | e.printStackTrace(); 100 | System.exit(1); 101 | } 102 | } 103 | 104 | private static void downloadFileFromURL(String urlString, File destination) throws Exception { 105 | URL website = new URL(urlString); 106 | ReadableByteChannel rbc; 107 | rbc = Channels.newChannel(website.openStream()); 108 | FileOutputStream fos = new FileOutputStream(destination); 109 | fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); 110 | fos.close(); 111 | rbc.close(); 112 | } 113 | 114 | } 115 | -------------------------------------------------------------------------------- /spring-cloud-consul-client/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunweisheng/spring-cloud-example/29ede89ea30037025ce3644380edbe9b5738f696/spring-cloud-consul-client/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /spring-cloud-consul-client/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.0/apache-maven-3.6.0-bin.zip 2 | -------------------------------------------------------------------------------- /spring-cloud-consul-client/ConsulClusterServerClientMode.md: -------------------------------------------------------------------------------- 1 | # Consul集群Server+Client模式 2 | 3 | ## 架构示意图 4 | 5 | ![Alt text](http://static.bluersw.com/images/spring-cloud-consul-client-25.png) 6 | 7 | 只使用Consul的Server模式有以下2个问题: 8 | 9 | * 因为Consul Server数量受到控制所以压力承载(扩展性)是个问题。 10 | * Server很少导致一个Server下会注册很多微服务,当Server挂掉,这个Server节点下注册的微服务都会视为无效。 11 | 12 | 基于上述问题我们在架构中加入Consul Client模式,Client因为加入了LAN gossip协议组成网络中(高速局域网),可以识别故障的Server节点并找到可用的Server节点继续工作,其实Server模式负责的是用WAN gossip协议组成的网络进行跨广域网的数据同步(多个数据中心),这点Client模式是做不到的,Client模式也提供服务的注册和查询,但Client模式不存储节点数据,Client将请求转发给Server进行处理,节点注册数据在Server端是持久化保存的,Client的数量可以无限多,Server的数量是受控制的。总之:Client模式+LAN gossip协议组成了一个数据中心中的各个节点,Server负责投票选出Leader进行数据中心内的数据同步,这个Leader还负责利用WAN gossip协议跨广域网的与其他数据中心进行数据同步。 13 | PS:在Client注册的服务心跳监控检查由Client负责。 14 | 15 | ## 搭建环境 16 | 17 | 获得Docker镜像(bluersw/spring-cloud-consul-consumer 是服务消费者镜像里面运行的程序项目叫spring-cloud-consul-client,因为名字的起的不讲究导致了混乱,spring-cloud-consul-client不是Consul Client。): 18 | 19 | ```shell 20 | docker pull consul 21 | docker pull bluersw/spring-cloud-consul-consumer:cc 22 | docker pull bluersw/spring-cloud-provider:cc 23 | docker pull bluersw/spring-cloud-provider:cc 24 | docker pull bluersw/spring-cloud-provider-second:cc 25 | ``` 26 | 27 | 启动Consul Server(Windows版本的Docker运行命令时参数的IP地址要用"ip地址",比如:-client="0.0.0.0"): 28 | 29 | ```shell 30 | docker run -i -t -p 8500:8500 --name=ConsulServer-C consul agent -server -ui -node=Server-C -bootstrap-expect=3 -client=0.0.0.0 31 | 32 | docker run -i -t -p 8501:8500 --name=ConsulServer-A consul agent -server -ui -node=Server-A -bootstrap-expect=3 -client=0.0.0.0 -join=172.17.0.2 33 | 34 | docker run -i -t -p 8502:8500 --name=ConsulServer-B consul agent -server -ui -node=Server-B -bootstrap-expect=3 -client=0.0.0.0 -join=172.17.0.2 35 | ``` 36 | 37 | ![Alt text](http://static.bluersw.com/images/spring-cloud-consul-client-26.png) 38 | 39 | 启动spring-cloud-provider: 40 | 41 | ```shell 42 | docker run --name=spring-cloud-provider -d -p 9001:9001 bluersw/spring-cloud-provider:cc /opt/consul/./consul agent -data-dir=/opt/consul/data -config-dir=/opt/consul/config -node=privider-cc -join 172.17.0.3 43 | ``` 44 | 45 | 在启动此Docker的同时运行Consul Client模式,并加入Consul Server A(加入那个Consul Server都可以),TAG为CC的镜像文件里已经包含了Consul程序。 46 | ![Alt text](http://static.bluersw.com/images/spring-cloud-consul-client-27.png) 47 | 48 | spring-cloud-provider的配置文件内容: 49 | 50 | ```text 51 | spring.application.name=spring-cloud-provider-01 52 | server.port=9001 53 | spring.cloud.consul.host=127.0.0.1 54 | spring.cloud.consul.port=8500 55 | #注册到consul的服务名称 56 | spring.cloud.consul.discovery.serviceName=service-provider 57 | #以下两项如果不配置健康检查一定失败 58 | spring.cloud.consul.discovery.prefer-ip-address=true 59 | spring.cloud.consul.discovery.health-check-path=/actuator/health 60 | ``` 61 | 62 | 配置中的注册服务地址已经改成了127.0.0.1,其他服务项目的配置文件都改成了在本机的Consul Client中注册。 63 | 启动服务: 64 | 65 | ```shell 66 | docker exec spring-cloud-provider /usr/local/java/bin/java -jar /opt/spring-cloud-provider-0.0.1-SNAPSHOT.jar 67 | ``` 68 | 69 | service-provider服务在privider-cc节点被注册成功。 70 | ![Alt text](http://static.bluersw.com/images/spring-cloud-consul-client-28.png) 71 | ![Alt text](http://static.bluersw.com/images/spring-cloud-consul-client-29.png) 72 | 73 | 用同样的方法启动spring-cloud-provider-second和spring-cloud-consul-consumer。 74 | 75 | ```shell 76 | docker run --name=spring-cloud-provider-second -d -p 9002:9002 bluersw/spring-cloud-provider-second:cc /opt/consul/./consul agent -data-dir=/opt/consul/data -config-dir=/opt/consul/config -node=provider-second-cc -join 172.17.0.4 77 | 78 | docker exec spring-cloud-provider-second /usr/local/java/bin/java -jar /opt/spring-cloud-provider-second-0.0.1-SNAPSHOT.jar 79 | 80 | docker run --name=spring-cloud-consul-consumer -d -p 9003:9003 bluersw/spring-cloud-consul-consumer:cc /opt/consul/./consul agent -data-dir=/opt/consul/data -config-dir=/opt/consul/config -node=consumer-cc -join 172.17.0.2 81 | 82 | docker exec spring-cloud-consul-consumer /usr/local/java/bin/java -jar /opt/spring-cloud-consul-client-0.0.1-SNAPSHOT.jar 83 | 84 | ``` 85 | 86 | ![Alt text](http://static.bluersw.com/images/spring-cloud-consul-client-32.png) 87 | ![Alt text](http://static.bluersw.com/images/spring-cloud-consul-client-30.png) 88 | ![Alt text](http://static.bluersw.com/images/spring-cloud-consul-client-31.png) 89 | 90 | ## 模拟服务器故障 91 | 92 | 关闭Consul Server B: 93 | ![Alt text](http://static.bluersw.com/images/spring-cloud-consul-client-33.png) 94 | ![Alt text](http://static.bluersw.com/images/spring-cloud-consul-client-34.png) 95 | 96 | 因为service-provider在本机的Consul Client中注册,并Client可以利用LAN gossip协议找到可用的Server,所以关闭Consul Server B丝毫造成不了影响,如果Client或者服务本身挂掉了,那么Server端会将此节点或服务标记故障并不再使用,请求者就请求不到这个故障的节点了,同样的修复故障节点后所有服务和功能恢复如初。 97 | -------------------------------------------------------------------------------- /spring-cloud-consul-client/ConsulClusterServerMode.md: -------------------------------------------------------------------------------- 1 | # Consul集群Server模式 2 | 3 | ## 架构示意图 4 | 5 | Consul在生产环境下运行模式分为两种:Server模式和Client模式(dev模式属于开发模式不在这里讨论),我们先用Server模式搭建一个Consul集群,示意图如下: 6 | ![Alt text](http://static.bluersw.com/images/spring-cloud-consul-client-08.png) 7 | Consul Server A、B、C是启动的三个Consul服务运行于Server模式下,其中Consul Server C 是“总指挥”,他们的Leader,Consul Server A和B是Follower当“替补”,他们都可以提供注册和查询微服务器的功能。Leader负责给其他Follower同步数据和监控各个节点的健康,Leader是由他们仨根据Raft一致性算法选举出来的,Server模式运行的Consul服务不能太多,推荐3或5个,因为太多开会选举性能不佳,并且个数要求是奇数(选举算法要求)。 8 | spring-cloud-provider是模拟的服务提供者程序,spring-cloud-provider-second也是模式的服务提供者程序只是返回内容上不太一样(便于区分是哪个服务返回),他们都在Consul中注册同一个服务名称:service-provider,spring-cloud-consul-consumer是模拟服务消费者程序,负责使用service-provider服务。 9 | 10 | ## 搭建环境 11 | 12 | 为了测试方便我们使用docker进行部署,上述服务可以从以下地址下载: 13 | 14 | * [Mac安装Docker](https://docs.docker.com/docker-for-mac/) 15 | * [Docker Consul Image](https://learn.hashicorp.com/consul/day-0/containers-guide) 16 | * [其他Docker Image](https://hub.docker.com/u/bluersw) 17 | 18 | bluersw/spring-cloud-consul-consumer 是服务消费者镜像里面运行的程序项目叫spring-cloud-consul-client,因为名字的起的不讲究导致了混乱,spring-cloud-consul-client不是Consul Client。 19 | 20 | ```shell 21 | docker pull consul 22 | docker pull bluersw/spring-cloud-consul-consumer:v1 23 | docker pull bluersw/spring-cloud-provider:v1 24 | docker pull bluersw/spring-cloud-provider-second:v1 25 | ``` 26 | 27 | 启动Consul脚本(Windows版本的Docker运行命令时参数的IP地址要用"ip地址",比如:-client="0.0.0.0"): 28 | 29 | ```shell 30 | docker run -i -t -p 8500:8500 --name=ConsulServer-C consul agent -server -ui -node=Server-C -bootstrap-expect=3 -client=0.0.0.0 31 | 32 | docker run -i -t -p 8501:8500 --name=ConsulServer-A consul agent -server -ui -node=Server-A -bootstrap-expect=3 -client=0.0.0.0 -join=172.17.0.2 33 | 34 | docker run -i -t -p 8502:8500 --name=ConsulServer-B consul agent -server -ui -node=Server-B -bootstrap-expect=3 -client=0.0.0.0 -join=172.17.0.2 35 | ``` 36 | 37 | bootstrap-expect是指最少几个Server模式下的Consul服务,整个集群才启动。 38 | join=172.17.0.2这个地址就是Server-C的IP地址,Server-C是Leader。 39 | 启动后查看127.0.0.1:8500端口查看后台: 40 | ![Alt text](http://static.bluersw.com/images/spring-cloud-consul-client-09.png) 41 | ![Alt text](http://static.bluersw.com/images/spring-cloud-consul-client-10.png) 42 | 然后启动消费者和生产者docker: 43 | 44 | ```shell 45 | docker run -t -i --name=spring-cloud-provider -p 9001:9001 bluersw/spring-cloud-provider:v1 46 | source /etc/profile 47 | cd /opt 48 | java -jar spring-cloud-provider-0.0.1-SNAPSHOT.jar 49 | 50 | docker run -t -i --name=spring-cloud-provider-second -p 9002:9002 bluersw/spring-cloud-provider-second:v1 51 | source /etc/profile 52 | cd /opt 53 | java -jar spring-cloud-provider-second-0.0.1-SNAPSHOT.jar 54 | 55 | docker run -t -i --name=spring-cloud-consul-consumer -p 9003:9003 bluersw/spring-cloud-consul-consumer:v1 56 | source /etc/profile 57 | cd /opt 58 | java -jar spring-cloud-consul-client-0.0.1-SNAPSHOT.jar 59 | ``` 60 | 61 | 注册服务示例: 62 | 63 | ```text 64 | spring.application.name=spring-cloud-provider-01 65 | server.port=9001 66 | #172.17.0.3是Server-A 67 | spring.cloud.consul.host=172.17.0.3 68 | spring.cloud.consul.port=8500 69 | #注册到consul的服务名称 70 | spring.cloud.consul.discovery.serviceName=service-provider 71 | #以下两项如果不配置健康检查一定失败 72 | spring.cloud.consul.discovery.prefer-ip-address=true 73 | spring.cloud.consul.discovery.health-check-path=/actuator/health 74 | ``` 75 | 76 | ```text 77 | spring.application.name=spring-cloud-provider-02 78 | server.port=9002 79 | #172.17.0.4是Server-B 80 | spring.cloud.consul.host=172.17.0.4 81 | spring.cloud.consul.port=8500 82 | #注册到consul的服务名称 83 | spring.cloud.consul.discovery.serviceName=service-provider 84 | #以下两项如果不配置健康检查一定失败 85 | spring.cloud.consul.discovery.prefer-ip-address=true 86 | spring.cloud.consul.discovery.health-check-path=/actuator/health 87 | 88 | ``` 89 | 90 | 启动后Docker容器内容: 91 | ![Alt text](http://static.bluersw.com/images/spring-cloud-consul-client-11.png) 92 | service-provider服务已经注册完毕: 93 | ![Alt text](http://static.bluersw.com/images/spring-cloud-consul-client-17.png) 94 | 访问127.0.0.1:9003/TestHello 测试部署结果: 95 | ![Alt text](http://static.bluersw.com/images/spring-cloud-consul-client-12.png) 96 | 97 | ## 模拟服务器故障 98 | 99 | ### 关闭Consul Server B 100 | 101 | Consul Server B 已经不能访问: 102 | ![Alt text](http://static.bluersw.com/images/spring-cloud-consul-client-13.png) 103 | 从Leader上看Server-B节点已经故障: 104 | ![Alt text](http://static.bluersw.com/images/spring-cloud-consul-client-14.png) 105 | 从Leader上看服务service-provider的注册节点检查已经出现红叉: 106 | ![Alt text](http://static.bluersw.com/images/spring-cloud-consul-client-15.png) 107 | 因为Consul处理机制consul节点故障其中注册的服务都视为不可用,所以spring-cloud-provider-second服务虽然没有出问题,但已经不再被轮询到,两次访问都是访问的spring-cloud-provider服务。 108 | ![Alt text](http://static.bluersw.com/images/spring-cloud-consul-client-16.png) 109 | 110 | ### 恢复Consul Server B 111 | 112 | 重新启动Consul Server B后,一切自动恢复: 113 | ![Alt text](http://static.bluersw.com/images/spring-cloud-consul-client-18.png) 114 | ![Alt text](http://static.bluersw.com/images/spring-cloud-consul-client-19.png) 115 | 116 | ### 关闭Consul Server C 117 | 118 | 因为关闭Consul Server C是Leader,所以Consul Server C被关闭之后,Leader被Consul Server B接管: 119 | ![Alt text](http://static.bluersw.com/images/spring-cloud-consul-client-20.png) 120 | 此时如果spring-cloud-consul-consumer程序不重新启动,那么因为其保留着上次查询服务的缓存所以还可以继续显示正常: 121 | ![Alt text](http://static.bluersw.com/images/spring-cloud-consul-client-21.png) 122 | 如果重新启动因为找不到注册服务的Consul Server C会在访问时发生异常: 123 | ![Alt text](http://static.bluersw.com/images/spring-cloud-consul-client-22.png) 124 | 125 | ### 恢复Consul Server C 126 | 127 | Consul Server C之后,Leader仍然是Consul Server B 128 | ![Alt text](http://static.bluersw.com/images/spring-cloud-consul-client-23.png) 129 | 130 | 相关服务恢复正常,由上面的测试可以知道Consul大致的故障处理策略: 131 | ![Alt text](http://static.bluersw.com/images/spring-cloud-consul-client-24.png) 132 | -------------------------------------------------------------------------------- /spring-cloud-consul-client/ConsumerService.md: -------------------------------------------------------------------------------- 1 | # 调用Consul服务(消费服务) 2 | 3 | ## 依赖项 4 | 5 | 在spring-cloud-consul-client项目中添加依赖项,POM文件内容中添加如下依赖项: 6 | 7 | ```text 8 | 9 | org.springframework.cloud 10 | spring-cloud-starter-consul-discovery 11 | 12 | 13 | 14 | org.springframework.cloud 15 | spring-cloud-starter-openfeign 16 | 17 | 18 | 19 | org.springframework.boot 20 | spring-boot-starter-web 21 | 22 | ``` 23 | 24 | spring-cloud-starter-consul-discovery为Consul提供支持,spring-cloud-starter-openfeign为HTTP请求提供Feign风格的调用,spring-boot-starter-web仅仅为了使用HTTP MVC测试方便。 25 | 26 | ## 配置信息 27 | 28 | ```text 29 | spring.application.name=spring-cloud-consul-client 30 | server.port=9002 31 | spring.cloud.consul.host=127.0.0.1 32 | spring.cloud.consul.port=8500 33 | #设置不需要注册到 consul 中 34 | spring.cloud.consul.discovery.register=false 35 | ``` 36 | 37 | 本测试不用把自己注册到服务中心里:spring.cloud.consul.discovery.register=false,所以在启动类里也不用声明@EnableDiscoveryClient注解。 38 | 39 | ## 远程服务调用接口 40 | 41 | ```java 42 | @FeignClient(name= "service-provider") 43 | public interface ServiceProviderRemote { 44 | 45 | @RequestMapping("/hello") 46 | public String Hello(@RequestParam String name); 47 | } 48 | ``` 49 | 50 | 使用openfeign调用远程服务接口,openfeign是Spring封装后的Feign,本项目中openfeign需要使用spring-cloud-starter-consul-discovery。 51 | 52 | ## 测试消费服务接口 53 | 54 | ```java 55 | @RestController 56 | public class TestConsul { 57 | 58 | @Autowired 59 | ServiceProviderRemote remote; 60 | 61 | @RequestMapping("/TestHello") 62 | public String TestHello(){ 63 | String first = remote.Hello("first-SWS"); 64 | String second = remote.Hello("second-SWS"); 65 | return first + " | " + second; 66 | } 67 | 68 | @RequestMapping("/Test") 69 | public String Test(){ 70 | return "OK"; 71 | } 72 | } 73 | ``` 74 | 75 | 为了测试负载均衡所以调用两次服务接口。 76 | 77 | ## 启动类 78 | 79 | ```java 80 | @SpringBootApplication 81 | @EnableFeignClients 82 | public class SpringCloudConsulClientApplication { 83 | 84 | public static void main(String[] args) { 85 | SpringApplication.run(SpringCloudConsulClientApplication.class, args); 86 | } 87 | 88 | } 89 | ``` 90 | 91 | 在启动类里需要使用@EnableFeignClients注解启动openfeign。 92 | 93 | ## 启动项目测试 94 | 95 | 访问查看结果: 96 | ![Alt text](http://static.bluersw.com/images/spring-cloud-consul-client-07.png) 97 | -------------------------------------------------------------------------------- /spring-cloud-consul-client/CreateProject.md: -------------------------------------------------------------------------------- 1 | # 创建调用Consul的客户端项目 2 | 3 | ## 创建项目 4 | 5 | ![Alt text](http://static.bluersw.com/images/spring-cloud-consul-client-01.png) 6 | ![Alt text](http://static.bluersw.com/images/spring-cloud-consul-client-02.png) 7 | ![Alt text](http://static.bluersw.com/images/spring-cloud-consul-client-03.png) 8 | ![Alt text](http://static.bluersw.com/images/spring-cloud-consul-client-04.png) 9 | -------------------------------------------------------------------------------- /spring-cloud-consul-client/InstallConsul.md: -------------------------------------------------------------------------------- 1 | # 安装Consul服务中心 2 | 3 | 首先下载对应版本的安装程序。[点击下载](https://www.consul.io/downloads.html) 4 | 5 | 我下载的是macOS64位版本,下载文件是一个ZIP文件,下载后解压缩到一个你喜欢的位置,以开发模式启动consul服务: 6 | 7 | ```shell 8 | #进入consul目录 9 | cd ~/consul 10 | #以开发模式启动服务,-server表示以服务模式启动 11 | ./consul agent -dev 12 | ``` 13 | 14 | ![Alt text](http://static.bluersw.com/images/spring-cloud-consul-client-05.png) 15 | 按照信息提示访问127.0.0.1:8500可以打开consul管理界面 16 | ![Alt text](http://static.bluersw.com/images/spring-cloud-consul-client-06.png) 17 | -------------------------------------------------------------------------------- /spring-cloud-consul-client/README.md: -------------------------------------------------------------------------------- 1 | # 目录 2 | 3 | * [安装Consul服务中心](InstallConsul.md) 4 | * [创建Consul客户端项目](CreateProject.md) 5 | * [调用Consul服务(消费服务)](ConsumerService.md) 6 | * [Consul集群Server模式](ConsulClusterServerMode.md) 7 | * [Consul集群Server+Client模式](ConsulClusterServerClientMode.md) 8 | -------------------------------------------------------------------------------- /spring-cloud-consul-client/mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM https://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Maven2 Start Up Batch script 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM M2_HOME - location of maven2's installed home dir 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | @REM e.g. to debug Maven itself, use 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | @REM ---------------------------------------------------------------------------- 35 | 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 37 | @echo off 38 | @REM set title of command window 39 | title %0 40 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' 41 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 42 | 43 | @REM set %HOME% to equivalent of $HOME 44 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 45 | 46 | @REM Execute a user defined script before this one 47 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 48 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 49 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" 50 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" 51 | :skipRcPre 52 | 53 | @setlocal 54 | 55 | set ERROR_CODE=0 56 | 57 | @REM To isolate internal variables from possible post scripts, we use another setlocal 58 | @setlocal 59 | 60 | @REM ==== START VALIDATION ==== 61 | if not "%JAVA_HOME%" == "" goto OkJHome 62 | 63 | echo. 64 | echo Error: JAVA_HOME not found in your environment. >&2 65 | echo Please set the JAVA_HOME variable in your environment to match the >&2 66 | echo location of your Java installation. >&2 67 | echo. 68 | goto error 69 | 70 | :OkJHome 71 | if exist "%JAVA_HOME%\bin\java.exe" goto init 72 | 73 | echo. 74 | echo Error: JAVA_HOME is set to an invalid directory. >&2 75 | echo JAVA_HOME = "%JAVA_HOME%" >&2 76 | echo Please set the JAVA_HOME variable in your environment to match the >&2 77 | echo location of your Java installation. >&2 78 | echo. 79 | goto error 80 | 81 | @REM ==== END VALIDATION ==== 82 | 83 | :init 84 | 85 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 86 | @REM Fallback to current working directory if not found. 87 | 88 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 89 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 90 | 91 | set EXEC_DIR=%CD% 92 | set WDIR=%EXEC_DIR% 93 | :findBaseDir 94 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 95 | cd .. 96 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 97 | set WDIR=%CD% 98 | goto findBaseDir 99 | 100 | :baseDirFound 101 | set MAVEN_PROJECTBASEDIR=%WDIR% 102 | cd "%EXEC_DIR%" 103 | goto endDetectBaseDir 104 | 105 | :baseDirNotFound 106 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 107 | cd "%EXEC_DIR%" 108 | 109 | :endDetectBaseDir 110 | 111 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 112 | 113 | @setlocal EnableExtensions EnableDelayedExpansion 114 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 115 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 116 | 117 | :endReadAdditionalConfig 118 | 119 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 120 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" 121 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 122 | 123 | set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar" 124 | FOR /F "tokens=1,2 delims==" %%A IN (%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties) DO ( 125 | IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B 126 | ) 127 | 128 | @REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 129 | @REM This allows using the maven wrapper in projects that prohibit checking in binary data. 130 | if exist %WRAPPER_JAR% ( 131 | echo Found %WRAPPER_JAR% 132 | ) else ( 133 | echo Couldn't find %WRAPPER_JAR%, downloading it ... 134 | echo Downloading from: %DOWNLOAD_URL% 135 | powershell -Command "(New-Object Net.WebClient).DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')" 136 | echo Finished downloading %WRAPPER_JAR% 137 | ) 138 | @REM End of extension 139 | 140 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 141 | if ERRORLEVEL 1 goto error 142 | goto end 143 | 144 | :error 145 | set ERROR_CODE=1 146 | 147 | :end 148 | @endlocal & set ERROR_CODE=%ERROR_CODE% 149 | 150 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost 151 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 152 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" 153 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" 154 | :skipRcPost 155 | 156 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 157 | if "%MAVEN_BATCH_PAUSE%" == "on" pause 158 | 159 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% 160 | 161 | exit /B %ERROR_CODE% 162 | -------------------------------------------------------------------------------- /spring-cloud-consul-client/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.1.8.RELEASE 9 | 10 | 11 | com.bluersw 12 | spring-cloud-consul-client 13 | 0.0.1-SNAPSHOT 14 | spring-cloud-consul-client 15 | Demo project for Consul Client 16 | 17 | 18 | 1.8 19 | Greenwich.SR3 20 | 21 | 22 | 23 | 24 | org.springframework.cloud 25 | spring-cloud-starter-consul-discovery 26 | 27 | 28 | 29 | org.springframework.cloud 30 | spring-cloud-starter-openfeign 31 | 32 | 33 | 34 | org.springframework.boot 35 | spring-boot-starter-test 36 | test 37 | 38 | 39 | org.springframework.boot 40 | spring-boot-starter-web 41 | 42 | 43 | 44 | 45 | 46 | 47 | org.springframework.cloud 48 | spring-cloud-dependencies 49 | ${spring-cloud.version} 50 | pom 51 | import 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | org.springframework.boot 60 | spring-boot-maven-plugin 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /spring-cloud-consul-client/src/main/java/com/bluersw/consul/client/SpringCloudConsulClientApplication.java: -------------------------------------------------------------------------------- 1 | package com.bluersw.consul.client; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 6 | import org.springframework.cloud.openfeign.EnableFeignClients; 7 | 8 | @SpringBootApplication 9 | @EnableFeignClients 10 | public class SpringCloudConsulClientApplication { 11 | 12 | public static void main(String[] args) { 13 | SpringApplication.run(SpringCloudConsulClientApplication.class, args); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /spring-cloud-consul-client/src/main/java/com/bluersw/consul/client/controller/TestConsul.java: -------------------------------------------------------------------------------- 1 | package com.bluersw.consul.client.controller; 2 | 3 | import com.bluersw.consul.client.service.GatewayRemote; 4 | import com.bluersw.consul.client.service.ServiceProviderRemote; 5 | 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.web.bind.annotation.RequestMapping; 8 | import org.springframework.web.bind.annotation.RestController; 9 | 10 | @RestController 11 | public class TestConsul { 12 | 13 | @Autowired 14 | ServiceProviderRemote remote; 15 | 16 | @Autowired 17 | GatewayRemote gatewayRemote; 18 | 19 | @RequestMapping("/TestHello") 20 | public String TestHello(){ 21 | String first = remote.Hello("first-SWS"); 22 | String second = remote.Hello("second-SWS"); 23 | return first + " | " + second; 24 | } 25 | 26 | @RequestMapping("/Test") 27 | public String Test(){ 28 | return "OK"; 29 | } 30 | 31 | @RequestMapping("/TestGW") 32 | public String TestGW(){ 33 | String first = gatewayRemote.Hello("first-SWS"); 34 | String second = gatewayRemote.Hello("second-SWS"); 35 | return first + " | " + second; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /spring-cloud-consul-client/src/main/java/com/bluersw/consul/client/service/GatewayRemote.java: -------------------------------------------------------------------------------- 1 | package com.bluersw.consul.client.service; 2 | 3 | import org.springframework.cloud.openfeign.FeignClient; 4 | import org.springframework.web.bind.annotation.RequestMapping; 5 | import org.springframework.web.bind.annotation.RequestParam; 6 | 7 | //网关服务 8 | @FeignClient(name="PC-ApiGateWay") 9 | public interface GatewayRemote { 10 | 11 | //网关上的请求地址和外部用浏览器浏览的路径相同 12 | @RequestMapping("/service-provider/hello") 13 | public String Hello(@RequestParam String name); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /spring-cloud-consul-client/src/main/java/com/bluersw/consul/client/service/ServiceProviderRemote.java: -------------------------------------------------------------------------------- 1 | package com.bluersw.consul.client.service; 2 | 3 | import org.springframework.cloud.openfeign.FeignClient; 4 | import org.springframework.web.bind.annotation.RequestMapping; 5 | import org.springframework.web.bind.annotation.RequestParam; 6 | 7 | @FeignClient(name= "service-provider") 8 | public interface ServiceProviderRemote { 9 | 10 | @RequestMapping("/hello") 11 | public String Hello(@RequestParam String name); 12 | } 13 | -------------------------------------------------------------------------------- /spring-cloud-consul-client/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.application.name=spring-cloud-consul-client 2 | server.port=9003 3 | spring.cloud.consul.host=127.0.0.1 4 | spring.cloud.consul.port=8500 5 | #设置不需要注册到 consul 中 6 | spring.cloud.consul.discovery.register=false 7 | -------------------------------------------------------------------------------- /spring-cloud-consul-client/src/test/java/com/bluersw/consul/client/SpringCloudConsulClientApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.bluersw.consul.client; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class SpringCloudConsulClientApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /spring-cloud-gateway/.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | !.mvn/wrapper/maven-wrapper.jar 3 | !**/src/main/** 4 | !**/src/test/** 5 | 6 | ### STS ### 7 | .apt_generated 8 | .classpath 9 | .factorypath 10 | .project 11 | .settings 12 | .springBeans 13 | .sts4-cache 14 | 15 | ### IntelliJ IDEA ### 16 | .idea 17 | *.iws 18 | *.iml 19 | *.ipr 20 | 21 | ### NetBeans ### 22 | /nbproject/private/ 23 | /nbbuild/ 24 | /dist/ 25 | /nbdist/ 26 | /.nb-gradle/ 27 | build/ 28 | 29 | ### VS Code ### 30 | .vscode/ 31 | -------------------------------------------------------------------------------- /spring-cloud-gateway/.mvn/wrapper/MavenWrapperDownloader.java: -------------------------------------------------------------------------------- 1 | /* 2 | Licensed to the Apache Software Foundation (ASF) under one 3 | or more contributor license agreements. See the NOTICE file 4 | distributed with this work for additional information 5 | regarding copyright ownership. The ASF licenses this file 6 | to you under the Apache License, Version 2.0 (the 7 | "License"); you may not use this file except in compliance 8 | with the License. You may obtain a copy of the License at 9 | 10 | https://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, 13 | software distributed under the License is distributed on an 14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | KIND, either express or implied. See the License for the 16 | specific language governing permissions and limitations 17 | under the License. 18 | */ 19 | 20 | import java.io.File; 21 | import java.io.FileInputStream; 22 | import java.io.FileOutputStream; 23 | import java.io.IOException; 24 | import java.net.URL; 25 | import java.nio.channels.Channels; 26 | import java.nio.channels.ReadableByteChannel; 27 | import java.util.Properties; 28 | 29 | public class MavenWrapperDownloader { 30 | 31 | /** 32 | * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. 33 | */ 34 | private static final String DEFAULT_DOWNLOAD_URL = 35 | "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar"; 36 | 37 | /** 38 | * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to 39 | * use instead of the default one. 40 | */ 41 | private static final String MAVEN_WRAPPER_PROPERTIES_PATH = 42 | ".mvn/wrapper/maven-wrapper.properties"; 43 | 44 | /** 45 | * Path where the maven-wrapper.jar will be saved to. 46 | */ 47 | private static final String MAVEN_WRAPPER_JAR_PATH = 48 | ".mvn/wrapper/maven-wrapper.jar"; 49 | 50 | /** 51 | * Name of the property which should be used to override the default download url for the wrapper. 52 | */ 53 | private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; 54 | 55 | public static void main(String args[]) { 56 | System.out.println("- Downloader started"); 57 | File baseDirectory = new File(args[0]); 58 | System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); 59 | 60 | // If the maven-wrapper.properties exists, read it and check if it contains a custom 61 | // wrapperUrl parameter. 62 | File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); 63 | String url = DEFAULT_DOWNLOAD_URL; 64 | if(mavenWrapperPropertyFile.exists()) { 65 | FileInputStream mavenWrapperPropertyFileInputStream = null; 66 | try { 67 | mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); 68 | Properties mavenWrapperProperties = new Properties(); 69 | mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); 70 | url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); 71 | } catch (IOException e) { 72 | System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); 73 | } finally { 74 | try { 75 | if(mavenWrapperPropertyFileInputStream != null) { 76 | mavenWrapperPropertyFileInputStream.close(); 77 | } 78 | } catch (IOException e) { 79 | // Ignore ... 80 | } 81 | } 82 | } 83 | System.out.println("- Downloading from: : " + url); 84 | 85 | File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); 86 | if(!outputFile.getParentFile().exists()) { 87 | if(!outputFile.getParentFile().mkdirs()) { 88 | System.out.println( 89 | "- ERROR creating output direcrory '" + outputFile.getParentFile().getAbsolutePath() + "'"); 90 | } 91 | } 92 | System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); 93 | try { 94 | downloadFileFromURL(url, outputFile); 95 | System.out.println("Done"); 96 | System.exit(0); 97 | } catch (Throwable e) { 98 | System.out.println("- Error downloading"); 99 | e.printStackTrace(); 100 | System.exit(1); 101 | } 102 | } 103 | 104 | private static void downloadFileFromURL(String urlString, File destination) throws Exception { 105 | URL website = new URL(urlString); 106 | ReadableByteChannel rbc; 107 | rbc = Channels.newChannel(website.openStream()); 108 | FileOutputStream fos = new FileOutputStream(destination); 109 | fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); 110 | fos.close(); 111 | rbc.close(); 112 | } 113 | 114 | } 115 | -------------------------------------------------------------------------------- /spring-cloud-gateway/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunweisheng/spring-cloud-example/29ede89ea30037025ce3644380edbe9b5738f696/spring-cloud-gateway/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /spring-cloud-gateway/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.0/apache-maven-3.6.0-bin.zip 2 | -------------------------------------------------------------------------------- /spring-cloud-gateway/ConsulClusterServerClientGatewayMode.md: -------------------------------------------------------------------------------- 1 | # Consul集群加入网关服务 2 | 3 | ## 架构示意图 4 | 5 | ![Alt text](http://static.bluersw.com/images/spring-cloud-gateway/spring-cloud-gateway-12.png ) 6 | 外部的应用或网站通过外部网关服务消费各种服务,内部的生产者本身也可能是消费者,内部消费行为通过内部网关服务消费。 7 | 一个内部网关和一个外部网关以及一个Consul Client部署在一台服务器上,这样的网关服务器至少2组,外部网关前面还会有负载均衡设备,内部网关服务使用Consul Client进行查询后使用,内部网关的负载均衡由Consul负责了。 8 | 9 | ## 搭建演示环境 10 | 11 | 在[Consul集群Server+Client模式](./spring-cloud-consul-client/ConsulClusterServerClientMode.md)的基础上,我们更新并启动网关服务和消费者服务,演示环境中我们只启动一个网关服务进行模拟。 12 | 删除spring-cloud-gateway和spring-cloud-consul-consumer这两个容器。 13 | 14 | ```shell 15 | docker pull bluersw/spring-cloud-gateway:v3 16 | 17 | docker run --name=spring-cloud-gateway -d -p 9000:9000 bluersw/spring-cloud-gateway:v3 /opt/consul/./consul agent -data-dir=/opt/consul/data -config-dir=/opt/consul/config -node=gw-cc -join 172.17.0.2 18 | 19 | docker exec spring-cloud-gateway /usr/local/java/bin/java -jar /opt/spring-cloud-gateway-0.0.1-SNAPSHOT.jar 20 | 21 | docker pull bluersw/spring-cloud-consul-consumer:v3 22 | 23 | docker run --name=spring-cloud-consul-consumer -d -p 9003:9003 bluersw/spring-cloud-consul-consumer:v3 /opt/consul/./consul agent -data-dir=/opt/consul/data -config-dir=/opt/consul/config -node=consumer-cc -join 172.17.0.2 24 | 25 | docker exec spring-cloud-consul-consumer /usr/local/java/bin/java -jar /opt/spring-cloud-consul-client-0.0.1-SNAPSHOT.jar 26 | 27 | ``` 28 | 29 | ![Alt text](http://static.bluersw.com/images/spring-cloud-gateway/spring-cloud-gateway-13.png ) 30 | ![Alt text](http://static.bluersw.com/images/spring-cloud-gateway/spring-cloud-gateway-14.png ) 31 | 32 | ## TAG:V3版本的网关和消费者镜像修改内容 33 | 34 | spring-cloud-gateway的项目配置文件修改如下(也是在本机Consul Client注册),主要是为了增加prefer-ip-address否则Consul获取不到服务的IP地址: 35 | 36 | ```yml 37 | server: 38 | port: 9000 39 | spring: 40 | cloud: 41 | consul: 42 | host: 127.0.0.1 43 | port: 8500 44 | discovery: 45 | register: true 46 | prefer-ip-address: true 47 | health-check-path: /actuator/health 48 | gateway: 49 | routes: 50 | - id: test_route 51 | uri: lb://service-provider 52 | predicates: 53 | - Path=/service-provider/{segment} 54 | filters: 55 | - SetPath=/{segment} 56 | - name: Hystrix 57 | args: 58 | name: service-provider-fallback 59 | fallbackUri: forward:/service-provider-error 60 | - name: Retry 61 | args: 62 | retries: 3 63 | statuses: BAD_GATEWAY,BAD_REQUEST 64 | default-filters: 65 | - name: Hystrix 66 | args: 67 | name: fallbackcmd 68 | fallbackUri: forward:/default-error 69 | application: 70 | name: PC-ApiGateWay 71 | 72 | 73 | ``` 74 | 75 | 为了模拟内部服务调用网关消费其他服务,spring-cloud-consul-client项目(spring-cloud-consul-consumer)添加如下代码: 76 | 创建Feign风格的代理类 77 | 78 | ```java 79 | //网关服务 80 | @FeignClient(name="PC-ApiGateWay") 81 | public interface GatewayRemote { 82 | 83 | //网关上的请求地址和外部用浏览器浏览的路径相同 84 | @RequestMapping("/service-provider/hello") 85 | public String Hello(@RequestParam String name); 86 | 87 | } 88 | ``` 89 | 90 | Controller里增加如下方法: 91 | 92 | ```java 93 | @Autowired 94 | GatewayRemote gatewayRemote; 95 | 96 | @RequestMapping("/TestGW") 97 | public String TestGW(){ 98 | String first = gatewayRemote.Hello("first-SWS"); 99 | String second = gatewayRemote.Hello("second-SWS"); 100 | return first + " | " + second; 101 | } 102 | ``` 103 | 104 | ## 模拟外部访问 105 | 106 | 直接在浏览器里访问127.0.0.1:9000/service-provider/hello?name=sws,得到服务的返回信息: 107 | ![Alt text](http://static.bluersw.com/images/spring-cloud-gateway/spring-cloud-gateway-15.png ) 108 | 109 | ## 模拟内部访问 110 | 111 | 在浏览器里访问127.0.0.1:9003/TestGW,得到服务的返回信息: 112 | ![Alt text](http://static.bluersw.com/images/spring-cloud-gateway/spring-cloud-gateway-16.png ) 113 | -------------------------------------------------------------------------------- /spring-cloud-gateway/CreateProject.md: -------------------------------------------------------------------------------- 1 | # 创建网关项目 2 | 3 | ## 加入网关后微服务的架构图 4 | 5 | ![Alt text](http://static.bluersw.com/images/spring-cloud-gateway/spring-cloud-gateway-01.png ) 6 | 7 | ## 创建项目 8 | 9 | ![Alt text](http://static.bluersw.com/images/spring-cloud-gateway/spring-cloud-gateway-02.png ) 10 | ![Alt text](http://static.bluersw.com/images/spring-cloud-gateway/spring-cloud-gateway-03.png ) 11 | 12 | ## POM文件 13 | 14 | ```xml 15 | 16 | 1.8 17 | Greenwich.SR3 18 | 19 | 20 | 21 | 22 | org.springframework.cloud 23 | spring-cloud-starter-gateway 24 | 25 | 26 | 27 | org.springframework.boot 28 | spring-boot-starter-test 29 | test 30 | 31 | 32 | 33 | 34 | 35 | 36 | org.springframework.cloud 37 | spring-cloud-dependencies 38 | ${spring-cloud.version} 39 | pom 40 | import 41 | 42 | 43 | 44 | ``` 45 | 46 | ## 修改配置文件 47 | 48 | 将项目目录下的/src/main/resources/application.properties文件重命名为application.yml,properties配置格式和yml配置格式是等效的,而yml配置格式能更好的被配置中心使用,所以我们使用yml配置格式。 49 | 50 | ## 测试网关项目 51 | 52 | application.yml配置文件内容修改如下: 53 | 54 | ```yml 55 | server: 56 | port: 9000 57 | spring: 58 | cloud: 59 | gateway: 60 | routes: 61 | - id: first_route 62 | uri: https://github.com/sunweisheng 63 | predicates: 64 | - Path=/test 65 | ``` 66 | 67 | * port:网关服务端口 68 | * routes:路由集合 69 | * id:路由的唯一标示 70 | * uri:路由目标地址 71 | * predicates:路由条件,如果为true则路由到uri 72 | 73 | predicates(还有filters)的种类很多请参考[Spring Cloud Gateway官网](https://cloud.spring.io/spring-cloud-gateway/reference/html/) 74 | 75 | ## 启动项目测试 76 | 77 | 访问127.0.0.1:9000/test 78 | ![Alt text](http://static.bluersw.com/images/spring-cloud-gateway/spring-cloud-gateway-04.png ) 79 | -------------------------------------------------------------------------------- /spring-cloud-gateway/Fuse.md: -------------------------------------------------------------------------------- 1 | # 网关中加入熔断机制 2 | 3 | ## 在网关中加入熔断机制 4 | 5 | ![Alt text](http://static.bluersw.com/images/spring-cloud-gateway/spring-cloud-gateway-09.png ) 6 | 7 | ## 添加依赖项 8 | 9 | spring-cloud-gateway项目POM文件加入spring-cloud-starter-netflix-hystrix 10 | 11 | ```xml 12 | 13 | org.springframework.cloud 14 | spring-cloud-starter-netflix-hystrix 15 | 16 | ``` 17 | 18 | ## 修改配置文件 19 | 20 | 修改application.yml配置文件 21 | 22 | ```yml 23 | server: 24 | port: 9000 25 | spring: 26 | cloud: 27 | consul: 28 | host: 127.0.0.1 29 | port: 8500 30 | discovery: 31 | register: true 32 | gateway: 33 | routes: 34 | - id: test_route 35 | uri: lb://service-provider 36 | predicates: 37 | - Path=/service-provider/{segment} 38 | filters: 39 | - SetPath=/{segment} 40 | - name: Hystrix 41 | args: 42 | name: service-provider-fallback 43 | fallbackUri: forward:/service-provider-error 44 | - name: Retry 45 | args: 46 | retries: 3 47 | statuses: BAD_GATEWAY,BAD_REQUEST 48 | default-filters: 49 | - name: Hystrix 50 | args: 51 | name: fallbackcmd 52 | fallbackUri: forward:/default-error 53 | application: 54 | name: PC-ApiGateWay 55 | ``` 56 | 57 | ### 在默认过滤器中加入熔断机制 58 | 59 | ```yml 60 | default-filters: 61 | - name: Hystrix 62 | args: 63 | name: fallbackcmd 64 | fallbackUri: forward:/default-error 65 | ``` 66 | 67 | gateway下的default-filters代表默认过滤器,Hystrix是熔断机制的实现,fallbackcmd是HystrixCommand对象的名字(name属性),fallbackUri表示触发熔断机制后的跳转请求url,/default-error是在spring-cloud-gateway项目中实现的错误信息统一处理Controller: 68 | 69 | ```java 70 | @RestController 71 | public class ErrorHandle { 72 | 73 | @RequestMapping("/default-error") 74 | public String DefaultErrorHandle(){ 75 | return "这是通用错误处理返回的信息。"; 76 | } 77 | } 78 | ``` 79 | 80 | ### 自定义单条路由的熔断机制处理内容 81 | 82 | ```yml 83 | gateway: 84 | routes: 85 | - id: test_route 86 | uri: lb://service-provider 87 | predicates: 88 | - Path=/service-provider/{segment} 89 | filters: 90 | - SetPath=/{segment} 91 | - name: Hystrix 92 | args: 93 | name: service-provider-fallback 94 | fallbackUri: forward:/service-provider-error 95 | ``` 96 | 97 | 内容和上面介绍相同,同样需要spring-cloud-gateway项目实现service-provider-error处理过程。 98 | 99 | ```java 100 | @RestController 101 | public class ErrorHandle { 102 | 103 | @RequestMapping("/default-error") 104 | public String DefaultErrorHandle(){ 105 | return "这是通用错误处理返回的信息。"; 106 | } 107 | 108 | @RequestMapping("/service-provider-error") 109 | public String ServiceProviderErrorHandle(){ 110 | return "这是ServiceProvider服务专属的错误处理信息。"; 111 | } 112 | } 113 | ``` 114 | 115 | ### 自动重试机制 116 | 117 | ```yml 118 | gateway: 119 | routes: 120 | - id: test_route 121 | uri: lb://service-provider 122 | predicates: 123 | - Path=/service-provider/{segment} 124 | filters: 125 | - SetPath=/{segment} 126 | - name: Hystrix 127 | args: 128 | name: service-provider-fallback 129 | fallbackUri: forward:/service-provider-error 130 | - name: Retry 131 | args: 132 | retries: 3 133 | statuses: BAD_GATEWAY,BAD_REQUEST 134 | ``` 135 | 136 | 在gateway的filters下声明name为Retry的过滤器,retries重试次数,statuses返回HTTP状态码为何值时重试(还有methods和series参数),请参考org.springframework.http.HttpStatus、org.springframework.http.HttpMethod和org.springframework.http.HttpStatus.Series。 137 | 138 | ## 启动项目测试 139 | 140 | 启动 Consul服务中心和spring-cloud-provider微服务,最后启动spring-cloud-gateway项目,正常情况下: 141 | ![Alt text](http://static.bluersw.com/images/spring-cloud-gateway/spring-cloud-gateway-10.png ) 142 | 143 | 关闭spring-cloud-provider微服务进程之后再次刷新页面: 144 | ![Alt text](http://static.bluersw.com/images/spring-cloud-gateway/spring-cloud-gateway-11.png ) 145 | -------------------------------------------------------------------------------- /spring-cloud-gateway/README.md: -------------------------------------------------------------------------------- 1 | # 目录 2 | 3 | * [创建网关项目](CreateProject.md) 4 | * [Spring Cloud Gateway注册到服务器中心(Consul)](RegisteredConsul.md) 5 | * [网关中加入熔断机制](Fuse.md) 6 | * [Consul集群加入网关服务](ConsulClusterServerClientGatewayMode.md) 7 | -------------------------------------------------------------------------------- /spring-cloud-gateway/RegisteredConsul.md: -------------------------------------------------------------------------------- 1 | # Spring Cloud Gateway注册到服务器中心(Consul) 2 | 3 | ## 准备环境 4 | 5 | 启动Consul(./consul agent -dev)作为服务中心,默认是8500端口,然后启动spring-cloud-provider(9001端口)和spring-cloud-provider-second(9002端口)两个项目作为微服务。 6 | 在Consul管理后台可以看见两个服务启动: 7 | ![Alt text](http://static.bluersw.com/images/spring-cloud-gateway/spring-cloud-gateway-05.png ) 8 | 9 | ## 添加Spring Cloud Gateway项目的依赖项 10 | 11 | POM内增加如下依赖: 12 | 13 | ```xml 14 | 15 | org.springframework.boot 16 | spring-boot-starter-actuator 17 | 18 | 19 | org.springframework.cloud 20 | spring-cloud-starter-consul-discovery 21 | 22 | ``` 23 | 24 | ## 修改Spring Cloud Gateway项目配置 25 | 26 | ```yml 27 | server: 28 | port: 9000 29 | spring: 30 | cloud: 31 | consul: 32 | host: 127.0.0.1 33 | port: 8500 34 | discovery: 35 | register: true 36 | gateway: 37 | routes: 38 | - id: test_route 39 | uri: lb://service-provider 40 | predicates: 41 | - Path=/service-provider/{segment} 42 | filters: 43 | - SetPath=/{segment} 44 | application: 45 | name: PC-ApiGateWay 46 | ``` 47 | 48 | * host:Consul的IP地址 49 | * port:Consul的端口号 50 | * register:是否将自己注册到Consul中 51 | * lb://service-provider:Consul的服务名称,以{lb://服务名}进行访问 52 | * Path:路由要匹配的路径格式 53 | * SetPath:设置路径过滤器,作用是匹配后可以根据分割符进行访问路径的设置 54 | * name:自己注册到Consul中的名称 55 | 56 | ## 启动Spring Cloud Gateway项目 57 | 58 | 启动后Consul后台可以看见Spring Cloud Gateway项目的注册内容 59 | ![Alt text](http://static.bluersw.com/images/spring-cloud-gateway/spring-cloud-gateway-06.png ) 60 | 61 | ## 测试访问 62 | 63 | 访问 “127.0.0.1:9000/service-provider/hello?name=sws” 这个地址,并刷新页面测试网关的负载均衡。 64 | ![Alt text](http://static.bluersw.com/images/spring-cloud-gateway/spring-cloud-gateway-07.png ) 65 | ![Alt text](http://static.bluersw.com/images/spring-cloud-gateway/spring-cloud-gateway-08.png ) 66 | 67 | 可以看出网关代理了后台微服务的功能,并起到了轮询访问的作用。 68 | -------------------------------------------------------------------------------- /spring-cloud-gateway/mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM https://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Maven2 Start Up Batch script 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM M2_HOME - location of maven2's installed home dir 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | @REM e.g. to debug Maven itself, use 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | @REM ---------------------------------------------------------------------------- 35 | 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 37 | @echo off 38 | @REM set title of command window 39 | title %0 40 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' 41 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 42 | 43 | @REM set %HOME% to equivalent of $HOME 44 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 45 | 46 | @REM Execute a user defined script before this one 47 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 48 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 49 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" 50 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" 51 | :skipRcPre 52 | 53 | @setlocal 54 | 55 | set ERROR_CODE=0 56 | 57 | @REM To isolate internal variables from possible post scripts, we use another setlocal 58 | @setlocal 59 | 60 | @REM ==== START VALIDATION ==== 61 | if not "%JAVA_HOME%" == "" goto OkJHome 62 | 63 | echo. 64 | echo Error: JAVA_HOME not found in your environment. >&2 65 | echo Please set the JAVA_HOME variable in your environment to match the >&2 66 | echo location of your Java installation. >&2 67 | echo. 68 | goto error 69 | 70 | :OkJHome 71 | if exist "%JAVA_HOME%\bin\java.exe" goto init 72 | 73 | echo. 74 | echo Error: JAVA_HOME is set to an invalid directory. >&2 75 | echo JAVA_HOME = "%JAVA_HOME%" >&2 76 | echo Please set the JAVA_HOME variable in your environment to match the >&2 77 | echo location of your Java installation. >&2 78 | echo. 79 | goto error 80 | 81 | @REM ==== END VALIDATION ==== 82 | 83 | :init 84 | 85 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 86 | @REM Fallback to current working directory if not found. 87 | 88 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 89 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 90 | 91 | set EXEC_DIR=%CD% 92 | set WDIR=%EXEC_DIR% 93 | :findBaseDir 94 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 95 | cd .. 96 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 97 | set WDIR=%CD% 98 | goto findBaseDir 99 | 100 | :baseDirFound 101 | set MAVEN_PROJECTBASEDIR=%WDIR% 102 | cd "%EXEC_DIR%" 103 | goto endDetectBaseDir 104 | 105 | :baseDirNotFound 106 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 107 | cd "%EXEC_DIR%" 108 | 109 | :endDetectBaseDir 110 | 111 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 112 | 113 | @setlocal EnableExtensions EnableDelayedExpansion 114 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 115 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 116 | 117 | :endReadAdditionalConfig 118 | 119 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 120 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" 121 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 122 | 123 | set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar" 124 | FOR /F "tokens=1,2 delims==" %%A IN (%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties) DO ( 125 | IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B 126 | ) 127 | 128 | @REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 129 | @REM This allows using the maven wrapper in projects that prohibit checking in binary data. 130 | if exist %WRAPPER_JAR% ( 131 | echo Found %WRAPPER_JAR% 132 | ) else ( 133 | echo Couldn't find %WRAPPER_JAR%, downloading it ... 134 | echo Downloading from: %DOWNLOAD_URL% 135 | powershell -Command "(New-Object Net.WebClient).DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')" 136 | echo Finished downloading %WRAPPER_JAR% 137 | ) 138 | @REM End of extension 139 | 140 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 141 | if ERRORLEVEL 1 goto error 142 | goto end 143 | 144 | :error 145 | set ERROR_CODE=1 146 | 147 | :end 148 | @endlocal & set ERROR_CODE=%ERROR_CODE% 149 | 150 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost 151 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 152 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" 153 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" 154 | :skipRcPost 155 | 156 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 157 | if "%MAVEN_BATCH_PAUSE%" == "on" pause 158 | 159 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% 160 | 161 | exit /B %ERROR_CODE% 162 | -------------------------------------------------------------------------------- /spring-cloud-gateway/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.1.8.RELEASE 9 | 10 | 11 | com.bluersw 12 | spring-cloud-gateway 13 | 0.0.1-SNAPSHOT 14 | spring-cloud-gateway 15 | Demo project for Spring Cloud Gateway 16 | 17 | 18 | 1.8 19 | Greenwich.SR3 20 | 21 | 22 | 23 | 24 | org.springframework.cloud 25 | spring-cloud-starter-gateway 26 | 27 | 28 | 29 | org.springframework.boot 30 | spring-boot-starter-actuator 31 | 32 | 33 | org.springframework.cloud 34 | spring-cloud-starter-consul-discovery 35 | 36 | 37 | 38 | org.springframework.boot 39 | spring-boot-starter-test 40 | test 41 | 42 | 43 | 44 | org.springframework.cloud 45 | spring-cloud-starter-netflix-hystrix 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | org.springframework.cloud 54 | spring-cloud-dependencies 55 | ${spring-cloud.version} 56 | pom 57 | import 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | org.springframework.boot 66 | spring-boot-maven-plugin 67 | 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /spring-cloud-gateway/src/main/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunweisheng/spring-cloud-example/29ede89ea30037025ce3644380edbe9b5738f696/spring-cloud-gateway/src/main/.DS_Store -------------------------------------------------------------------------------- /spring-cloud-gateway/src/main/java/com/bluersw/cloud/gateway/SpringCloudGatewayApplication.java: -------------------------------------------------------------------------------- 1 | package com.bluersw.cloud.gateway; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class SpringCloudGatewayApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(SpringCloudGatewayApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /spring-cloud-gateway/src/main/java/com/bluersw/cloud/gateway/controller/ErrorHandle.java: -------------------------------------------------------------------------------- 1 | package com.bluersw.cloud.gateway.controller; 2 | 3 | import org.springframework.web.bind.annotation.RequestMapping; 4 | import org.springframework.web.bind.annotation.RestController; 5 | 6 | @RestController 7 | public class ErrorHandle { 8 | 9 | @RequestMapping("/default-error") 10 | public String DefaultErrorHandle(){ 11 | return "这是通用错误处理返回的信息。"; 12 | } 13 | 14 | @RequestMapping("/service-provider-error") 15 | public String ServiceProviderErrorHandle(){ 16 | return "这是ServiceProvider服务专属的错误处理信息。"; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /spring-cloud-gateway/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 9000 3 | spring: 4 | cloud: 5 | consul: 6 | host: 127.0.0.1 7 | port: 8500 8 | discovery: 9 | register: true 10 | prefer-ip-address: true 11 | health-check-path: /actuator/health 12 | gateway: 13 | routes: 14 | - id: test_route 15 | uri: lb://service-provider 16 | predicates: 17 | - Path=/service-provider/{segment} 18 | filters: 19 | - SetPath=/{segment} 20 | - name: Hystrix 21 | args: 22 | name: service-provider-fallback 23 | fallbackUri: forward:/service-provider-error 24 | - name: Retry 25 | args: 26 | retries: 3 27 | statuses: BAD_GATEWAY,BAD_REQUEST 28 | default-filters: 29 | - name: Hystrix 30 | args: 31 | name: fallbackcmd 32 | fallbackUri: forward:/default-error 33 | application: 34 | name: PC-ApiGateWay 35 | -------------------------------------------------------------------------------- /spring-cloud-gateway/src/test/java/com/bluersw/cloud/gateway/SpringCloudGatewayApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.bluersw.cloud.gateway; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class SpringCloudGatewayApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /spring-cloud-provider-second/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/** 5 | !**/src/test/** 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | 30 | ### VS Code ### 31 | .vscode/ 32 | -------------------------------------------------------------------------------- /spring-cloud-provider-second/.mvn/wrapper/MavenWrapperDownloader.java: -------------------------------------------------------------------------------- 1 | /* 2 | Licensed to the Apache Software Foundation (ASF) under one 3 | or more contributor license agreements. See the NOTICE file 4 | distributed with this work for additional information 5 | regarding copyright ownership. The ASF licenses this file 6 | to you under the Apache License, Version 2.0 (the 7 | "License"); you may not use this file except in compliance 8 | with the License. You may obtain a copy of the License at 9 | 10 | https://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, 13 | software distributed under the License is distributed on an 14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | KIND, either express or implied. See the License for the 16 | specific language governing permissions and limitations 17 | under the License. 18 | */ 19 | 20 | import java.io.File; 21 | import java.io.FileInputStream; 22 | import java.io.FileOutputStream; 23 | import java.io.IOException; 24 | import java.net.URL; 25 | import java.nio.channels.Channels; 26 | import java.nio.channels.ReadableByteChannel; 27 | import java.util.Properties; 28 | 29 | public class MavenWrapperDownloader { 30 | 31 | /** 32 | * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. 33 | */ 34 | private static final String DEFAULT_DOWNLOAD_URL = 35 | "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar"; 36 | 37 | /** 38 | * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to 39 | * use instead of the default one. 40 | */ 41 | private static final String MAVEN_WRAPPER_PROPERTIES_PATH = 42 | ".mvn/wrapper/maven-wrapper.properties"; 43 | 44 | /** 45 | * Path where the maven-wrapper.jar will be saved to. 46 | */ 47 | private static final String MAVEN_WRAPPER_JAR_PATH = 48 | ".mvn/wrapper/maven-wrapper.jar"; 49 | 50 | /** 51 | * Name of the property which should be used to override the default download url for the wrapper. 52 | */ 53 | private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; 54 | 55 | public static void main(String args[]) { 56 | System.out.println("- Downloader started"); 57 | File baseDirectory = new File(args[0]); 58 | System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); 59 | 60 | // If the maven-wrapper.properties exists, read it and check if it contains a custom 61 | // wrapperUrl parameter. 62 | File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); 63 | String url = DEFAULT_DOWNLOAD_URL; 64 | if(mavenWrapperPropertyFile.exists()) { 65 | FileInputStream mavenWrapperPropertyFileInputStream = null; 66 | try { 67 | mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); 68 | Properties mavenWrapperProperties = new Properties(); 69 | mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); 70 | url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); 71 | } catch (IOException e) { 72 | System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); 73 | } finally { 74 | try { 75 | if(mavenWrapperPropertyFileInputStream != null) { 76 | mavenWrapperPropertyFileInputStream.close(); 77 | } 78 | } catch (IOException e) { 79 | // Ignore ... 80 | } 81 | } 82 | } 83 | System.out.println("- Downloading from: : " + url); 84 | 85 | File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); 86 | if(!outputFile.getParentFile().exists()) { 87 | if(!outputFile.getParentFile().mkdirs()) { 88 | System.out.println( 89 | "- ERROR creating output direcrory '" + outputFile.getParentFile().getAbsolutePath() + "'"); 90 | } 91 | } 92 | System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); 93 | try { 94 | downloadFileFromURL(url, outputFile); 95 | System.out.println("Done"); 96 | System.exit(0); 97 | } catch (Throwable e) { 98 | System.out.println("- Error downloading"); 99 | e.printStackTrace(); 100 | System.exit(1); 101 | } 102 | } 103 | 104 | private static void downloadFileFromURL(String urlString, File destination) throws Exception { 105 | URL website = new URL(urlString); 106 | ReadableByteChannel rbc; 107 | rbc = Channels.newChannel(website.openStream()); 108 | FileOutputStream fos = new FileOutputStream(destination); 109 | fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); 110 | fos.close(); 111 | rbc.close(); 112 | } 113 | 114 | } 115 | -------------------------------------------------------------------------------- /spring-cloud-provider-second/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunweisheng/spring-cloud-example/29ede89ea30037025ce3644380edbe9b5738f696/spring-cloud-provider-second/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /spring-cloud-provider-second/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.0/apache-maven-3.6.0-bin.zip 2 | -------------------------------------------------------------------------------- /spring-cloud-provider-second/mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM https://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Maven2 Start Up Batch script 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM M2_HOME - location of maven2's installed home dir 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | @REM e.g. to debug Maven itself, use 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | @REM ---------------------------------------------------------------------------- 35 | 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 37 | @echo off 38 | @REM set title of command window 39 | title %0 40 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' 41 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 42 | 43 | @REM set %HOME% to equivalent of $HOME 44 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 45 | 46 | @REM Execute a user defined script before this one 47 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 48 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 49 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" 50 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" 51 | :skipRcPre 52 | 53 | @setlocal 54 | 55 | set ERROR_CODE=0 56 | 57 | @REM To isolate internal variables from possible post scripts, we use another setlocal 58 | @setlocal 59 | 60 | @REM ==== START VALIDATION ==== 61 | if not "%JAVA_HOME%" == "" goto OkJHome 62 | 63 | echo. 64 | echo Error: JAVA_HOME not found in your environment. >&2 65 | echo Please set the JAVA_HOME variable in your environment to match the >&2 66 | echo location of your Java installation. >&2 67 | echo. 68 | goto error 69 | 70 | :OkJHome 71 | if exist "%JAVA_HOME%\bin\java.exe" goto init 72 | 73 | echo. 74 | echo Error: JAVA_HOME is set to an invalid directory. >&2 75 | echo JAVA_HOME = "%JAVA_HOME%" >&2 76 | echo Please set the JAVA_HOME variable in your environment to match the >&2 77 | echo location of your Java installation. >&2 78 | echo. 79 | goto error 80 | 81 | @REM ==== END VALIDATION ==== 82 | 83 | :init 84 | 85 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 86 | @REM Fallback to current working directory if not found. 87 | 88 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 89 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 90 | 91 | set EXEC_DIR=%CD% 92 | set WDIR=%EXEC_DIR% 93 | :findBaseDir 94 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 95 | cd .. 96 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 97 | set WDIR=%CD% 98 | goto findBaseDir 99 | 100 | :baseDirFound 101 | set MAVEN_PROJECTBASEDIR=%WDIR% 102 | cd "%EXEC_DIR%" 103 | goto endDetectBaseDir 104 | 105 | :baseDirNotFound 106 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 107 | cd "%EXEC_DIR%" 108 | 109 | :endDetectBaseDir 110 | 111 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 112 | 113 | @setlocal EnableExtensions EnableDelayedExpansion 114 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 115 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 116 | 117 | :endReadAdditionalConfig 118 | 119 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 120 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" 121 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 122 | 123 | set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar" 124 | FOR /F "tokens=1,2 delims==" %%A IN (%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties) DO ( 125 | IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B 126 | ) 127 | 128 | @REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 129 | @REM This allows using the maven wrapper in projects that prohibit checking in binary data. 130 | if exist %WRAPPER_JAR% ( 131 | echo Found %WRAPPER_JAR% 132 | ) else ( 133 | echo Couldn't find %WRAPPER_JAR%, downloading it ... 134 | echo Downloading from: %DOWNLOAD_URL% 135 | powershell -Command "(New-Object Net.WebClient).DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')" 136 | echo Finished downloading %WRAPPER_JAR% 137 | ) 138 | @REM End of extension 139 | 140 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 141 | if ERRORLEVEL 1 goto error 142 | goto end 143 | 144 | :error 145 | set ERROR_CODE=1 146 | 147 | :end 148 | @endlocal & set ERROR_CODE=%ERROR_CODE% 149 | 150 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost 151 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 152 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" 153 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" 154 | :skipRcPost 155 | 156 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 157 | if "%MAVEN_BATCH_PAUSE%" == "on" pause 158 | 159 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% 160 | 161 | exit /B %ERROR_CODE% 162 | -------------------------------------------------------------------------------- /spring-cloud-provider-second/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.1.8.RELEASE 9 | 10 | 11 | com.bluersw 12 | spring-cloud-provider-second 13 | 0.0.1-SNAPSHOT 14 | spring-cloud-provider-second 15 | Demo project for cloud provider second 16 | 17 | 18 | 1.8 19 | 20 | 21 | 22 | 23 | org.springframework.boot 24 | spring-boot-starter-actuator 25 | 26 | 27 | org.springframework.cloud 28 | spring-cloud-starter-consul-discovery 29 | 2.1.3.RELEASE 30 | 31 | 32 | org.springframework.boot 33 | spring-boot-starter-web 34 | 35 | 36 | 37 | org.springframework.boot 38 | spring-boot-devtools 39 | runtime 40 | true 41 | 42 | 43 | org.springframework.boot 44 | spring-boot-starter-test 45 | test 46 | 47 | 48 | 49 | 50 | 51 | 52 | org.springframework.boot 53 | spring-boot-maven-plugin 54 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /spring-cloud-provider-second/src/main/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunweisheng/spring-cloud-example/29ede89ea30037025ce3644380edbe9b5738f696/spring-cloud-provider-second/src/main/.DS_Store -------------------------------------------------------------------------------- /spring-cloud-provider-second/src/main/java/com/bluersw/provider/second/SpringCloudProviderSecondApplication.java: -------------------------------------------------------------------------------- 1 | package com.bluersw.provider.second; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 6 | 7 | @SpringBootApplication 8 | @EnableDiscoveryClient 9 | public class SpringCloudProviderSecondApplication { 10 | 11 | public static void main(String[] args) { 12 | SpringApplication.run(SpringCloudProviderSecondApplication.class, args); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /spring-cloud-provider-second/src/main/java/com/bluersw/provider/second/controller/HelloWorld.java: -------------------------------------------------------------------------------- 1 | package com.bluersw.provider.second.controller; 2 | 3 | import org.springframework.web.bind.annotation.RequestMapping; 4 | import org.springframework.web.bind.annotation.RequestParam; 5 | import org.springframework.web.bind.annotation.RestController; 6 | 7 | @RestController 8 | public class HelloWorld { 9 | 10 | @RequestMapping("/hello") 11 | public String Hello(@RequestParam String name){ 12 | return "你好!" + name + ",这是第二个微服务。"; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /spring-cloud-provider-second/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.application.name=spring-cloud-provider-02 2 | server.port=9002 3 | spring.cloud.consul.host=127.0.0.1 4 | spring.cloud.consul.port=8500 5 | #注册到consul的服务名称 6 | spring.cloud.consul.discovery.serviceName=service-provider 7 | #以下两项如果不配置健康检查一定失败 8 | spring.cloud.consul.discovery.prefer-ip-address=true 9 | spring.cloud.consul.discovery.health-check-path=/actuator/health 10 | -------------------------------------------------------------------------------- /spring-cloud-provider-second/src/test/java/com/bluersw/provider/second/SpringCloudProviderSecondApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.bluersw.provider.second; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class SpringCloudProviderSecondApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /spring-cloud-provider/.gitignore: -------------------------------------------------------------------------------- 1 | README.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/** 5 | !**/src/test/** 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | 30 | ### VS Code ### 31 | .vscode/ 32 | -------------------------------------------------------------------------------- /spring-cloud-provider/.mvn/wrapper/MavenWrapperDownloader.java: -------------------------------------------------------------------------------- 1 | /* 2 | Licensed to the Apache Software Foundation (ASF) under one 3 | or more contributor license agreements. See the NOTICE file 4 | distributed with this work for additional information 5 | regarding copyright ownership. The ASF licenses this file 6 | to you under the Apache License, Version 2.0 (the 7 | "License"); you may not use this file except in compliance 8 | with the License. You may obtain a copy of the License at 9 | 10 | https://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, 13 | software distributed under the License is distributed on an 14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | KIND, either express or implied. See the License for the 16 | specific language governing permissions and limitations 17 | under the License. 18 | */ 19 | 20 | import java.io.File; 21 | import java.io.FileInputStream; 22 | import java.io.FileOutputStream; 23 | import java.io.IOException; 24 | import java.net.URL; 25 | import java.nio.channels.Channels; 26 | import java.nio.channels.ReadableByteChannel; 27 | import java.util.Properties; 28 | 29 | public class MavenWrapperDownloader { 30 | 31 | /** 32 | * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. 33 | */ 34 | private static final String DEFAULT_DOWNLOAD_URL = 35 | "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar"; 36 | 37 | /** 38 | * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to 39 | * use instead of the default one. 40 | */ 41 | private static final String MAVEN_WRAPPER_PROPERTIES_PATH = 42 | ".mvn/wrapper/maven-wrapper.properties"; 43 | 44 | /** 45 | * Path where the maven-wrapper.jar will be saved to. 46 | */ 47 | private static final String MAVEN_WRAPPER_JAR_PATH = 48 | ".mvn/wrapper/maven-wrapper.jar"; 49 | 50 | /** 51 | * Name of the property which should be used to override the default download url for the wrapper. 52 | */ 53 | private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; 54 | 55 | public static void main(String args[]) { 56 | System.out.println("- Downloader started"); 57 | File baseDirectory = new File(args[0]); 58 | System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); 59 | 60 | // If the maven-wrapper.properties exists, read it and check if it contains a custom 61 | // wrapperUrl parameter. 62 | File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); 63 | String url = DEFAULT_DOWNLOAD_URL; 64 | if(mavenWrapperPropertyFile.exists()) { 65 | FileInputStream mavenWrapperPropertyFileInputStream = null; 66 | try { 67 | mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); 68 | Properties mavenWrapperProperties = new Properties(); 69 | mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); 70 | url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); 71 | } catch (IOException e) { 72 | System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); 73 | } finally { 74 | try { 75 | if(mavenWrapperPropertyFileInputStream != null) { 76 | mavenWrapperPropertyFileInputStream.close(); 77 | } 78 | } catch (IOException e) { 79 | // Ignore ... 80 | } 81 | } 82 | } 83 | System.out.println("- Downloading from: : " + url); 84 | 85 | File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); 86 | if(!outputFile.getParentFile().exists()) { 87 | if(!outputFile.getParentFile().mkdirs()) { 88 | System.out.println( 89 | "- ERROR creating output direcrory '" + outputFile.getParentFile().getAbsolutePath() + "'"); 90 | } 91 | } 92 | System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); 93 | try { 94 | downloadFileFromURL(url, outputFile); 95 | System.out.println("Done"); 96 | System.exit(0); 97 | } catch (Throwable e) { 98 | System.out.println("- Error downloading"); 99 | e.printStackTrace(); 100 | System.exit(1); 101 | } 102 | } 103 | 104 | private static void downloadFileFromURL(String urlString, File destination) throws Exception { 105 | URL website = new URL(urlString); 106 | ReadableByteChannel rbc; 107 | rbc = Channels.newChannel(website.openStream()); 108 | FileOutputStream fos = new FileOutputStream(destination); 109 | fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); 110 | fos.close(); 111 | rbc.close(); 112 | } 113 | 114 | } 115 | -------------------------------------------------------------------------------- /spring-cloud-provider/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunweisheng/spring-cloud-example/29ede89ea30037025ce3644380edbe9b5738f696/spring-cloud-provider/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /spring-cloud-provider/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.0/apache-maven-3.6.0-bin.zip 2 | -------------------------------------------------------------------------------- /spring-cloud-provider/CreateProject.md: -------------------------------------------------------------------------------- 1 | # 创建一个测试用的微服务项目HelloWorld 2 | 3 | ## 创建项目 4 | 5 | ![Alt text](http://static.bluersw.com/images/spring-cloud-provider-01.png) 6 | ![Alt text](http://static.bluersw.com/images/spring-cloud-provider-02.png) 7 | ![Alt text](http://static.bluersw.com/images/spring-cloud-provider-03.png) 8 | ![Alt text](http://static.bluersw.com/images/spring-cloud-provider-04.png) 9 | 10 | ## 编写服务代码 11 | 12 | ```java 13 | @RestController 14 | public class HelloWorld { 15 | 16 | @RequestMapping("/hello") 17 | public String Hello(@RequestParam String name){ 18 | return "你好!" + name + ",这是一个微服务。"; 19 | } 20 | } 21 | ``` 22 | 23 | 编辑配置文件application.properties: 24 | 25 | ```text 26 | spring.application.name=spring-cloud-provider-01 27 | server.port=9000 28 | ``` 29 | 30 | ![Alt text](http://static.bluersw.com/images/spring-cloud-provider-05.png) 31 | 32 | ## 测试运行 33 | 34 | ![Alt text](http://static.bluersw.com/images/spring-cloud-provider-06.png) 35 | -------------------------------------------------------------------------------- /spring-cloud-provider/README.md: -------------------------------------------------------------------------------- 1 | # 目录 2 | 3 | * [创建微服务项目(Spring Boot)](CreateProject.md) 4 | * [注册服务到服务中心(Consul)](RegistrationService.md) 5 | -------------------------------------------------------------------------------- /spring-cloud-provider/RegistrationService.md: -------------------------------------------------------------------------------- 1 | # 注册服务到服务中心(Consul) 2 | 3 | ## 添加POM文件中的依赖 4 | 5 | 在POM文件添加如下依赖: 6 | 7 | ```xml 8 | 9 | org.springframework.boot 10 | spring-boot-starter-actuator 11 | 12 | 13 | org.springframework.cloud 14 | spring-cloud-starter-consul-discovery 15 | 2.1.3.RELEASE 16 | 17 | ``` 18 | spring-boot-starter-actuator负责健康检查,spring-cloud-starter-consul-discovery负责对Consul的支持。 19 | 在引用spring-cloud-starter-consul-discovery时必须明确版本号,我们这个项目BOOT的版本是2.1.8.RELEASE,spring-cloud-starter-consul-discovery版本号是2.1.3.RELEASE,可以在[Spring Cloud官网](https://spring.io/projects/spring-cloud)查到。 20 | ![Alt text](http://static.bluersw.com/images/spring-cloud-provider-07.png) 21 | 22 | 或者使用dependencyManagement进行版本号的管理,在POM文件里添加如下内容可以不指明spring-cloud-starter-consul-discovery的版本号: 23 | 24 | ```xml 25 | 26 | 1.8 27 | Greenwich.SR3 28 | 29 | 30 | 31 | 32 | 33 | org.springframework.cloud 34 | spring-cloud-dependencies 35 | ${spring-cloud.version} 36 | pom 37 | import 38 | 39 | 40 | 41 | 42 | 43 | 44 | ..... 45 | 46 | 47 | org.springframework.cloud 48 | spring-cloud-starter-consul-discovery 49 | 50 | 51 | ..... 52 | 53 | 54 | ``` 55 | 56 | ## 配置文件 57 | 58 | ```text 59 | spring.application.name=spring-cloud-provider-01 60 | server.port=9000 61 | spring.cloud.consul.host=localhost 62 | #consul端口可以自行修改 63 | spring.cloud.consul.port=8500 64 | #注册到consul的服务名称 65 | spring.cloud.consul.discovery.serviceName=service-provider 66 | ``` 67 | 68 | ## 启动类 69 | 70 | SpringCloudProviderApplication.java 71 | 72 | ```java 73 | @SpringBootApplication 74 | //支持服务发现 75 | @EnableDiscoveryClient 76 | public class SpringCloudProviderApplication { 77 | 78 | public static void main(String[] args) { 79 | SpringApplication.run(SpringCloudProviderApplication.class, args); 80 | } 81 | 82 | } 83 | ``` 84 | 85 | ## 启动服务 86 | 87 | 启动服务后自动完成注册服务的过程,回到consul控制界面可以看到服务已经注册好了: 88 | ![Alt text](http://static.bluersw.com/images/spring-cloud-provider-08.png) 89 | 点击service-provider可以看到该服务只有一个微服务: 90 | ![Alt text](http://static.bluersw.com/images/spring-cloud-provider-09.png) 91 | 92 | ## 负载均衡 93 | 94 | 我们参照spring-cloud-provider项目在复制一个微服务项目spring-cloud-provider-second,并对HelloWorld类进行修改以便区分: 95 | spring-cloud-provider项目中的HelloWorld类: 96 | 97 | ```java 98 | @RestController 99 | public class HelloWorld { 100 | 101 | @RequestMapping("/hello") 102 | public String Hello(@RequestParam String name){ 103 | return "你好!" + name + ",这是第一个微服务。"; 104 | } 105 | } 106 | ``` 107 | 108 | spring-cloud-provider-second项目中的HelloWorld类: 109 | 110 | ```java 111 | @RestController 112 | public class HelloWorld { 113 | 114 | @RequestMapping("/hello") 115 | public String Hello(@RequestParam String name){ 116 | return "你好!" + name + ",这是第二个微服务。"; 117 | } 118 | } 119 | ``` 120 | 121 | 修改spring-cloud-provider-second项目的端口号: 122 | spring-cloud-provider-second项目中的application.properties文件内容: 123 | 124 | ```text 125 | spring.application.name=spring-cloud-provider-02 126 | server.port=9001 127 | spring.cloud.consul.host=localhost 128 | spring.cloud.consul.port=8500 129 | #注册到consul的服务名称 130 | spring.cloud.consul.discovery.serviceName=service-provider 131 | ``` 132 | 133 | 启动spring-cloud-provider-second项目,查看service-provider服务提供者已经出现了两个服务提供者: 134 | ![Alt text](http://static.bluersw.com/images/spring-cloud-provider-10.png) 135 | -------------------------------------------------------------------------------- /spring-cloud-provider/mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM https://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Maven2 Start Up Batch script 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM M2_HOME - location of maven2's installed home dir 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | @REM e.g. to debug Maven itself, use 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | @REM ---------------------------------------------------------------------------- 35 | 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 37 | @echo off 38 | @REM set title of command window 39 | title %0 40 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' 41 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 42 | 43 | @REM set %HOME% to equivalent of $HOME 44 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 45 | 46 | @REM Execute a user defined script before this one 47 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 48 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 49 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" 50 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" 51 | :skipRcPre 52 | 53 | @setlocal 54 | 55 | set ERROR_CODE=0 56 | 57 | @REM To isolate internal variables from possible post scripts, we use another setlocal 58 | @setlocal 59 | 60 | @REM ==== START VALIDATION ==== 61 | if not "%JAVA_HOME%" == "" goto OkJHome 62 | 63 | echo. 64 | echo Error: JAVA_HOME not found in your environment. >&2 65 | echo Please set the JAVA_HOME variable in your environment to match the >&2 66 | echo location of your Java installation. >&2 67 | echo. 68 | goto error 69 | 70 | :OkJHome 71 | if exist "%JAVA_HOME%\bin\java.exe" goto init 72 | 73 | echo. 74 | echo Error: JAVA_HOME is set to an invalid directory. >&2 75 | echo JAVA_HOME = "%JAVA_HOME%" >&2 76 | echo Please set the JAVA_HOME variable in your environment to match the >&2 77 | echo location of your Java installation. >&2 78 | echo. 79 | goto error 80 | 81 | @REM ==== END VALIDATION ==== 82 | 83 | :init 84 | 85 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 86 | @REM Fallback to current working directory if not found. 87 | 88 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 89 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 90 | 91 | set EXEC_DIR=%CD% 92 | set WDIR=%EXEC_DIR% 93 | :findBaseDir 94 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 95 | cd .. 96 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 97 | set WDIR=%CD% 98 | goto findBaseDir 99 | 100 | :baseDirFound 101 | set MAVEN_PROJECTBASEDIR=%WDIR% 102 | cd "%EXEC_DIR%" 103 | goto endDetectBaseDir 104 | 105 | :baseDirNotFound 106 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 107 | cd "%EXEC_DIR%" 108 | 109 | :endDetectBaseDir 110 | 111 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 112 | 113 | @setlocal EnableExtensions EnableDelayedExpansion 114 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 115 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 116 | 117 | :endReadAdditionalConfig 118 | 119 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 120 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" 121 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 122 | 123 | set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar" 124 | FOR /F "tokens=1,2 delims==" %%A IN (%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties) DO ( 125 | IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B 126 | ) 127 | 128 | @REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 129 | @REM This allows using the maven wrapper in projects that prohibit checking in binary data. 130 | if exist %WRAPPER_JAR% ( 131 | echo Found %WRAPPER_JAR% 132 | ) else ( 133 | echo Couldn't find %WRAPPER_JAR%, downloading it ... 134 | echo Downloading from: %DOWNLOAD_URL% 135 | powershell -Command "(New-Object Net.WebClient).DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')" 136 | echo Finished downloading %WRAPPER_JAR% 137 | ) 138 | @REM End of extension 139 | 140 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 141 | if ERRORLEVEL 1 goto error 142 | goto end 143 | 144 | :error 145 | set ERROR_CODE=1 146 | 147 | :end 148 | @endlocal & set ERROR_CODE=%ERROR_CODE% 149 | 150 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost 151 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 152 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" 153 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" 154 | :skipRcPost 155 | 156 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 157 | if "%MAVEN_BATCH_PAUSE%" == "on" pause 158 | 159 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% 160 | 161 | exit /B %ERROR_CODE% 162 | -------------------------------------------------------------------------------- /spring-cloud-provider/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.1.8.RELEASE 9 | 10 | 11 | com.bluersw 12 | spring-cloud-provider 13 | 0.0.1-SNAPSHOT 14 | spring-cloud-provider 15 | Demo project for Service Provider 16 | 17 | 18 | 1.8 19 | 20 | 21 | 22 | 23 | org.springframework.boot 24 | spring-boot-starter-actuator 25 | 26 | 27 | org.springframework.cloud 28 | spring-cloud-starter-consul-discovery 29 | 2.1.3.RELEASE 30 | 31 | 32 | org.springframework.boot 33 | spring-boot-starter-web 34 | 35 | 36 | 37 | org.springframework.boot 38 | spring-boot-devtools 39 | runtime 40 | true 41 | 42 | 43 | org.springframework.boot 44 | spring-boot-starter-test 45 | test 46 | 47 | 48 | 49 | 50 | 51 | 52 | org.springframework.boot 53 | spring-boot-maven-plugin 54 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /spring-cloud-provider/src/main/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunweisheng/spring-cloud-example/29ede89ea30037025ce3644380edbe9b5738f696/spring-cloud-provider/src/main/.DS_Store -------------------------------------------------------------------------------- /spring-cloud-provider/src/main/java/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunweisheng/spring-cloud-example/29ede89ea30037025ce3644380edbe9b5738f696/spring-cloud-provider/src/main/java/.DS_Store -------------------------------------------------------------------------------- /spring-cloud-provider/src/main/java/com/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunweisheng/spring-cloud-example/29ede89ea30037025ce3644380edbe9b5738f696/spring-cloud-provider/src/main/java/com/.DS_Store -------------------------------------------------------------------------------- /spring-cloud-provider/src/main/java/com/bluersw/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunweisheng/spring-cloud-example/29ede89ea30037025ce3644380edbe9b5738f696/spring-cloud-provider/src/main/java/com/bluersw/.DS_Store -------------------------------------------------------------------------------- /spring-cloud-provider/src/main/java/com/bluersw/cloud/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunweisheng/spring-cloud-example/29ede89ea30037025ce3644380edbe9b5738f696/spring-cloud-provider/src/main/java/com/bluersw/cloud/.DS_Store -------------------------------------------------------------------------------- /spring-cloud-provider/src/main/java/com/bluersw/cloud/provider/SpringCloudProviderApplication.java: -------------------------------------------------------------------------------- 1 | package com.bluersw.cloud.provider; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 6 | 7 | @SpringBootApplication 8 | //支持服务发现 9 | @EnableDiscoveryClient 10 | public class SpringCloudProviderApplication { 11 | 12 | public static void main(String[] args) { 13 | SpringApplication.run(SpringCloudProviderApplication.class, args); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /spring-cloud-provider/src/main/java/com/bluersw/cloud/provider/controller/HelloWorld.java: -------------------------------------------------------------------------------- 1 | package com.bluersw.cloud.provider.controller; 2 | 3 | import org.springframework.web.bind.annotation.RequestMapping; 4 | import org.springframework.web.bind.annotation.RequestParam; 5 | import org.springframework.web.bind.annotation.RestController; 6 | 7 | @RestController 8 | public class HelloWorld { 9 | 10 | @RequestMapping("/hello") 11 | public String Hello(@RequestParam String name){ 12 | return "你好!" + name + ",这是第一个微服务。"; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /spring-cloud-provider/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.application.name=spring-cloud-provider-01 2 | server.port=9001 3 | spring.cloud.consul.host=127.0.0.1 4 | spring.cloud.consul.port=8500 5 | #注册到consul的服务名称 6 | spring.cloud.consul.discovery.serviceName=service-provider 7 | #以下两项如果不配置健康检查一定失败 8 | spring.cloud.consul.discovery.prefer-ip-address=true 9 | spring.cloud.consul.discovery.health-check-path=/actuator/health 10 | -------------------------------------------------------------------------------- /spring-cloud-provider/src/test/java/com/bluersw/cloud/provider/SpringCloudProviderApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.bluersw.cloud.provider; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class SpringCloudProviderApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /spring-cloud-stream/spring-cloud-stream-a/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .DS_Store 3 | target/ 4 | !.mvn/wrapper/maven-wrapper.jar 5 | !**/src/main/** 6 | !**/src/test/** 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | 17 | ### IntelliJ IDEA ### 18 | .idea 19 | *.iws 20 | *.iml 21 | *.ipr 22 | 23 | ### NetBeans ### 24 | /nbproject/private/ 25 | /nbbuild/ 26 | /dist/ 27 | /nbdist/ 28 | /.nb-gradle/ 29 | build/ 30 | 31 | ### VS Code ### 32 | .vscode/ 33 | -------------------------------------------------------------------------------- /spring-cloud-stream/spring-cloud-stream-a/.mvn/wrapper/MavenWrapperDownloader.java: -------------------------------------------------------------------------------- 1 | /* 2 | Licensed to the Apache Software Foundation (ASF) under one 3 | or more contributor license agreements. See the NOTICE file 4 | distributed with this work for additional information 5 | regarding copyright ownership. The ASF licenses this file 6 | to you under the Apache License, Version 2.0 (the 7 | "License"); you may not use this file except in compliance 8 | with the License. You may obtain a copy of the License at 9 | 10 | https://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, 13 | software distributed under the License is distributed on an 14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | KIND, either express or implied. See the License for the 16 | specific language governing permissions and limitations 17 | under the License. 18 | */ 19 | 20 | import java.io.File; 21 | import java.io.FileInputStream; 22 | import java.io.FileOutputStream; 23 | import java.io.IOException; 24 | import java.net.URL; 25 | import java.nio.channels.Channels; 26 | import java.nio.channels.ReadableByteChannel; 27 | import java.util.Properties; 28 | 29 | public class MavenWrapperDownloader { 30 | 31 | /** 32 | * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. 33 | */ 34 | private static final String DEFAULT_DOWNLOAD_URL = 35 | "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar"; 36 | 37 | /** 38 | * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to 39 | * use instead of the default one. 40 | */ 41 | private static final String MAVEN_WRAPPER_PROPERTIES_PATH = 42 | ".mvn/wrapper/maven-wrapper.properties"; 43 | 44 | /** 45 | * Path where the maven-wrapper.jar will be saved to. 46 | */ 47 | private static final String MAVEN_WRAPPER_JAR_PATH = 48 | ".mvn/wrapper/maven-wrapper.jar"; 49 | 50 | /** 51 | * Name of the property which should be used to override the default download url for the wrapper. 52 | */ 53 | private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; 54 | 55 | public static void main(String args[]) { 56 | System.out.println("- Downloader started"); 57 | File baseDirectory = new File(args[0]); 58 | System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); 59 | 60 | // If the maven-wrapper.properties exists, read it and check if it contains a custom 61 | // wrapperUrl parameter. 62 | File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); 63 | String url = DEFAULT_DOWNLOAD_URL; 64 | if(mavenWrapperPropertyFile.exists()) { 65 | FileInputStream mavenWrapperPropertyFileInputStream = null; 66 | try { 67 | mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); 68 | Properties mavenWrapperProperties = new Properties(); 69 | mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); 70 | url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); 71 | } catch (IOException e) { 72 | System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); 73 | } finally { 74 | try { 75 | if(mavenWrapperPropertyFileInputStream != null) { 76 | mavenWrapperPropertyFileInputStream.close(); 77 | } 78 | } catch (IOException e) { 79 | // Ignore ... 80 | } 81 | } 82 | } 83 | System.out.println("- Downloading from: : " + url); 84 | 85 | File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); 86 | if(!outputFile.getParentFile().exists()) { 87 | if(!outputFile.getParentFile().mkdirs()) { 88 | System.out.println( 89 | "- ERROR creating output direcrory '" + outputFile.getParentFile().getAbsolutePath() + "'"); 90 | } 91 | } 92 | System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); 93 | try { 94 | downloadFileFromURL(url, outputFile); 95 | System.out.println("Done"); 96 | System.exit(0); 97 | } catch (Throwable e) { 98 | System.out.println("- Error downloading"); 99 | e.printStackTrace(); 100 | System.exit(1); 101 | } 102 | } 103 | 104 | private static void downloadFileFromURL(String urlString, File destination) throws Exception { 105 | URL website = new URL(urlString); 106 | ReadableByteChannel rbc; 107 | rbc = Channels.newChannel(website.openStream()); 108 | FileOutputStream fos = new FileOutputStream(destination); 109 | fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); 110 | fos.close(); 111 | rbc.close(); 112 | } 113 | 114 | } 115 | -------------------------------------------------------------------------------- /spring-cloud-stream/spring-cloud-stream-a/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunweisheng/spring-cloud-example/29ede89ea30037025ce3644380edbe9b5738f696/spring-cloud-stream/spring-cloud-stream-a/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /spring-cloud-stream/spring-cloud-stream-a/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.0/apache-maven-3.6.0-bin.zip 2 | -------------------------------------------------------------------------------- /spring-cloud-stream/spring-cloud-stream-a/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.1.9.RELEASE 9 | 10 | 11 | com.bluersw 12 | spring-cloud-stream-a 13 | 0.0.1-SNAPSHOT 14 | spring-cloud-stream-a 15 | Demo project for Spring Cloud Stream 16 | 17 | 18 | 1.8 19 | Greenwich.SR3 20 | 21 | 22 | 23 | 24 | org.springframework.cloud 25 | spring-cloud-stream 26 | 27 | 28 | 29 | org.springframework.cloud 30 | spring-cloud-stream-binder-rabbit 31 | 32 | 33 | org.springframework.boot 34 | spring-boot-starter-test 35 | test 36 | 37 | 38 | org.springframework.cloud 39 | spring-cloud-stream-test-support 40 | test 41 | 42 | 43 | 44 | 45 | 46 | 47 | org.springframework.cloud 48 | spring-cloud-dependencies 49 | ${spring-cloud.version} 50 | pom 51 | import 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | org.springframework.boot 60 | spring-boot-maven-plugin 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /spring-cloud-stream/spring-cloud-stream-a/src/main/java/com/bluersw/s/c/s/a/AClient.java: -------------------------------------------------------------------------------- 1 | package com.bluersw.s.c.s.a; 2 | 3 | import java.util.Date; 4 | import java.util.HashMap; 5 | import java.util.Map; 6 | 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | 10 | import org.springframework.beans.factory.annotation.Autowired; 11 | import org.springframework.cloud.stream.annotation.EnableBinding; 12 | import org.springframework.cloud.stream.annotation.StreamListener; 13 | import org.springframework.messaging.support.GenericMessage; 14 | import org.springframework.messaging.support.MessageBuilder; 15 | 16 | //ChatInput.class的输入通道不在这里绑定,监听到数据会找不到AClient类的引用。 17 | //Input和Output通道定义的名字不能一样,否则程序启动会抛异常。 18 | @EnableBinding({ChatOutput.class,ChatInput.class}) 19 | public class AClient { 20 | 21 | private static Logger logger = LoggerFactory.getLogger(AClient.class); 22 | 23 | @Autowired 24 | private ChatOutput chatOutput; 25 | 26 | //StreamListener自带了Json转对象的能力,收到B的消息打印并回复B一个新的消息。 27 | @StreamListener(ChatInput.INPUT) 28 | public void PrintInput(ChatMessage message) { 29 | 30 | logger.info(message.ShowMessage()); 31 | 32 | ChatMessage replyMessage = new ChatMessage("ClientA","A To B Message.", new Date()); 33 | 34 | //这里只是测试实际业务根据需要设计特征值的范围,这个和消费组内有多少实例有关,然后把特征值放在消息头router属性中 35 | int feature = 1; 36 | Map headers = new HashMap<>(); 37 | headers.put("router", feature); 38 | 39 | GenericMessage genericMessage = new GenericMessage<>(replyMessage,headers); 40 | 41 | chatOutput.output().send(MessageBuilder.fromMessage(genericMessage).build()); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /spring-cloud-stream/spring-cloud-stream-a/src/main/java/com/bluersw/s/c/s/a/ChatInput.java: -------------------------------------------------------------------------------- 1 | package com.bluersw.s.c.s.a; 2 | 3 | import org.springframework.cloud.stream.annotation.Input; 4 | import org.springframework.messaging.SubscribableChannel; 5 | 6 | public interface ChatInput { 7 | 8 | String INPUT = "ChatExchanges-A-Input"; 9 | 10 | @Input(ChatInput.INPUT) 11 | SubscribableChannel input(); 12 | } 13 | -------------------------------------------------------------------------------- /spring-cloud-stream/spring-cloud-stream-a/src/main/java/com/bluersw/s/c/s/a/ChatMessage.java: -------------------------------------------------------------------------------- 1 | package com.bluersw.s.c.s.a; 2 | 3 | import java.io.Serializable; 4 | import java.util.Date; 5 | 6 | public class ChatMessage implements Serializable { 7 | 8 | private String name; 9 | private String message; 10 | private Date chatDate; 11 | 12 | //没有无参数的构造函数并行化会出错 13 | private ChatMessage(){} 14 | 15 | public ChatMessage(String name,String message,Date chatDate){ 16 | this.name = name; 17 | this.message = message; 18 | this.chatDate = chatDate; 19 | } 20 | 21 | public String getName(){ 22 | return this.name; 23 | } 24 | 25 | public String getMessage(){ 26 | return this.message; 27 | } 28 | 29 | public Date getChatDate() { return this.chatDate; } 30 | 31 | public String ShowMessage(){ 32 | return String.format("聊天消息:%s的时候,%s说%s。",this.chatDate,this.name,this.message); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /spring-cloud-stream/spring-cloud-stream-a/src/main/java/com/bluersw/s/c/s/a/ChatOutput.java: -------------------------------------------------------------------------------- 1 | package com.bluersw.s.c.s.a; 2 | 3 | import org.springframework.cloud.stream.annotation.Output; 4 | import org.springframework.messaging.MessageChannel; 5 | 6 | public interface ChatOutput { 7 | 8 | String OUTPUT = "ChatExchanges-A-Output"; 9 | 10 | @Output(ChatOutput.OUTPUT) 11 | MessageChannel output(); 12 | } 13 | -------------------------------------------------------------------------------- /spring-cloud-stream/spring-cloud-stream-a/src/main/java/com/bluersw/s/c/s/a/SpringCloudStreamAApplication.java: -------------------------------------------------------------------------------- 1 | package com.bluersw.s.c.s.a; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class SpringCloudStreamAApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(SpringCloudStreamAApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /spring-cloud-stream/spring-cloud-stream-a/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.application.name=spring-cloud-stream-a 2 | server.port=9010 3 | 4 | #设置默认绑定器 5 | spring.cloud.stream.defaultBinder = rabbit 6 | 7 | spring.rabbitmq.host=127.0.0.1 8 | spring.rabbitmq.port=5672 9 | spring.rabbitmq.username=guest 10 | spring.rabbitmq.password=guest 11 | 12 | #设置消费组(消费方设置) 13 | spring.cloud.stream.bindings.ChatExchanges-A-Input.group=A.group 14 | spring.cloud.stream.bindings.ChatExchanges-A-Input.destination=AInput 15 | #设置消费组(生产方设置) 16 | spring.cloud.stream.bindings.ChatExchanges-A-Output.destination=AOutput 17 | 18 | #设置分区(消费方设置) 19 | spring.cloud.stream.bindings.ChatExchanges-A-Input.consumer.partitioned=true 20 | spring.cloud.stream.instance-count=1 21 | spring.cloud.stream.instance-index=0 22 | #设置分区(生产方设置) 23 | spring.cloud.stream.bindings.ChatExchanges-A-Output.producer.partitionKeyExpression=headers.router 24 | spring.cloud.stream.bindings.ChatExchanges-A-Output.producer.partitionCount=1 25 | -------------------------------------------------------------------------------- /spring-cloud-stream/spring-cloud-stream-a/src/test/java/com/bluersw/s/c/s/a/SpringCloudStreamAApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.bluersw.s.c.s.a; 2 | 3 | import java.util.Date; 4 | 5 | import com.fasterxml.jackson.core.JsonProcessingException; 6 | import com.fasterxml.jackson.databind.ObjectMapper; 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import org.springframework.beans.factory.annotation.Autowired; 11 | import org.springframework.boot.test.context.SpringBootTest; 12 | import org.springframework.messaging.support.MessageBuilder; 13 | import org.springframework.test.context.junit4.SpringRunner; 14 | 15 | @RunWith(SpringRunner.class) 16 | @SpringBootTest 17 | public class SpringCloudStreamAApplicationTests { 18 | 19 | @Autowired 20 | private ChatOutput chatOutput; 21 | 22 | @Test 23 | public void contextLoads() throws JsonProcessingException { 24 | ChatMessage message = new ChatMessage("ClientA","Test Message", new Date()); 25 | 26 | String strMessage = new ObjectMapper().writeValueAsString(message); 27 | 28 | chatOutput.output().send(MessageBuilder.withPayload(message).build()); 29 | 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /spring-cloud-stream/spring-cloud-stream-b/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .DS_Store 3 | target/ 4 | !.mvn/wrapper/maven-wrapper.jar 5 | !**/src/main/** 6 | !**/src/test/** 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | 17 | ### IntelliJ IDEA ### 18 | .idea 19 | *.iws 20 | *.iml 21 | *.ipr 22 | 23 | ### NetBeans ### 24 | /nbproject/private/ 25 | /nbbuild/ 26 | /dist/ 27 | /nbdist/ 28 | /.nb-gradle/ 29 | build/ 30 | 31 | ### VS Code ### 32 | .vscode/ 33 | -------------------------------------------------------------------------------- /spring-cloud-stream/spring-cloud-stream-b/.mvn/wrapper/MavenWrapperDownloader.java: -------------------------------------------------------------------------------- 1 | /* 2 | Licensed to the Apache Software Foundation (ASF) under one 3 | or more contributor license agreements. See the NOTICE file 4 | distributed with this work for additional information 5 | regarding copyright ownership. The ASF licenses this file 6 | to you under the Apache License, Version 2.0 (the 7 | "License"); you may not use this file except in compliance 8 | with the License. You may obtain a copy of the License at 9 | 10 | https://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, 13 | software distributed under the License is distributed on an 14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | KIND, either express or implied. See the License for the 16 | specific language governing permissions and limitations 17 | under the License. 18 | */ 19 | 20 | import java.io.File; 21 | import java.io.FileInputStream; 22 | import java.io.FileOutputStream; 23 | import java.io.IOException; 24 | import java.net.URL; 25 | import java.nio.channels.Channels; 26 | import java.nio.channels.ReadableByteChannel; 27 | import java.util.Properties; 28 | 29 | public class MavenWrapperDownloader { 30 | 31 | /** 32 | * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. 33 | */ 34 | private static final String DEFAULT_DOWNLOAD_URL = 35 | "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar"; 36 | 37 | /** 38 | * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to 39 | * use instead of the default one. 40 | */ 41 | private static final String MAVEN_WRAPPER_PROPERTIES_PATH = 42 | ".mvn/wrapper/maven-wrapper.properties"; 43 | 44 | /** 45 | * Path where the maven-wrapper.jar will be saved to. 46 | */ 47 | private static final String MAVEN_WRAPPER_JAR_PATH = 48 | ".mvn/wrapper/maven-wrapper.jar"; 49 | 50 | /** 51 | * Name of the property which should be used to override the default download url for the wrapper. 52 | */ 53 | private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; 54 | 55 | public static void main(String args[]) { 56 | System.out.println("- Downloader started"); 57 | File baseDirectory = new File(args[0]); 58 | System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); 59 | 60 | // If the maven-wrapper.properties exists, read it and check if it contains a custom 61 | // wrapperUrl parameter. 62 | File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); 63 | String url = DEFAULT_DOWNLOAD_URL; 64 | if(mavenWrapperPropertyFile.exists()) { 65 | FileInputStream mavenWrapperPropertyFileInputStream = null; 66 | try { 67 | mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); 68 | Properties mavenWrapperProperties = new Properties(); 69 | mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); 70 | url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); 71 | } catch (IOException e) { 72 | System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); 73 | } finally { 74 | try { 75 | if(mavenWrapperPropertyFileInputStream != null) { 76 | mavenWrapperPropertyFileInputStream.close(); 77 | } 78 | } catch (IOException e) { 79 | // Ignore ... 80 | } 81 | } 82 | } 83 | System.out.println("- Downloading from: : " + url); 84 | 85 | File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); 86 | if(!outputFile.getParentFile().exists()) { 87 | if(!outputFile.getParentFile().mkdirs()) { 88 | System.out.println( 89 | "- ERROR creating output direcrory '" + outputFile.getParentFile().getAbsolutePath() + "'"); 90 | } 91 | } 92 | System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); 93 | try { 94 | downloadFileFromURL(url, outputFile); 95 | System.out.println("Done"); 96 | System.exit(0); 97 | } catch (Throwable e) { 98 | System.out.println("- Error downloading"); 99 | e.printStackTrace(); 100 | System.exit(1); 101 | } 102 | } 103 | 104 | private static void downloadFileFromURL(String urlString, File destination) throws Exception { 105 | URL website = new URL(urlString); 106 | ReadableByteChannel rbc; 107 | rbc = Channels.newChannel(website.openStream()); 108 | FileOutputStream fos = new FileOutputStream(destination); 109 | fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); 110 | fos.close(); 111 | rbc.close(); 112 | } 113 | 114 | } 115 | -------------------------------------------------------------------------------- /spring-cloud-stream/spring-cloud-stream-b/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunweisheng/spring-cloud-example/29ede89ea30037025ce3644380edbe9b5738f696/spring-cloud-stream/spring-cloud-stream-b/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /spring-cloud-stream/spring-cloud-stream-b/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.0/apache-maven-3.6.0-bin.zip 2 | -------------------------------------------------------------------------------- /spring-cloud-stream/spring-cloud-stream-b/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.1.9.RELEASE 9 | 10 | 11 | com.bluersw 12 | spring-cloud-stream-b 13 | 0.0.1-SNAPSHOT 14 | spring-cloud-stream-b 15 | Demo project for Spring Cloud Stream 16 | 17 | 18 | 1.8 19 | Greenwich.SR3 20 | 21 | 22 | 23 | 24 | org.springframework.cloud 25 | spring-cloud-stream 26 | 27 | 28 | 29 | org.springframework.cloud 30 | spring-cloud-stream-binder-rabbit 31 | 32 | 33 | 34 | org.springframework.boot 35 | spring-boot-starter-test 36 | test 37 | 38 | 39 | org.springframework.cloud 40 | spring-cloud-stream-test-support 41 | test 42 | 43 | 44 | 45 | 46 | 47 | 48 | org.springframework.cloud 49 | spring-cloud-dependencies 50 | ${spring-cloud.version} 51 | pom 52 | import 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | org.springframework.boot 61 | spring-boot-maven-plugin 62 | 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /spring-cloud-stream/spring-cloud-stream-b/src/main/java/com/bluersw/s/c/s/b/BClient.java: -------------------------------------------------------------------------------- 1 | package com.bluersw.s.c.s.b; 2 | 3 | import java.util.Date; 4 | import java.util.HashMap; 5 | import java.util.Map; 6 | 7 | import com.fasterxml.jackson.databind.ObjectMapper; 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | 11 | import org.springframework.cloud.stream.annotation.EnableBinding; 12 | import org.springframework.context.annotation.Bean; 13 | import org.springframework.integration.annotation.InboundChannelAdapter; 14 | import org.springframework.integration.annotation.Poller; 15 | import org.springframework.integration.annotation.ServiceActivator; 16 | import org.springframework.integration.annotation.Transformer; 17 | import org.springframework.messaging.support.GenericMessage; 18 | 19 | @EnableBinding(ChatProcessor.class) 20 | public class BClient { 21 | 22 | private static Logger logger = LoggerFactory.getLogger(BClient.class); 23 | 24 | //@ServiceActivator没有Json转对象的能力需要借助@Transformer注解 25 | @ServiceActivator(inputChannel=ChatProcessor.INPUT) 26 | public void PrintInput(ChatMessage message) { 27 | 28 | logger.info(message.ShowMessage()); 29 | } 30 | 31 | @Transformer(inputChannel = ChatProcessor.INPUT,outputChannel = ChatProcessor.INPUT) 32 | public ChatMessage transform(String message) throws Exception{ 33 | //logger.info(message); 34 | ObjectMapper objectMapper = new ObjectMapper(); 35 | return objectMapper.readValue(message,ChatMessage.class); 36 | } 37 | 38 | //每秒发出一个消息给A 39 | @Bean 40 | @InboundChannelAdapter(value = ChatProcessor.OUTPUT,poller = @Poller(fixedDelay="1000")) 41 | public GenericMessage SendChatMessage(){ 42 | ChatMessage message = new ChatMessage("ClientB","B To A Message.", new Date()); 43 | 44 | //这里只是测试实际业务根据需要设计特征值的范围,这个和消费组内有多少实例有关,然后把特征值放在消息头router属性中 45 | int feature = 1; 46 | Map headers = new HashMap<>(); 47 | headers.put("router", feature); 48 | 49 | return new GenericMessage<>(message,headers); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /spring-cloud-stream/spring-cloud-stream-b/src/main/java/com/bluersw/s/c/s/b/ChatMessage.java: -------------------------------------------------------------------------------- 1 | package com.bluersw.s.c.s.b; 2 | 3 | import java.util.Date; 4 | 5 | public class ChatMessage { 6 | private String name; 7 | private String message; 8 | private Date chatDate; 9 | 10 | //没有无参数的构造函数并行化会出错 11 | private ChatMessage(){} 12 | 13 | public ChatMessage(String name,String message,Date chatDate){ 14 | this.name = name; 15 | this.message = message; 16 | this.chatDate = chatDate; 17 | } 18 | 19 | public String getName(){ 20 | return this.name; 21 | } 22 | 23 | public String getMessage(){ 24 | return this.message; 25 | } 26 | 27 | public Date getChatDate() { return this.chatDate; } 28 | 29 | public String ShowMessage(){ 30 | return String.format("聊天消息:%s的时候,%s说%s。",this.chatDate,this.name,this.message); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /spring-cloud-stream/spring-cloud-stream-b/src/main/java/com/bluersw/s/c/s/b/ChatProcessor.java: -------------------------------------------------------------------------------- 1 | package com.bluersw.s.c.s.b; 2 | 3 | import org.springframework.cloud.stream.annotation.Input; 4 | import org.springframework.cloud.stream.annotation.Output; 5 | import org.springframework.messaging.MessageChannel; 6 | import org.springframework.messaging.SubscribableChannel; 7 | 8 | public interface ChatProcessor { 9 | 10 | String OUTPUT = "ChatExchanges-A-Input"; 11 | String INPUT = "ChatExchanges-A-Output"; 12 | 13 | @Input(ChatProcessor.INPUT) 14 | SubscribableChannel input(); 15 | 16 | @Output(ChatProcessor.OUTPUT) 17 | MessageChannel output(); 18 | } 19 | -------------------------------------------------------------------------------- /spring-cloud-stream/spring-cloud-stream-b/src/main/java/com/bluersw/s/c/s/b/SpringCloudStreamBApplication.java: -------------------------------------------------------------------------------- 1 | package com.bluersw.s.c.s.b; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class SpringCloudStreamBApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(SpringCloudStreamBApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /spring-cloud-stream/spring-cloud-stream-b/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.application.name=spring-cloud-stream-b 2 | server.port=9011 3 | 4 | #设置默认绑定器 5 | spring.cloud.stream.defaultBinder = rabbit 6 | 7 | spring.rabbitmq.host=127.0.0.1 8 | spring.rabbitmq.port=5672 9 | spring.rabbitmq.username=guest 10 | spring.rabbitmq.password=guest 11 | 12 | #设置消费组(消费方设置) 13 | spring.cloud.stream.bindings.ChatExchanges-A-Output.group=B.group 14 | spring.cloud.stream.bindings.ChatExchanges-A-Output.destination=AOutput 15 | #设置消费组(生产方设置) 16 | spring.cloud.stream.bindings.ChatExchanges-A-Input.destination=AInput 17 | 18 | #设置分区(消费方设置) 19 | spring.cloud.stream.bindings.ChatExchanges-A-Output.consumer.partitioned=true 20 | spring.cloud.stream.instance-count=1 21 | spring.cloud.stream.instance-index=0 22 | #设置分区(生产方设置) 23 | spring.cloud.stream.bindings.ChatExchanges-A-Input.producer.partitionKeyExpression=headers.router 24 | spring.cloud.stream.bindings.ChatExchanges-A-Input.producer.partitionCount=1 -------------------------------------------------------------------------------- /spring-cloud-stream/spring-cloud-stream-b/src/test/java/com/bluersw/s/c/s/b/SpringCloudStreamBApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.bluersw.s.c.s.b; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class SpringCloudStreamBApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | --------------------------------------------------------------------------------