为什么学习微服务架构?学习微服务架构需要那些技术储备?
1、在我们刚接触的项目当中大部分都是单体架构(除了一线互联网公司),单体结构的特点就是以满足业务需求是第一位,技术实现其次所以业务量不是跟大比如一些公司的内部使用系统。设想如果用户量、业务量很大呢单体架构很难支撑,所以我们要采用微服务架构解决高并发的问题。
2、技术储备首先要学习Spring Boot框架(可查看我的文章SpringBoot篇),因为Spring Cloud架构是在Spring Boot就框架的基础上进行开发和搭建,也可以理解为多个Spring Boot项目放在一起就是一个分布式Spring Cloud项目
提示:以下是本篇文章正文内容,下面案例可供参考
其实Spring Cloud是在Spring Boot基础上构建的,用于快速构建分布式系统的通用模式的工具集。
他的特点:约定优于配置。
组件丰富,功能齐全。SpringCloud为微服务。列如Euerk架构提供了非常完整的支持。列如配置管理、服务发现、断路器、微服务网关等。
1、服务注册发现
2、远程服务调用
3、负载均衡
4、断路器
5、分布式消息
6、配置中心
7、链路监控
所以, spring cloud 提 供 了 一 些 解 决 这 类 问 题 的 工 具 。
比 如 服 务 注 册 提 供 了Eureka/Consoul/zookeeper;
远程调用基于 RestTemplate 针对 http 协议调用的封装;
负载均衡采用 Ribbon、断路器采用 hystrix;
分布式消息基于 kafka、rabbitMQ;
配置中心基于config;
链路监控基于 sleuth.
pom.xml添加依赖
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
项目工程目录结构图
1.1、创建启动类EurekaApp,如果是SpringBoot项目构建时会生成,也可自己创建。
注意@SpringBootApplication(含义:这是SpringBoot项目的启动器) @EnableEurekaServer(含 义:这是网关服务的服务service)
代码如下(示例):
@SpringBootApplication
@EnableEurekaServer
public class EurekaApp {
public static void main(String[] args) {
SpringApplication.run(EurekaApp.class,args);
}
}
1.2、配置文件在resource文件夹下创建application.yml配置文件,配置如下。
server:
port: 10000 #端口号
spring:
application:
name: eurekaapp #服务名
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10000/eureka
register-with-eureka: false #不注册自己,列表当中看不到自己
fetch-registry: false #不注册自己
pom.xml添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.1.1</version>
</dependency>
<!-- mysql驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<!--添加jsp的依赖-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
<!--添加mysql数据库-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
</dependencies>
项目工程目录结构图
2.1、创建启动类ShengApp ,如果是SpringBoot项目构建时会生成,也可自己创建。
注意@SpringBootApplication(含义:这是SpringBoot项目的启动器) @EnableEurekaClient(含 义:我方作为客户端向网关服务注册自己)
@SpringBootApplication(exclude={DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
@EnableEurekaClient
public class ShengApp {
public static void main(String[] args) {
SpringApplication.run(ShengApp.class ,args);
}
2.2、配置文件在resource文件夹下创建application.yml配置文件,配置如下。
spring:
application:
name: shengchanzhe #服务名称
datasource:
username: root ##数据库用户,改成自己的
password: root ##数据库密码,改成自己的
url: jdbc:mysql://localhost:MySql/MySql?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC
driver-class-name: com.mysql.jdbc.Driver
server:
port: 8083 #服端口号
eureka:
client:
service-url: # EurekaServer地址
defaultZone: http://127.0.0.1:10000/eureka
instance:
prefer-ip-address: true # 当调用getHostname获取实例的,返回ip而不是host名称
ip-address: 127.0.0.1 # 指定自己的ip信息,不指定的话会自己寻找
2.3项目访问Controller层请求url
@RestController
public class HelloController {
@Autowired
private IgoodsQuery igoodsQuery;
@GetMapping("/hello")
public String hellow(){
return "hello world!!!8087第一个服务器";
}
}
pom.xml添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-feign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
项目工程目录结构图
3.1、创建启动类XiaoApp,如果是SpringBoot项目构建时会生成,也可自己创建。
注意@SpringBootApplication(含义:这是SpringBoot项目的启动器) @EnableEurekaClient(含义:我方作为客户端向网关服务注册自己)
@EnableFeignClients(含义:使用Feign方式进行服务之间的通信)
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class XiaoApp {
public static void main(String[] args) {
SpringApplication.run(XiaoApp.class ,args);
}
}
3.2、配置文件在resource文件夹下创建application.yml配置文件,配置如下。
spring:
application:
name: xiaofeizhe #服务名称
server:
port: 8082 #端口号
eureka:
client:
service-url: # EurekaServer地址
defaultZone: http://127.0.0.1:10000/eureka
instance:
prefer-ip-address: true # 当调用getHostname获取实例的,返回ip而不是host名称
ip-address: 127.0.0.1 # 指定自己的ip信息,不指定的话会自己寻找
3.3编写消费者服务-------->调用消息生产者服务Controller层
@RestController
public class HelloController {
@Autowired
HelloService helloService; //注入依赖
@GetMapping("/xhello")
public String hello(){
return helloService.hello();
}
}
3.4编写消费者服务-------->调用消息生产者服务Service层
@Service
public class HelloService {
@Autowired
IHelloFeign helloDao;
public String hello(){
return helloDao.hello();
}
}
3.5编写消费者服务-------->调用消息生产者服务dao(数据持久)层
@FeignClient注解实现被调用方的服务注入
//更优雅、灵活、方便的调用服务
@FeignClient("SHENGCHANZHE") #我们调用消费者的服务名称
public interface IHelloFeign {
@GetMapping("/hello")
public String hello();
@GetMapping("/goodsQuery")
public String queryGoodsController();
}
3.6其中3.5章节FeignClient请求方式只是服务之间通信一种,另为一种为RestTemplate方式,要创建一个配置类
@Configuration //表示这是一个配置类,项目启东时就加载
public class ljqConfig {
@Bean //交给Bean管理
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
如果采用RestTemplate方式最为服务之间的通信,那么3.5章节的请求方式修改如下:
@Repository
public class HelloDao {
@Autowired
RestTemplate restTemplate; //注入依赖
/**
* 生产者服务的请求路径 http://SHENGCHANZHE/hello
*/
public String hello(){
return restTemplate.getForObject("http://SHENGCHANZHE/hello",String.class);
}
}
pom.xml添加依赖
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-netflix-zuul -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
项目工程目录结构图
4.1、创建启动类ZuulApp,如果是SpringBoot项目构建时会生成,也可自己创建。
注意@SpringBootApplication(含义:这是SpringBoot项目的启动器) @EnableEurekaClient(含义:我方作为客户端向网关服务注册自己)
@EnableZuulProxy(含义:这是Zull网关服务)
@SpringBootApplication
@EnableEurekaClient
@EnableZuulProxy
public class ZuulApp {
public static void main(String[] args) {
SpringApplication.run(ZuulApp.class , args);
}
}
4.2、配置文件在resource文件夹下创建application.yml配置文件,配置如下。
spring:
application:
name: zuulserver ##服务名称
server:
port: 10088 ##端口号
eureka:
client:
service-url: # EurekaServer地址
defaultZone: http://127.0.0.1:10000/eureka
instance:
prefer-ip-address: true # 当调用getHostname获取实例的,返回ip而不是host名称
ip-address: 127.0.0.1 # 指定自己的ip信息,不指定的话会自己寻找
#instance-id: zuul.com
zuul:
#ignored-services:
prefix: /api #请求前缀
routes:
SHENGCHANZHE: /aa/** #通过http://localhost:10088/api/aa/hello
XIAOFEIZHE: /bb/** #通过http://localhost:10088/api/bb/xhello访问
4个服务已经启动
点击Euerka服务端口号,可进入注册列表,可以看见zull、生产者、消费者服务都已经实现注册。
点击http://localhost:10088/api/aa/hello,就可以实现服务的调用
1、要想引入组件Ribbon,客户端负载均衡技术,服务之间访问要使用RestTemplate方式实现。
2、Hystrix,客户端容错保护,特性有服务降级、服务熔断、请求缓存、请求合并、依赖隔离。可在生产者服务的Controler,实现通过回调函数方式实现降级、熔断。
3、Feign,声明式服务调用,本质上就是 Ribbon+Hystrix
4、Stream,消息驱动,有 Sink、Source、Processor 三种通道,特性有订阅发布、消费组、消息分区。
5、Bus,消息总线,配合 Config 仓库修改的一种 Stream 实现,
6、Sleuth,分布式服务追踪,需要搞清楚 TraceID 和 SpanID 以及抽样,如何与 ELK 整合。
备注:SpringCloud组件,以及版本号要对应上,否则会出现版本不一致的情况
1、项目当中要是想根据技术选型实现业务需求,在项目总结构当中根据以上步骤创建服务项即可(组件说明见上边图片Component)
2、结合下面这个图来看,能够清晰每个组件是干什么用的
提示:当然这只是阐述一下微服务项目开发的一个基本的流程,一个微服务的项目服务会有跟多,可以引用相关组件来实现业务需求,但是如果服务比较多接口定义一定要规范并且要汇总接口调用基线,否则后期维护起来还是挺耗时间的、麻烦也比较多。