1、单体应用与微服务
1.1、单体应用
1.1.1、什么的单体应用
项目所有的资源都在一个应用中,打包成一个war包,使用一个tomcat去运行,运行在一个进程中
1.1.2、单体应用的问题
- 一个模块挂了,整个项目都受影响
- 单个tomcat更能处理的并发有限,可以做集群,但是不方便局部(某一个模块)扩展
- 维护/开发/升级比较麻烦
- 代码臃肿,编译,打包都比较慢
- 技术选型单一
- 数据库选型单一
1.2、微服务架构
1.2.1、什么是微服务架构
微服务就是把一个大的系统,拆分成多个小的服务,每个微服务只专注一个业务 ,每个服务有各自的进程, 微服务之间使用网络通信协议进行数据交互(通常是基于HTTP的RESTful API)。
1.2.2、微服务的特点
- 数据库选型多样化
- 技术选型多样化
- 每个微服务专注一个业务
- 每个维护有自己的进程
- 微服务之间通过网络协议进行通信
- 方便做局部拓展
- 开发/维护/升级更方便
1.2.3、微服务缺点
- 成本高
- 技术要求比较高
- 部署麻烦
1.3、spring cloud
1.3.1、简介
Spring cloud是一个基于Spring Boot实现的服务治理工具包,用于微服务架构中管理和协调服务的。
1.3.2、主要组件
- 服务注册发现——Netflix Eureka : 帮我们服务的通信地址的
- 客服端负载均衡——Netflix Ribbon\Feign :解决网络通信的
- 断路器——Netflix Hystrix :解决微服务故障的
- 服务网关——Netflix Zuul :微服务的大门(安保部门)
- 分布式配置——Spring Cloud Config :统一管理微服务的配置
1.3.3、SpringCloud和Dubbo的区别
- dubbo是rpc框架
- SpringCloud是一系列微服务解决方案
- dubbo基于tcp
- SpringCloud基于http
- dubbo在通信方面的性能高于SpringCloud
1.3.4、Spring Cloud框架特点
- 约定优于配置
- 适用于各种环境,开发、部署在PC Servler 或各种云环境
- 隐藏了组件的复杂性,并提供声明式、无xml的配置方式
- 开箱即用,快速启动
- 轻量级组件。Spring Cloud整合的组件大多比较轻量,例如Eureka,Zuul等等,都是各自领域轻量级的实现
- 组件丰富,功能齐全。
- 选型中立、丰富。支持Eureka,Zookeeper和Consul实现的服务发现。
2、Spring Cloud入门
2.1、注册中心原理
2.2、搭建注册中心
2.2.1、创建多模块工程
2.2.2、springcould-parent管理依赖
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<spring-cloud.version>Finchley.SR1</spring-cloud.version>
<springboot.version>2.0.5.RELEASE</springboot.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</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>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${springboot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
2.2.3、springcloud-eureka-server-3000导入依赖
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
2.2.4、主配置类EnrekaServerApplication_3000
@SpringBootApplication
//开启注册中心
@EnableEurekaServer
public class EnrekaServerApplication_3000 {
public static void main(String[] args) {
SpringApplication.run(EnrekaServerApplication_3000.class);
}
2.2.5、配置文件application.yml
server:
port: 3000
eureka:
instance:
hostname: localhost
client:
registerWithEureka: false #是否要注册到eureka
fetchRegistry: false #表示是否从Eureka Server获取注册信息
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #单机配置
2.2.6、启动
2.3、搭建订单服务springcloud-produce-user-server-1000
2.3.1、导入依赖
<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>
</dependencies>
2.3.2、主配置类UserProviderApplication_1000
@SpringBootApplication
public class UserProviderApplication_1000 {
public static void main(String[] args) {
SpringApplication.run(UserProviderApplication_1000.class);
}
}
2.3.3、配置文件application.yml
eureka:
client:
serviceUrl:
#注册中心服务端的注册地址
defaultZone: http://localhost:3000/eureka/
instance:
prefer-ip-address: true#使用ip地址注册
instance-id: user-server:1000 #服务注册到注册中心的id
server:
port: 1000
#应用的名字
spring:
application:
name: user-server
2.3.4、启动
在注册中心可以看到启动的提供者
2.4、搭建消费者服务springcloud-consumer-pay-server-2000
步骤与上面一样
2.5、订单服务和用户服务完成通信
2.5.1 搭建公共的用户模块springcloud-user-common
因为用户在用户服务和订单服务中都有,以后可能不仅仅这两个服务中有用户,所以将这种多次使用的类型,通过公共的模块,减少代码的冗余,直接将使用的微服务模块依赖于公共的模块。
为了演示,创建一个domain,User类
2.5.2 user-server提供者服务编写接口
1.依赖公共模块
<dependency>
<groupId>com.vivi</groupId>
<artifactId>springcloud-user-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
2.创建web.controller
@RestController
public class UserController {
@GetMapping(value = "/user/{id}")
public User getUser(@PathVariable("id") Long id){
User user = new User();
user.setName("调用成功");
user.setId(id);
user.setSex(1);
return user;
}
}
2.5.3 pay-server提供者服务编写接口
1.依赖公共模块
<dependency>
<groupId>com.vivi</groupId>
<artifactId>springcloud-user-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
2.定义RestTemplate的bean
/**
* SpringMvc提供的一个基于Rest风格的http调用工具
* @return
*/
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
3.创建web.controller
这里的url,也可以写String url = “http://localhost:1000/user/”+id;
@RestController
public class PayController {
@Autowired
private RestTemplate restTemplate;
@GetMapping(value = "/pay/user/{id}",produces = "application/json")
@HystrixCommand(fallbackMethod = "payFallback")
public User pay(@PathVariable("id") Long id) {
String url = "http://user-server/user/"+id;
User user = restTemplate.getForObject(url, User.class);
return user;
}
}
结果如下图: