1.SpringCloud架構搭建以及叢集&架構搭建之SpringCloud
1.建立maven聚合專案 spring-cloud-parent pom.xml配置
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artif actId> <version>2.0.5.RELEASE</version> <relativePath /> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <spring-cloud.version>Finchley.RELEASE</spring-cloud.version> <lombok.version>1.16.10</lombok.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>${lombok.version}</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
2.建立common模組 依賴父工程 3.建立eureka-8000 註冊中心 pom.xml配置
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
application.xml配置
server: port: 8000 eureka: instance: hostname: localhost #eureka伺服器的例項名字 client: register-with-eureka: false #註冊中心不註冊自己,預設自己也會註冊自己 fetch-registry: false #是否獲取資料,false表明自己就是註冊中心 service-url: defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ spring: application: name: eureka-8000 #應用名
啟動類配置
@EnableEurekaServer
@SpringBootApplication
public class Start {
public static void main(String[] args) {
SpringApplication.run(Start.class, args);
}
}
效果測試 成功 還沒有例項註冊到eureka 4.建立生產者 將服務註冊到eureka pom.xml配置檔案
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- 熱部署 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> </dependency> <!-- eureka客戶端 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> </dependencies>
application.yml配置檔案
server:
port: 1000
spring:
application:
name: provider-1000
eureka:
client:
service-url:
defaultZone: http://localhost:8000/eureka/
啟動類配置
@SpringBootApplication
@EnableEurekaClient
public class Start {
public static void main(String[] args) {
SpringApplication.run(Start.class, args);
}
}
測試效果 成功啟動 5.服務消費者 ribbon 與 feign ribbon 繼續新增多個生產者 provider -1001 provider-1002,給這些生產者 修改埠號 新增Ctrl
@RestController
public class Ctrl {
@RequestMapping("/hello")
public Map<String, Object> hello() {
Map<String, Object> map = new HashMap<String, Object>();
map.put("name", "provider-1002");
return map;
}
}
建立消費者 ribbon pom.xml配置檔案
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
</dependencies>
application.yml配置檔案
server:
port: 2000
eureka:
client:
service-url:
defaultZone: http://localhost:8000/eureka/
spring:
application:
name: consumer-ribbon-2000
配置檔案類
@Configuration
public class MyConfig {
@Bean
@LoadBalanced
/**新增負載均衡,預設會輪詢呼叫提供者*/
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
控制層
@RestController
public class Ctrl {
@Resource
RestTemplate restTemplate;
@RequestMapping("/hello")
public Map hello() {
return restTemplate.getForObject("http://PROVIDER/hello", Map.class);
}
}
測試效果 每次都會輪流執行 切換負載均衡策略 在myConfig 新增後 重新整理即可
/**修改負載均衡策略*/
@Bean
public IRule LoadBalanced(){
return new RandomRule();
}
建立消費者 Feign 編寫介面 我將介面寫到common工程 pom.xml配置檔案 org.springframework.cloud spring-cloud-starter-netflix-eureka-client org.springframework.boot spring-boot-starter-web org.springframework.cloud spring-cloud-starter-feign 1.4.2.RELEASE
介面
@FeignClient(value = "PROVIDER")/**通過value繫結微服務的名字*/
public interface IService {
@GetMapping("/hello")/**呼叫provider的@RequestMapping裡的名字*/
public Map<String,Object> hello();
}
consumer-feign pom.xml配置檔案
<dependencies>
<dependency>
<groupId>com.xiaowei.springcloud</groupId>
<artifactId>spring-cloud-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-feign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
<version>1.4.2.RELEASE</version>
</dependency>
</dependencies>
啟動類
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class Start {
public static void main(String[] args) {
SpringApplication.run(Start.class, args);
}
}
控制層
@RestController
public class Ctrl {
@Resource
IService iService;
@RequestMapping("/hello")
public Map hello() {
return iService.hello();
}
}
application.yml配置檔案
server:
port: 3000
eureka:
client:
service-url:
defaultZone: http://localhost:8000/eureka/
spring:
application:
name: consumer-feign-3000
測試 6.熔斷器 ribbon中使用熔斷器 pom.xml配置檔案
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
</dependencies>
application.yml配置檔案
server:
port: 2000
eureka:
client:
service-url:
defaultZone: http://localhost:8000/eureka/
spring:
application:
name: consumer-ribbon-hyxtrix-2000
啟動類
@SpringBootApplication
@EnableEurekaClient
@EnableHystrix
public class Start {
public static void main(String[] args) {
SpringApplication.run(Start.class, args);
}
}
配置檔案類
@Configuration
public class MyConfig {
@Bean
@LoadBalanced
/**新增負載均衡,預設會輪詢呼叫提供者*/
public RestTemplate restTemplate() {
return new RestTemplate();
}
/**修改負載均衡策略*/
/* @Bean
public IRule LoadBalanced(){
return new RandomRule();
}*/
}
控制層
@RestController
public class Ctrl {
@Resource
RestTemplate restTemplate;
@RequestMapping("/hello")
@HystrixCommand(fallbackMethod = "errorMethod")
public Map hello() {
/**PROVIDER是應用提供者註冊的名字*/
return restTemplate.getForObject("http://PROVIDER/hello", Map.class);
}
public Map<String, Object> errorMethod() {
Map<String, Object> map = new HashMap<>();
map.put("error", "出錯啦");
return map;
}
}
測試類 只啟動註冊中心和寫了熔斷器的消費者 Feign中使用熔斷器 feign中已經引入了hystrix 所以不需要依賴了 application.yml配置檔案
server:
port: 5000
eureka:
client:
service-url:
defaultZone: http://localhost:8000/eureka/
spring:
application:
name: consumer-feign-hyxtrix-5000
feign:
hystrix:
enabled: true # 開啟hystrix熔斷器
common工程中寫一個介面
/**用來處理異常問題*/
@FeignClient(value = "PROVIDER",fallback = HystrixService.class)
public interface IServiceHystrix {
@GetMapping("/hello")
public Map<String,Object> hello();
}
再寫一個介面實現類
@Component
public class HystrixService implements IServiceHystrix {
@Override
public Map<String, Object> hello() {
Map<String, Object> map = new HashMap<String, Object>();
map.put("feign", "出錯啦");
return map;
}
}
啟動類
@RestController
public class Ctrl {
@Resource
IServiceHystrix iService;
@RequestMapping("/hello")
public Map hello() {
return iService.hello();
}
}
測試 只開啟註冊中心和帶熔斷器的消費者feign 7 zuul路由閘道器配置 pom.xml配置檔案
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
application.yml配置檔案
server:
port: 6001
eureka:
client:
service-url:
defaultZone: http://localhost:8000/eureka/
spring:
application:
name: zuul
啟動類
@EnableZuulProxy
@SpringBootApplication
public class Start {
public static void main(String[] args) {
SpringApplication.run(Start.class, args);
}
}
測試 路由配置
application.yml
server:
port: 6001
eureka:
client:
service-url:
defaultZone: http://localhost:8000/eureka/
spring:
application:
name: zuul
zuul:
routes:
my-route: # 標識 代表一組 路由名稱 隨便起一個就好了 沒有任何意義,如果沒有配置 和service-id是一樣的
service-id: provider # 微服務的名字 要被路由的微服務
path: /zuuls/** # /zuul/hello ---> /provider/下面的hello請求 使用的路由路徑
測試 但是有bug 如果 看下圖 還是可以訪問 繼續修改 application.yml配置檔案
server:
port: 6001
eureka:
client:
service-url:
defaultZone: http://localhost:8000/eureka/
spring:
application:
name: zuul
zuul:
routes:
my-route: # 標識 代表一組 路由名稱 隨便起一個就好了 沒有任何意義,如果沒有配置 和service-id是一樣的
service-id: provider # 微服務的名字 要被路由的微服務
path: /zuuls/** # /zuul/hello ---> /provider/下面的hello請求 使用的路由路徑
ignored-services: "*" # 遮蔽指定的服務 遮蔽全部 但是不遮蔽設定好的
prefix: /xiaowei # 字首 隨便加一點
測試 進入之前的 成功! 8 過濾器 在zuul工程編寫一個類
/**
* 〈過濾器〉<br>
* @author xiaowei
* @create 2018/9/29
* @since 1.0.0
*/
public class TokenFilter extends ZuulFilter {
/**過濾器型別,例項裡邊型別類似與通知*/
@Override
public String filterType() {
return FilterConstants.PRE_TYPE;
}
/**當前過濾器的級別,在同一種類型才有意義,數字越大,優先順序越低*/
@Override
public int filterOrder() {
return 0;
}
/**是否要被過濾 true代表需要進行過濾*/
@Override
public boolean shouldFilter() {
return true;
}
/**過濾器要執行的方法*/
@Override
public Object run() throws ZuulException {
RequestContext context= RequestContext.getCurrentContext();
HttpServletRequest request = context.getRequest();
/**獲取請求的引數*/
String token = request.getParameter("token");
if(token==null){
/**過濾該請求,不對其進行路由*/
context.setSendZuulResponse(false);
/**返回錯誤碼*/
context.setResponseStatusCode(250);
/**返回錯誤內容*/
context.setResponseBody("{\"result\":\"你沒有傳遞token\"}");
context.set("isSuccess",false);
}else{
/**對該請求進行路由*/
context.setSendZuulResponse(true);
context.setResponseStatusCode(200);
/**設值,讓下一個Filter看到上一個Filter的狀態*/
context.set("isSuccess",true);
}
return null;
}
}
把這個類配置到Spring容器中
/**
* 〈閘道器啟動類〉<br>
*
* @author xiaowei
* @create 2018/9/28
* @since 1.0.0
*/
@SpringBootApplication
@EnableZuulProxy
@Configuration
public class Start {
public static void main(String[] args) {
SpringApplication.run(Start.class, args);
}
@Bean
public TokenFilter tokenFilter() {
return new TokenFilter();
}
}
啟動 測試 成功被攔截 成功進入 9 config分散式配置中心 建立一個Git倉庫 接下來下載到本地進行修改 編寫 application.yml配置檔案
spring:
profiles:
active:
- dev
---
spring:
profiles: dev
application:
name: config-client-9001
server:
port: 9001
user:
name: xiaowei
age: 99
---
spring:
profiles: test
application:
name: config-client-9002
server:
port: 9002
user:
name: xiaobai
age: 19
上傳到碼雲 建立spring-cloud-config-server-9008模組 pom.xml配置檔案
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
</dependencies>
application.xml配置檔案
server:
port: 9008
spring:
application:
name: config-server
cloud:
config:
server:
git:
uri: [email protected]:xiaowei_wang/springcloud-config.git #存放配置檔案git倉庫的地址
啟動類
/**
* 〈啟動類〉<br>
*
* @author xiaowei
* @create 2018/9/28
* @since 1.0.0
*/
@EnableConfigServer
@SpringBootApplication
public class Start {
public static void main(String[] args) {
SpringApplication.run(Start.class, args);
}
}
測試 只需要啟動config-server即可 注意 : ssh可能連線不上 修改application.yml配置檔案
server:
port: 9008
spring:
application:
name: config-server-9008
cloud:
config:
server:
git:
uri: https://gitee.com/xiaowei_wang/springcloud-config.git #存放配置檔案git倉庫的地址
username: *******
password: *******
測試會自動的根據環境獲取到不同的配置 10 config-client 任何一個需要獲取配置資訊的微服務都可以是一個client 建立spring-cloud-config-client-9009 pom.xml配置檔案
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
</dependencies>
bootstrap.yml 這個配置檔案的優先順序高於applicaiton.yml,當然,我們也可以在專案中繼續保持, application.yml配置檔案
spring:
cloud:
config:
name: application # 配置檔案的名字,去掉字尾,如果不指明,會載入application檔案
uri: http://localhost:9008 # config-server的地址
label: master # git的分支
profile: dev # 選擇環境
啟動類
@SpringBootApplication
public class Start {
public static void main(String[] args) {
SpringApplication.run(Start.class, args);
}
}
測試 啟動config-server-9008 啟動config-client 結果應該為 9001 成功 11. Config-Server叢集搭建 config-server-2500 config-server-2600 config-server-2700 以下檔案通用 pom.xml配置檔案
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
啟動類
/**
* 〈啟動類〉<br>
*
* @author xiaowei
* @create 2018/9/28
* @since 1.0.0
*/
@EnableEurekaClient
@EnableConfigServer
@SpringBootApplication
public class Start {
public static void main(String[] args) {
SpringApplication.run(Start.class, args);
}
}
配置檔案
server:
port: 2500
spring:
application:
name: config-server #叢集的話必須一致啊
cloud:
config:
server:
git:
uri: https://gitee.com/xiaowei_wang/springcloud-config.git #存放配置檔案git倉庫的地址
username: [email protected]
password: wxx1997xxxx
eureka:
client:
service-url:
defaultZone: http://localhost:8000/eureka/
測試 一切正常啟動
編寫cluster-client pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
bootstrap.xml
spring:
cloud:
config:
name: application # 配置檔案的名字
discovery:
service-id: CONFIG-SERVER
enabled: true
label: master
profile: dev
eureka:
client:
service-url:
defaultZone: http://localhost:8000/eureka/
控制層
@RestController
public class TestCtrl {
@Value("${user.name}")
private String name;
@Value("${user.age}")
private String age;
@RequestMapping("/info")
public String showInfo(String name,String age){
System.out.println(name+age);
return "aaa";
}
}
啟動類
/**
* 〈啟動類〉<br>
*
* @author xiaowei
* @create 2018/9/28
* @since 1.0.0
*/
@EnableEurekaClient
@SpringBootApplication
public class Start {
public static void main(String[] args) {
SpringApplication.run(Start.class, args);
}
}
測試是否載入到資料 12.eureka叢集 pom.xml
<dependencies>
<!-- eureka服務端 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
application.yml
server:
port: 8003
eureka:
instance:
hostname: eureka-server-8003 #伺服器的主機名
client:
register-with-eureka: false #不向註冊中心註冊自己
fetch-registry: false # 是否獲取資料,false表示自己就是註冊中心
service-url:
defaultZone: http://eureka-server-8001:8001,http://eureka-server-8002:8002 #配置其它eureka伺服器的地址
spring:
application:
name: eureka-cluster
配置hosts C:\Windows\System32\drivers\etc
啟動類
@EnableEurekaServer
@SpringBootApplication
public class Start {
public static void main(String[] args) {
SpringApplication.run(Start.class, args);
}
}
測試 成功 最後整個結構