文章目录
- SpringCloud相关介绍及应用
SpringCloud相关介绍及应用
一、架构设计演变
1、单体项目
单体项目将所有的服务部署到一起,如果某个模块出现问题,直接影响整个服务。
2、分布式项目
整个项目的各个模块分开部署,如果某个模块出现问题,只影响局部服务,不会导致整个服务宕机。
(1)优点:实现了架构的松耦合;
(2)缺点:为了实现分布式运用,需采用其他的组件进行维护,维护的成本很高;
分布式项目架构如图所示:
3、微服务形式
将单个应用程序作为一套小型的服务进行开发,每个服务都运行在自己的进程中,各个服务之间通过通讯机制进行通讯(一般是Http的API)。各个服务一般按照业务进行拆分,进行全自动部署。简而言之,就是在分布式的前提下,让项目**独立**运行,一切部署都是**全自动**的实现。<br />**(1)微服务的优点**<br />1)每个服务足够内聚,足够小,代码容易理解,聚焦于一个指定的业务;<br />2)开发简单,开发效率高;<br />3)微服务能够被小团队(2-5人)单独开发;<br />4)微服务是松耦合的,是具有功能意义的服务,无论在开发阶段还是部署阶段都是独立的;<br />5)微服务可以使用不同的语言进行开发;<br />6)易于和第三方集成,微服务允许容易且灵活的方式继承自动部署,通过持续集成工具实现,集成工具有Jenkins、Hudson、bamboo等;<br />7)微服务容易理解、修改和维护;<br />8)微服务允许融合最新技术;<br />9)微服务只注重业务逻辑,不会和HTML、CSS等前段语言相混合;<br />10)每个微服务都可以有自己的存储能力,可以独立连接数据库,也可以有统一的数据库;<br />**(2)微服务的缺点**<br />1)开发人员要处理分布式系统的复杂性;<br />2)多服务运维难度,随着服务的增加,运维压力增大;<br />3)系统部署依赖;<br />4)服务间的通讯成本高;<br />5)数据一致性;<br />6)系统集成测试;<br />7)性能监控;
二、微服务思想SOA
SOA,即是面向服务的架构:
将不同功能的服务进行拆分,不同的服务之间通过良好的接口和契约联系。接口采用中立的方式定义,独立于实现服务的硬件平台、操作系统以及编程语言,是的构建在各个项目中的服务,以统一和通用的方式进行交互。
三、微服务框架-SpringCloud
SpringCloud是微服务落地的一种技术,它为开发人员提供了快速构建分布式系统需要的模式工具(如配置管理、断路器、只能路由、微代理等)。为最常见的分布式系统模式提供了一种简单易用的编辑模型,可帮助开发人员构建弹性、可靠、协调的应用程序。
Springcloud结构图如下:
四、SpringCloud项目构建
注意:SpringCloud项目构建是基于SpringBoot基础之上的。
1、构建步骤
(1)构建父项目jt-springcloud
1)创建maven工程
2)导入jar包
jar包导入完成后打包;
SpringCloud需要依赖的jar包如下:
<!--导入springBoot依赖包 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.1.RELEASE</version>
<relativePath />
</parent>
<properties>
<java.version>1.8</java.version>
</properties>
<!--依赖管理,用于管理spring-cloud的依赖 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.SR2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<!--需要依赖的其他jar包 -->
<dependencies>
<!--导入springCloudjar包 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream</artifactId>
</dependency>
<!--引入springBoot jar包 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency> -->
<!--支持热部署 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>springloaded</artifactId>
<version>1.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<!--整合redis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
</dependency>
<!--导入pojo插件 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!--使用druid整合mysql数据库 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!--阿里数据源 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.12</version>
</dependency>
<!--mybatis-plus配置 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.0.6</version>
</dependency>
</dependencies>
(2)构建服务接口jt-springcloud-interfance
作用:接口中保存了项目通讯的接口信息.和pojo等公共信息,其作用类似于common项目的作用;
1)创建maven工程
选择创建项目类型为:Maven
Module;
父项目:jt–parent;
打包方式:jar;
2)创建工具类 、公用pojo等
测试时,创建User的Pojo;
实际项目中根据项目中的需求新建java类;
创建完毕后,将项目打包;
(3)构建服务提供者jt-springcloud-provider-8000
1)创建maven工程
项目类型:Maven Module;
父项目:jt-springcloud-provider-8000
注意:在Springcloud中各个服务分别占用不同的端口,为方便明了,可将端口附在服务名之后,此处的端口为8000,实际项目中根据实际情况而定;
2)添加接口项目的依赖
需要使用接口中的工具类或公用类,就要将jt-springcloud-interface作为依赖添加到项目中;
3)完成业务逻辑
测试时:完成user表的增删改查;
实际项目中:根据实际情况完成业务逻辑;
4)配置application.yml配置文件
需要定义服务访问的端口号、根目录以及数据源,配置如下:
#服务端口及路径的配置
server:
port: 8000 #单点登录的端口
servlet:
context-path: / #该配置可以不配,默认配置为“/”
spring:
#数据源的配置
datasource:
#引入druid数据源
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/jtdb?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
username: root
password: 123456
#mybatis-plush配置
mybatis-plus:
type-aliases-package: com.jt.pojo
mapper-locations: classpath:/mybatis/mappers/*.xml
configuration:
map-underscore-to-camel-case: true #自动开启驼峰规则映射
(4)构建服务消费者jt-springcloud-consumer-8020
1)创建maven工程
项目类型:Maven Module;
父项目:jt-parent;
注意:此处测试的端口为8020;
2)添加接口项目的依赖
添加jt-springcloud-interface的依赖,使用其工具类和其他公用的pojo;
3)配置application.yml配置文件
需要定义服务访问的端口号、根目录,如下图所示:
server:
port: 8020
servlet:
context-path: /
注意:消费者端不需要连接数据库,则不需要配置数据源,需要在主启动类上添加如下配置,排除数据源的加载,否则程序启动会报错:
**
@SpringBootApplication(exclude=DataSourceAutoConfiguration.class)
a.RestTemplate对象的创建
springcloud中的封装远程调用是使用Http协议,本次案例中实现远程调用的对象是RestTemplate,通过这个对象执行远程调用;
RestTemplate对象的创建通过配置类实现:
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate getTemplate() {
return new RestTemplate();
}
}
b.远程调用获取数据
编写controller,使用restTemplate对象调用其方法向提供者端发起请求获取数据,测试程序能够调通,表示配置成功;
注意:到此,服务提供者和消费者之间的调用能够正常跑通,表示项目基础搭建完成,要实现Springcloud微服务的管理,则要借助于Springcloud的几个重要组件完成,后面依次介绍。
五、SpirngCloud各大组件介绍
1、注册中心Eureka
(1)作用
(2)实现原理
注册中心内部有心跳检测机制,可以实时坚挺服务状态,同时记录服务IP、端口、服务名称等信息,方便消费者的调用。原理图如下:
(3)工作流程
1)启动注册中心;
2)服务的提供者讲自己的信息写入注册中心,注册中心将各个服务维护成一份服务列表;
3)启动消费者后,消费者首先连接注册中心,获取服务列表数据,并保存到本地,方便之后的调用;
4)有多个提供者时,客户端(消费者)内部有负载均衡策略(默认轮巡),挑选一个服务发起HttpClient调用,获取数据;
5)当服务提供者宕机后,注册中心的心跳检测(1分钟)发现提供者宕机,则动态维护服务列表数据,标记宕机(添加down属性);
6)当服务列表发生变化。消费者会再次同步数据,最终实现数据一致性。这时如果有消费者请求时,将陷入阻塞状态,满足AP原则;
注意:与Zookeeper不同的是,服务宕机时,Zookeeper要求立即同步数据,满足CP原则。
(4)注册中心的搭建
A、搭建注册中心
1)创建Maven工程jt-springcloud-Eureka-7000
项目类型:Maven Module;
父项目:jt-springcloud;
打包方式:jar;
注意:此处测试端口号为:7000。
2)添加jar包
添加注册中心Eureka相关jar包,如下所示:
<dependencies>
<!--添加eureka注册中心 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
3)配置application.yml配置文件
此处测试端口号为7000,详细配置如下:
server:
port: 7000 #定义注册中心端口
eureka:
server:
enable-self-preservation: true #设定自我保护模式 默认值为true 不建议关闭
instance:
hostname: localhost #eureka服务的实例名称
client:
register-with-eureka: false #表示注册中心 不会注册自己本身
fetch-registry: false #表示自己就是注册中心,不需要检索服务
service-url:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
4)编辑主启动类
主启动类上添加注解,开启注册中心的开关:
@EnableEurekaServer //开启注册中心服务
5)启动注册中心,检测是否搭建成功
启动注册中心,访问http://localhost:7000/,成功显示注册中心Eureka管理界面表示搭建成功。
B、配置服务的提供者端
注意:在Springcloud中,其实没有消费者和提供者之说,消费者和提供者都是客户端,因为,消费者和提供者添加的都是客户端的jar包。
1)添加jar包
在提供者的pom.xml中添加如下依赖,以支持注册中心:
<!--添加eureka 客户端地址 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
2)编辑application.yml配置文件
在已有的配置基础之上添加如下配置:
注意:
a.application属于spring的属性,应与dataSource同级;
b.application的name属性:表示多个提供者(多台服务部署)的统一名称,多台提供者的名称要一致;
c.instance-id:表示每个服务独有名称,一般以共同名称加端口组成;
示例如下:
spring:
application: #定义服务名称
name: provider-user
eureka:
client:
service-url:
defaultZone: http://localhost:7000/eureka
instance:
instance-id: provider-user-8000 #定义微服务的名称
prefer-ip-address: true #是否显示IP和端口
3)在主启动类中开启注册中心客户端服务
@EnableEurekaClient //开启客户端服务
4)启动项目检测
启动提供者项目,刷新Eureka管理界面,出现开启的服务名称即表示配置成功,如下图所示:
C、配置服务的消费者端
1)添加jar包
在消费者的pom.xml中添加如下依赖,以支持注册中心:
<!--添加eureka 客户端地址 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
(2)编辑application.yml配置文件
在已有的配置基础之上添加如下配置:
注意:
a. register-with-eureka: 表示是否将自己的信息注册到Eureka中,消费者不需要注册自己的信息,所以填false**;
b. defaultZone**:表示连接注册中心的集群(可能有多个注册中心);
示例如下:
eureka:
client:
register-with-eureka: false #不会将自己的信息注册到eureka中
service-url:
defaultZone: http://localhost:7000/eureka #链接注册中心集群
3)在主启动类中开启注册中心客户端服务
@EnableEurekaClient //开启客户端服务
4)启动项目,进行测试
启动消费者端,调用程序,看是否能调通,能调用表示配置成功。
consumer中远程访问路径:http://provider-user(统一的服务名)/path;
2、客户端负载均衡Ribbon
(1)定义
Ribbon是SpringCloud中客户端负载均衡的组件,负载均衡在客户端实现。
注意:nginx是服务端的负载均衡。
(2)服务端和客户端负载均衡对比
1)服务端负载均衡
a.如果服务端负载均衡宕机,则直接影响整个服务项目;
b.服务端负载均衡是一种集中式的相应,性能低;
2)客户端负载均衡
a.客户端负载均衡在用户发起请求之前已经分配到服务器地址,请求速度快;
b.如果客户端宕机,只影响单个客户;
(3)配置方式
1)在获取RestTemplate连接对象的配置类的创建对象的方法上添加注解:@LoadBalanced ;
表示在客户端添加负载均衡。
2)在这个类中定义方法,定义负载均衡的策略:
a. RoundRobinRule:轮巡策略;
b.RandomRule:随机策略;
c. AvailabilityFilteringRule: 首先过滤掉故障机或者并发链接数超过阈值的服务器,剩余的机器轮询配置;
d. WeightedResponseTimeRule:服务器影响时间越快,则权重越高;
c. BestAvailableRule:最大可用策略,即先过滤出故障服务器后,选择一个当前并发请求数最小的;
代码示例如下:
@Configuration
public class RestTemplateConfig {
@Bean
@LoadBalanced //开启负载均衡
public RestTemplate getTemplate() {
return new RestTemplate();
}
/**
*配置均衡策略
*/
@Bean
public IRule getIrule() {
return new RoundRobinRule();
}
}
3、声明式http客户端:Feign
(1)定义
Feign是一个声明式、模板化的Http客户端,可以简化客户端的编码,使用户直接通过接口的方式声明式的调用,内部集成了Ribbon,实现负载均。
注意:Feign是简化服务的调用,是配置在服务的消费者端或者接口模块中。
(2)作用
(3)配置方式
1)导入jar包
本例配置在接口模块中。
在接口项目:jt-springcloud-interface中导入如下jar包,引入Feign的支持:
<dependencies>
<!--引入Feign支持 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
2)定义接口
在jt-springcloud-interface项目中定义调用服务提供者的接口,接口有如下要求:
a.在接口类上添加注解:@FeignClient(value=“服务提供者的服务名称”),指定需要调用的服务的名称;
b.在接口中定义所要调用的服务中的方法,需与提供者中保持一致。
代码示例如下:
@FeignClient(value="provider-user") //指定服务名称
public interface UserService {
//获取用户json信息
@RequestMapping("/findAll")
public List<User>findAll();
@RequestMapping("saveUser")
public String saveUser(@RequestBody User user);
//获取提供者一的数据
@RequestMapping("/getMsg")
public String getMsg();
}
3)编辑消费者
在消费者中注入定义好的接口,通过接口远程调用。
代码示例如下:
@RestController
@RequestMapping("/consumer")
public class UserController {
@Autowired
private UserService userService;
//实现查询方法(这里只举一个例子,其他需自行补充)
@RequestMapping("/findAll")
public List<User> findAll(){
return userService.findAll();
}
}
注意:使用feign时,如果controller接收参数时使用了@PathVariable注解,则要写明该注解的value属性,即是:@PathVariable(value=“参数名”),否则会报IllegalStateException异常。
4)消费者主启动类中开启Feign客户端
在主启动类上添加如下注解,开启Feign客户端:
@EnableFeignClients
5)测试
4、断路器Hystrix
(1)服务扇出
1)什么是服务扇出?
多个微服务之间相互调用的时候,A调用B和C,C又要依靠调用D或其他服务,称之为服务扇出。
2)会导致的问题
多个服务相互调用,如果其中被依赖的一个服务(比如服务D)执行较慢,或者不可用,导致服务的调用者(服务C)占用大量系统资源,最终导致服务崩溃。
(2)定义及作用
问题:在分布式系统里许多依赖可能会调用失败,为了避免长时间的等待或者抛出异常,需要使用熔断机制解决。
定义及作用:Hystrix是断路器,是一个用于处理分布式系统的延时和容错的开源库。**Hystrix能够保证当服务单元发生故障后,通过短路机制,返回一个满足预期处理条件的数据,**避免服务长时间没有响应或者报错等影响,提升软件的可靠性。
通过熔断机制,可实现服务的降级。
注意:断路器机制是对后台的保护,需配置在服务的提供者端。
(3)断路器配置方式
A、普通方式
1)导入jar包
在服务的提供者端
<!--添加断路器配置 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
2)编写服务提供者端的controller中的熔断方法
a.在业务类中定义每个方法熔断后需要执行的方法;
b.在相应的业务方法上添加注解:@HystrixCommand(fallbackMethod=“方法名”),指定熔断后执行的方法名;
@RequestMapping("/findAll")
@HystrixCommand(fallbackMethod="hystrix_findAll")
public List<User>findAll(){
returnuserService.findAll();
}
public List<User>hystrix_findAll(){
List<User>userList = newArrayList<User>();
User user = newUser();
user.setId(0)
.setName("")
.setAge(0)
.setSex("");
userList.add(user);
returnuserList;
}
3)在主启动类中开启熔断机制
在服务的提供者端的主启动类中添加注解:
@EnableHystrix//开启熔断机制。
4)测试
B、接口形式
说明:一般将断路器配置到服务端,可以返回有效地数据。但是如果服务端程序宕机了,这时断路器机制不能生效。因此,可以将断路器配置到接口中。具体配置方式如下:
1)导入jar包
在接口项目jt-springcloud-interface中添加支持熔断器的依赖,如下:
<!--添加断路器配置 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
2)编辑调用接口熔断器工厂FallBackFactory
通过这个工厂,创建熔断后的接口对象,该对象重写了服务提供者的所有业务方法,当熔断后,执行重写的方法,代码如下:
注意:这个工厂对象的创建要交给Spring管理,需添加@Component注解。
@Component
public class UserServiceFallbackFactory implements FallbackFactory<UserService>{
@Override
public UserService create(Throwable cause) {
//当程序调用发生异常时采用接口熔断,此处采用匿名内部类,重写熔断后执行的方法。
return new UserService() {
@Override
public String saveUser(User user) {
return"后台服务器异常,调用熔断机制";
}
@Override
public String getMsg() {
return"后台服务器异常!!!!!";
}
@Override
public List<User>findAll() {
return new ArrayList<User>();
}
};
}
}
(3)编辑Feign的调用接口
在接口方法的调用对象上添加注解,指定熔断工厂,熔断后才能执行该工厂中的方法,代码如下:
//编辑服务名称,定义熔断器工厂
@FeignClient(value="provider-user",fallbackFactory=UserServiceFallbackFactory.class )
public interface UserService {
//获取用户json信息
@RequestMapping("/findAll")
public List<User>findAll();
}
(4)编辑消费者端的application.yml配置文件
启动熔断机制,指定超时时间,配置如下:
feign:
hystrix:
enabled: true #启动熔断器机制 !!!!!!!!!!!!!
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 3000 #设定断路器超时时间
#说明:当服务端宕机机.由客户端中的配置返回数据,节省时间开销.
5、仪表盘监控DashBoard
(1)作用
Hystrix
DahBoard实时监控Hystrix的运行情况。
注意:
1)DashBoard只能对一台服务进行监控。而实际情况中通常不止一个服务,为了方便监控,需将多个DashBoard的数据汇总在一个DashBoard中展现,需要用到工具Turbine。Turbine工具后面进行讲解。
2)DashBoard是监控熔断机制的,所以在使用监控时,要开启熔断器。
3)如果采用的是接口熔断机制,在服务端需要被监控的方法上添加@HystrixCommond注解即可。
(2)项目搭建方式
A、监控端的搭建
1)创建项目jt-springcloud-dashboard-server
2)导入jar包
<dependencies>
<!--添加断路器配置 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<!--配置hystrix监控 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
</dependencies>
3)配置application.yml配置文件
此处测试的端口号为9000:
server:
port: 9000
3)在主启动类中开启DashBoard监控
在主启动类上添加一下配置,开启Hystrix的监控:
@EnableHystrixDashboard //启动仪表盘监控程序
4)启动测试
启动项目,访问:http://localhost:9000/hystrix,出现一下界面,表示搭建成功:
B、客户端实现服务的监控
1)导入jar包
在需要监控的服务的提供者端添加如下jar包,引入达式board的支持:
<!--添加监控 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
2)编辑配置类
两种方式:
a.在主启动类添加注解:
@EnableCircuitBreaker//开启实时监控;
这种方式默认的服务当前监控页面地址如下:<br /> http://localhost:8000/actuator/hystrix.stream<br /> <br />b.在服务的提供者端,定义配置类,实现监控的拦截,代码如下(可自定义监控名称和监控路径):
@Configuration
publicclassDashboardConfig {
//定义监控的相关参数
@Bean
public ServletRegistrationBean<Servlet> getServlet(){
HystrixMetricsStreamServletstreamServlet =new HystrixMetricsStreamServlet();
ServletRegistrationBean<Servlet> registrationBean =
new ServletRegistrationBean<>(streamServlet);
registrationBean.setLoadOnStartup(1);
//设定监控路径
registrationBean.addUrlMappings("/actuator/hystrix.stream");
//设定监控的名称
registrationBean.setName("HystrixMetricsStreamServlet");
return registrationBean;
}
}
3)查看监控页面效果
打开监控首页:http://localhost:9000/hystrix
在页面搜索框输入当前服务监控路径,到达监控页面,如下:
http://localhost:8000/actuator/hystrix.stream
注意:如果页面显示为loading…,表示服务还没有被消费,调用一下服务就可以了。
4)监控页面数据表示
监控状态信息表示如下:
关键词 | 表达含义 |
---|---|
Success | 请求成功次数 |
Bad Request | 错误请求次数 |
Timeout | 超时请求次数 |
Rejected | 拒绝请求次数 |
Failure | 请求失败次数 |
Error | 失效异常数 |
6、服务端路由器Zuul
(1)定义级作用
Zuul是Netflix开源的微服务网关,Springcloud对zuul进行了整合和增强,在Springcloud中,zuul担任网关的角色,对发送到服务端的请求进行一些预处理(比如安全验证、动态路由、负载均衡等),可拦截无效的请求,实现了请求的转发和响应。<br /> **zuul的核心是一系列的filters,**其作用可以类比Servlet框架的Filter或者spring的拦截器。
(2)项目搭建方式
A、zuul网管端创建jt-zuul
1)项目创建
项目类型:Maven Project;
打包方式:jar;
注意:网关是单独的项目,不属于微服务的模块,不能创建jt-springcloud-parent的子项目。
2)导入jar包,配置pom.xml配置文件
<!--导入springBoot依赖包 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.5.RELEASE</version>
<relativePath/>
</parent>
<properties>
<java.version>1.8</java.version>
</properties>
<!--依赖管理,用于管理spring-cloud的依赖 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.SR2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<dependencies>
<!--导入springCloudjar包 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream</artifactId>
</dependency>
<!--引入springBoot jar包 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--支持热部署 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>springloaded</artifactId>
<version>1.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<!--引入springBoot监控 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--添加eureka客户端地址 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
</dependencies>
3)配置application.yml配置文件
server:
port: 9050
servlet:
context-path: /
spring:
application: #定义服务名称
name: springcloud-zuul
eureka:
client:
service-url:
defaultZone: http://localhost:7000/eureka
instance:
instance-id: springcloud-zuul-9050 #定义微服务的名称
prefer-ip-address: true #是否显示IP和端口
zuul:
#prefix: / #通过统一的公共前缀访问
#ignored-services: springcloud-user #禁止通过某个服务名访问
ignored-services: "*" #禁止通过全部服务名访问
routes:
user-service:
serviceId: consumer-user #需要服务端映射路径名称,需要映射的是服务端就写服务端服务名称,要映射的是消费者端,就写消费者端服务名称。
path: /userService/** #映射对应的url,访问需在浏览器中输入,代替服务名,再在后面追加访问路径。
4)编辑主启动类
在主启动类上添加@EnableZuulProxy注解,启动zuul:
@EnableZuulProxy //启动zuul配置
B、消费者端配置
1)编辑application.yml配置文件
开启消费者的服务,将消费者注入注册中心,配置如下:
spring:
application:#定义服务名称,如果是多个相同的服务,则名称必须相同
name: consumer-user
eureka:
client:
service-url:
defaultZone: http://localhost:7000/eureka
instance:
instance-id: consumer-user-8020 #定义微服务的名称
2)访问测试
发起请求,进行测试。
**访问路径:**localhost:9050/zuul中配置的path值(映射后的路径)/每个方法的访问路径,例如:本例中的访问路径是:localhost:9050/userService/consumer/select
7、配置中心
(1)定义及作用
配置中心是使用GitHub(使用方法见后面)统一管理配置文件。项目开发时,配置文件可以统一的进行管理,以后使用配置文件时,只需要联网从网络中动态获取配置文件信息即可。
(2)配置中心的搭建
A、配置中心端
1)创建项目jt-springcloud-config-9080
项目类型:Maven Module;
父项目:jt-parent;
打包类型:jar;
2)导入jar包
<dependencies>
<!--springcloud配置中心 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<!--eclipse中整合github中防止冲突 -->
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit</artifactId>
</dependency>
<!-- web依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- actuator完善页面监控依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
3)配置application.yml配置文件
此处测试端口号为9080,在这里定义配置中心的服务名称,以及连接远程github账户。
server:
port: 9080
spring:
application:
name: springcloud-config #定义服务的名称
cloud:
config:
server:
git:
uri: https://github.com/junping1991/student_1811.git
#连接远程github账户
4)编辑主启动类
在主启动类中添加@EnableConfigServer注解,开启配置中心设置:
@EnableConfigServer //开启配置中心设置
@SpringBootApplication
publicclassSpringCloud_Config {
publicstaticvoidmain(String[] args) {
SpringApplication.run(SpringCloud_Config.class, args);
}
}
5)上传配置文件
测试:将provider中的yml配置文件上传到远程仓库中。
B、配置中心的客户端配置
1)导入jar包
在客户端添加jar包,引入配置中心的支持:
<!--eclipse中整合github中防止冲突 -->
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit</artifactId>
</dependency>
<!--客户端配置-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
(2)配置bootstrap.yml配置文件
#bootstrap的优先级高于application.yml
#系统级别的配置(高于用户级别的配置)
#只能识别application.yml和boostrap.yml,别的名字不能识别
spring:
cloud:
config:
#springcloud-config采用的是sv(服务器客户端)的架构模式
uri: http://localhost:9080#服务器地址
name: config-client #需要从gitee上读取的资源名称
profile: dev #开发模式 test是测试模式
label: master #geitee的分支
package com.common.springcloud.controller;
/**
* 写这个controller这是为了证明客户端能通过服务端从gitee拿到数据
* 这里把数据打印出来了
* 可以不写这个controller,在bootstrap.yml和application.yml写配置就行了
*/
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ConfigClientController {
@Value("${spring.application.name}")
private String applicationName;
@Value("${eureka.client.service-url.defaultZone}")
private String eurekaServer;
@Value("${server.port}")
private String port;
@RequestMapping("/config")
public String getConfig() {
return "applicationName:"+applicationName+
"eurekaServer:"+eurekaServer+
"port:"+port;
}
}
实战测试
在任何一个模块,加入 客户端的依赖
<!-- 导入giteeg关于dept配置要用的依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
编辑bootstrap.yml配置文件
#bootstrap的优先级高于application.yml
spring:
cloud:
config:
name: eureka #加载远程配置中心文件名称
profile: dev #动态加载开发环境配置文件
label: master #获取master默认分支
uri: http://localhost:9080/
先启动 配置中心的服务端 ,就是 9080 ,然后测试 一个 数据
localhost:9080/eureka-dev.yml
最后就可以了
六、GitHub的使用
1、在GitHub官网注册账号并登陆
2、使用
(1)新建仓库
(2)远程连接GitHub,将远程仓库下载到本地
(3)使用工具上传/下载文件GitHub Desktop
1)在本次仓库中创建新的文件
2)推送文件到远程服务器
3)检查远程仓库是否有文件
八 、消息总线 SpringCloudBus
SpringCloud Bus集成了市面上常用的消息中间件(rabbit mq,kafka等),连接微服务系统中的所有的节点,当有数据变更的时候,可以通过消息代理广播通知微服务及时变更数据,例如微服务的配置更新。
SpringCloud Bus 解决了什么问题 ?
Bus组件的作用,当我们把配置文件保存在Git当中,由Git进行管理,一旦配置字段的值进行改变
不需要采用服务器重启的方式去更新配置。
解决了微服务数据变更,及时同步的问题。
刷新客户端服务
刷新服务端服务
配置服务端
(1) 修改cloud_config工程的pom.xml,引用依赖
pom.xml
<!-- 消息 总线 依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-bus</artifactId>
</dependency>
<!-- 整合 Rabbitmq 的依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream-binder-rabbit</artifactId>
</dependency>
(2)修改application.yml ,添加配置
applicaion.yml
rabbitmq:
host: 127.0.0.1
management:
endpoints:
web:
exposure:
include: bus-refresh #开放出去的端口
配置客户端
(1 ) 我们还是以(Provider)生产者模块为例,加入消息总线
<!-- 消息 总线 依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-bus</artifactId>
</dependency>
<!-- 整合 Rabbitmq 的依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream-binder-rabbit</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
在客户端也加上
rabbitmq:
host: 127.0.0.1
management:
endpoints:
web:
exposure:
include: bus-refresh #开放出去的端口
(2)在码云的配置文件中配置Mysql的连接地址:
数据库 改成 001
url: jdbc:mysql://localhost:3306/clouddb001?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true # 数据库名称 # 数据库名称
我们在 新建一个数据库 ,clouddb001
在数据库当中 加入 部门 修改部
(3)启动cloud_config 、cloud_provider和cloud_eureka 看是否正常运行
(4) 我们改完之后 码云地址之后,再次发出请求,看看
结果 肯定还是之前一样 ,
postman测试
Url: http://127.0.0.1:9100/actuator/bus-refresh
Method: post
自定义配置的读取
(1)修改码云上的配置文件,增加自定义配置
bilibili:
ip: 127.0.0.1
(2)在cloud_provider工程中新建controller
@RestController
public class TestController {
@Value("${sms.ip}")
private String ip;
@RequestMapping(value = "/ip", method = RequestMethod.GET)
public String ip() {
return ip;
}
}
(3)运行测试看是否能够读取配置信息 ,OK.
(4)修改码云上的配置文件中的自定义配置
clicli:
ip: 127.0.0.1
(5)通过postman测试
Url: http://127.0.0.1:9100/actuator/bus-refresh
Method: post
测试后观察,发现并没有更新信息
这是因为我们的 controller少了一个注解@RefreshScope 此注解用于刷新配置
@RefreshScope
@RestController
public class TestController {
@Value("${sms.ip}")
private String ip;
@RequestMapping(value = "/ip", method = RequestMethod.GET)
public String ip() {
return ip;
}
}