一、SpringCloud概述
SpringCloud是一系列框架的有序集合。它利用SpringBoot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用SpringBoot的开发风格做到一键启动和部署。
微服务解决框架-SpringCloud、Dubbo
SpringBoot和SpringCloud的关系
SpringBoot简化xml配置,快速整合框架
SpringCloud是一整套微服务解决方案--RPC远程调用
关系SpringBoot的SpringMVC暴露接口,而SpringCloud管理接口,存在依赖关系。
SpringCloud解决问题
配置管理(注册中心Eureka,Dubbo的是Zookeeper)、服务发现、服务注册、断路器(非常重要,容错机制、限流、调用接口失败如何解决)、路由策略(接口分发那台机器上去)、负载均衡、全局锁、分布式会话、客户端调用、接口网关、服务管理系统。
什么是Eureka
Eureka是Netflix开源的一个RESTful服务,主要用于服务的注册发现。Eureka由两个组件组成:Eureka服务器和Eureka客户端。Eureka服务器用作服务注册服务器。Eureka客户端是一个java客户端,用来简化与服务器的交互、作为轮询负载均衡器,并提供服务的故障切换支持。Netflix在其生产环境中使用的是另外的客户端,它提供基于流量、资源利用率以及出错状态的加权负载均衡。
Eureka的吸引力来源于以下几点:
开源:大家可以对实现一探究竟,甚至修改源码。
可靠:经过Netflix多年的生产环境考验,使用应该比较靠谱省心
功能齐全:不但提供了完整的注册发现服务,还有Ribbon等可以配合使用的服务。
基于Java:对于Java程序员来说,使用起来,心里比较有底。
spring cloud可以使用Spring Cloud, 与Eureka进行了很好的集成,使用起来非常方便。
搭建注册中心、服务提供者、服务消费者
实现服务注册
1.创建Eurekaserver项目
2.Maven依赖
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<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>
<!--maven的插件 -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
<defaultGoal>compile</defaultGoal>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>com.lovo.cloud.RegisterMian</mainClass>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
3.配置application.yml
#服务器的端口号
server:
port: 7000
#服务器的名字
spring:
application:
name: registerSys
eureka:
instance:
hostname: 127.0.0.1 #服务器的IP地址
client:
register-with-eureka: false # 是否注册自己的信息到EurekaServer,默认是true
fetch-registry: false # 是否拉取其它服务的信息,默认是true
serviceUrl: #服务器向外发布的地址
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
4、启动类
@SpringBootApplication
@EnableEurekaServer
public class RegisterMian {
public static void main(String[] args) {
SpringApplication.run(RegisterMian.class);
}
}
5、打开EurekaServer界面
服务提供者
创建一个服务提供者
1.创建项目service-member
2.Maven依赖
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.SR8</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>lovo</groupId>
<artifactId>basicModel</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!--jpa的jar包 ,操作数据库的,类似hibernate -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.21</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<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>
<!--maven的插件 -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
<defaultGoal>compile</defaultGoal>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>com.lovo.config.TwoMain</mainClass>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
3.application.yml配置
#服务器的端口号
server:
port: 7002
#服务器的名字
spring:
rabbitmq:
host: 127.0.0.1
port: 5672
application:
name: cloudone
eureka:
instance:
hostname: 127.0.0.1 #服务器的IP地址
client:
serviceUrl: #服务器向外发布的地址
defaultZone: http://127.0.0.1:7000/eureka/
4、启动类
@SpringBootApplication
@EnableEurekaClient//注册,负载均衡(ribbon)
@EnableFeignClients//远程调用
@EnableCircuitBreaker //断熔
public class TwoMain {
public static void main(String[] args) {
SpringApplication.run(TwoMain.class);
}
}
5、演示效果
服务名称已经注册到Eureka上了
feigin 远程调用
服务器级别组件数据交互就像调用本地的数据一样
使用feign导入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
在启动类上加上 @EnableFeignClients //feign远程调用注解
书写一个接口加上 @FeignClient(“clientone”) 注解
clientone 是服务器组件的注册名字
接口中的方法必须和要调用的方法一样
什么是Rebbion
Ribbon是一个基于HTTP和TCP的客户端负载均衡器,当我们将Ribbon和Eureka一起使用时,Ribbon会从Eureka注册中心去获取服务端列表有相同注册名的服务器组件,然后进行轮询访问以到达负载均衡的作用,这个功能封装在eureka依赖中所以导入依赖和上面的eureka一样
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
所以注册到注册服务器的服务器的启动类加上注解
@EnableEurekaClient //注册客户端,负载均衡rabbon
application.yml配置如下
#服务器的端口号
server:
port: 7002
#服务器的名字
spring:
application:
name: cloudtwo
eureka:
instance:
hostname: 127.0.0.1 #服务器的IP地址
client:
serviceUrl: #服务器向外发布的地址
defaultZone: http://127.0.0.1:7000/eureka/
hystrix 熔断 防止链式反应
导入的依赖
<!--熔断-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
调用方法的类 详细看里面的注释
@HystrixCommand(fallbackMethod = "rpcOneCopy")
public String rpcOne() {
return oneService.hello();
}
public String rpcOneCopy(){
return "系统暂时无法访问";
}
启动类
@SpringBootApplication
@EnableEurekaClient//注册,负载均衡(ribbon)
@EnableFeignClients//远程调用
@EnableCircuitBreaker //断熔
public class TwoMain {
public static void main(String[] args) {
SpringApplication.run(TwoMain.class);
}
}
config 配置 解决配置管理问题
这儿要注意到依赖导入问题,配置服务导入的依赖和客户端导入的依赖是不同的
配置服务器导入的依赖
<!--配置服务-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<!--配置客户端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
使用config配置服务器后
将客户端的application.yml改为bootstrap.yml
为什么?因为bootstrap.yml的优先级要高于application.yml
然后config配置服务器这边的配置文件如下,configfile文件下的配置文件为其他客户端服务器的配置文件,里面的配置还是和以前一样写,但是客户端服务器下的bootstrap.yml配置文件要指向配置服务器
bootstrap.yml配置如下
spring:
application:
name: cloudone
cloud:
config:
profile: dev
uri: http://127.0.0.1:8888/ #配置服务器的地址
config服务器配置如下
aplication.yml
spring:
profiles:
active: native #本地的
application-native.yml
server:
port: 8888
spring:
application:
name: cloudconfig#注册服务器名
cloud:
config:
server:
native:
search-locations: classpath:/configfile/ #搜索位置(各个配置文件的存放处)
什么是接口网关
前面说了,我们通过httpclient、ajax访问服务,但是在访问不同接口会出现跨域和内网问题。这时候就需要接口网关。
路由网关(zuul)
zuul的主要作用是路由转发和过滤器,路由功能是微服务的一部分,比如/api/user/转发到user服务。
搭建SpringCloud网关
1.创建service-zuul工程
2.Maven依赖
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.SR8</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<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>
3.application.yml配置
#服务器的端口号
server:
port: 80
#服务器的名字
spring:
application:
name: cloudzuul
eureka:
instance:
hostname: 127.0.0.1 #服务器的IP地址
client:
register-with-eureka: true # 是否注册自己的信息到EurekaServer,默认是true
fetch-registry: true # 是否拉取其它服务的信息,默认是true
serviceUrl: #注册服务器的地址
defaultZone: http://127.0.0.1:7000/eureka/
zuul:
routes:
one:
path: /one/**
service-id: cloudone
sensitive-headers:
two:
path: /two/**
service-id: cloudtwo
sensitive-headers:
4.启动类
@SpringBootApplication
@EnableEurekaClient
@EnableZuulProxy //网关代理
public class ZuulMain {
public static void main(String[] args) {
SpringApplication.run(ZuulMain.class);
}
}
服务过滤
@Component
public class MyFilter extends ZuulFilter {
@Override
public String filterType() {
return "pre";// 前置过滤器
// pre:可以在请求被路由之前调用
// route:在路由请求时候被调用
// post:在route和error过滤器之后被调用
// error:处理请求时发生错误时被调用
}
@Override
public int filterOrder() {
return 0;//优先级为0,数字越大,优先级越低
}
@Override
public boolean shouldFilter() {
return true; //false不过滤
}
@Override
public Object run() throws ZuulException {
System.out.println("进入过滤器");
return null;
}
}