SpringBoot Cloud是什么
Spring Cloud是一个分布式的整体解决方案。 Spring Cloud 为开发者提供了在
分布式系统(配置管理,服务发现,熔断,路由,微代理,控制总线,一次性token,全局琐, leader选举,分布式session,集群状态)中快速构建的工具,
使用Spring Cloud的开发者可以快速的启动服务或构建应用、同时能够快速和云平台资源进行对接。
SpringCloud分布式开发五大常用组件
• 服务发现——Netflix Eureka (发现了 英 [,jʊ(ə)'riːkə] )
• 客服端负载均衡——Netflix Ribbon (缎带 英 ['rɪbən] )
• 断路器——Netflix Hystrix (断路器)
• 服务网关——Netflix Zuul (路由网关)
• 分布式配置——Spring Cloud Config (配置)
https://www.processon.com/diagraming/5cef1a48e4b05d5b38bdb090
springboot和springcloud如果版本不兼容会报异常java.lang.NoSuchMethodError: org.springframework.boot.builder.SpringApplicationBuilder.([Ljava/lang/Class;)V
springcloud中eureka搭建
建一个空项目springboot-07-cloud,内有三个子模块
- eureka-server (注册中心)
- cloud-provider (服务提供者)
- cloud-consumer (消费者)
三个子模块文件结构如下
springboot-07-cloud base分支中三个子模块如下
springboot-07-cloud中三个子模块 |
eureka-server (注册中心) |
cloud-provider (服务提供者) |
cloud-consumer (消费者) |
|
|
|
|
pom.xml区别 |
xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>1.5.21.RELEASEversion>
<relativePath/>
parent>
<groupId>com.examplegroupId>
<artifactId>eureka-serverartifactId>
<version>0.0.1-SNAPSHOTversion>
<name>eureka-servername>
<description>Demo project for Spring Bootdescription>
<properties>
<java.version>1.8java.version>
<spring-cloud.version>Edgware.SR6spring-cloud.version>
properties>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-eureka-serverartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-dependenciesartifactId>
<version>${spring-cloud.version}version>
<type>pomtype>
<scope>importscope>
dependency>
dependencies>
dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
plugin>
plugins>
build>
project>
|
xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>1.5.21.RELEASEversion>
<relativePath/>
parent>
<groupId>com.examplegroupId>
<artifactId>cloud-providerartifactId>
<version>0.0.1-SNAPSHOTversion>
<name>cloud-providername>
<description>Demo project for Spring Bootdescription>
<properties>
<java.version>1.8java.version>
<spring-cloud.version>Edgware.SR6spring-cloud.version>
properties>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-dependenciesartifactId>
<version>${spring-cloud.version}version>
<type>pomtype>
<scope>importscope>
dependency>
dependencies>
dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
plugin>
plugins>
build>
project>
|
xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>1.5.21.RELEASEversion>
<relativePath/>
parent>
<groupId>com.examplegroupId>
<artifactId>cloud-consumerartifactId>
<version>0.0.1-SNAPSHOTversion>
<name>cloud-consumername>
<description>Demo project for Spring Bootdescription>
<properties>
<java.version>1.8java.version>
<spring-cloud.version>Edgware.SR6spring-cloud.version>
properties>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-dependenciesartifactId>
<version>${spring-cloud.version}version>
<type>pomtype>
<scope>importscope>
dependency>
dependencies>
dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
plugin>
plugins>
build>
project>
|
application.yml区别 |
server:
port: 8761
eureka:
instance:
hostname: eureka-server # eureka实例主机名
client:
register-with-eureka: false # 不把自己注册到eureka上, 因为自己本来就是注册中心
fetch-registry: false # 不从eureka上获取服务的注册信息
service-url:
defaultZone: http://localhost:8761/eureka/
#defaultZone 是注册中心服务注册的地址
默认eureka服务注册中心也会将自己作为客户端来尝试注册它自己,所以我们需要禁用它的客户端注册行为,将register-with-eureka置为false 若未禁用eureka服务注册中心的客户端注册行为,需提供service-url注册中心地址 |
server:
port: 8001
spring:
application:
name: provider
eureka:
instance:
prefer-ip-address: true # 注册服务时使用服务的ip地址
client:
register-with-eureka: true # 把自己注册到eureka上
fetch-registry: true # 从eureka上获取服务的注册信息
service-url:
defaultZone: http://localhost:8761/eureka/
#defaultZone 是注册中心服务注册的地址
|
server:
port: 8002
spring:
application:
name: consumer
eureka:
instance:
prefer-ip-address: true # 注册服务时使用服务的ip地址
client:
register-with-eureka: true # 把自己注册到eureka上
fetch-registry: true # 从eureka上获取服务的注册信息
service-url:
defaultZone: http://localhost:8761/eureka/
#defaultZone 是注册中心服务注册的地址
|
特别注意: springboot和springcloud的版本有对应要求, 本样例用的是
springboot 1.5.21.RELEASE 对应 springbloud Edgware.SR6
大版本对应:
Spring Boot |
Spring Cloud |
1.2.x |
Angel版本 |
1.3.x |
Brixton版本 |
1.4.x stripes |
Camden版本 |
1.5.x |
Dalston版本、Edgware版本 |
2.0.x |
Finchley版本 |
在实际开发过程中,我们需要更详细的版本对应:
spring-boot-starter-parent |
spring-cloud-dependencies |
版本号 |
发布日期 |
|
版本号 |
发布日期 |
|
1.5.2.RELEASE |
2017年3月 |
稳定版 |
Dalston.RC1 |
2017年未知月 |
|
1.5.9.RELEASE |
2017年11月 |
稳定版 |
Edgware.RELEASE |
2017年11月 |
稳定版 |
1.5.16.RELEASE |
|
|
Edgware.SR5 |
|
|
1.5.20.RELEASE |
|
|
Edgware.SR5 |
|
|
2.0.2.RELEASE |
2018年5月 |
|
Finchley.BUILD-SNAPSHOT |
2018年未知月 |
|
2.0.6.RELEASE |
|
|
Finchley.SR2 |
|
|
2.1.4.RELEASE |
|
|
Greenwich.SR1 |
|
|
待更新... |
|
|
|
|
|
eureka-server (注册中心)
EurekaServerApplication.java
注册中心启动入口 , 注意需要@EnableEurekaServer注解支持
package com.example.eurekaserver;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
/**
* 使用注册中心步骤
* 1. application.yml配置
* 2. @EnableEurekaServer注解添加
*/
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
cloud-provider (服务提供者)
CloudProviderApplication.java
生产者启动类, 不需要额外注解, 因为做了注册到eureka上的配置, 就可以直接把@RestController注解的所有接口自动注册到eureka注册中心 , 供消费者调用.
package com.example.cloud.provider;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class CloudProviderApplication {
public static void main(String[] args) {
SpringApplication.run(CloudProviderApplication.class, args);
}
}
CloudProviderController.java
package com.example.cloud.provider.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class CloudProviderController {
static int number;
@GetMapping("/buyTicket")
public String buyTicker(){
return "ticker "+ ++number;
}
}
cloud-consumer (消费者)
CloudConsumerApplication.java
消费者启动入口 , 注意需要开启@EnableDiscoveryClient注解
package com.example.cloud.consumer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
/**
* cloud 客户端调用时需要引入 @EnableDiscoveryClient 注解
*/
@SpringBootApplication
@EnableDiscoveryClient
public class CloudConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(CloudConsumerApplication.class, args);
}
}
MyConfiguration.java
需要把RestTemplate类组装到springboot容器中, 专门用于调用eureka上发现的服务
package com.example.cloud.consumer.config;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class MyConfiguration {
@LoadBalanced//负载均衡
@Bean//需要把RestTemplate装配进来,专门用于调用Eureka上发现的服务
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
CloudConsumberController.java
使用 http://localhost:8002/buyTicket 访问
package com.example.cloud.consumer.controller;
import com.netflix.discovery.converters.Auto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
public class CloudConsumberController {
@Autowired
RestTemplate restTemplate;
//http://localhost:8002/buyTicket
@GetMapping("/buyTicket")
public String buyTicker(){
String retData = restTemplate.getForObject("http://PROVIDER/buyTicket",String.class);//
retData = "成功购买" + retData;
return retData;
}
}
访问
访问springcloud的eureka-server 注册中心 http://localhost:8761/
访问cloud-consumer消费者提供的controller接口 http://localhost:8002/buyTicket 后,浏览器显示如下
注意Status一栏显示的是服务实例名, 默认取名规则为${spring.cloud.client.hostname}:${spring.application.name}:${spring.application.instance_id:${server.port}} , 最后的写法意为如果spring.application.instance_id没有定义,则取server.port, 如果已定义了则舍掉server.port取spring.application.instance_id
遗留问题
defaultZone 需要添加/eureka后缀? 是的默认就这样.
我的git项目地址
https://gitee.com/KingBoBo/springboot-07-cloud base分支
进阶篇
SpringBoot SpringCloud集群==>https://www.cnblogs.com/whatlonelytear/p/10894161.html