1)单体架构
所有功能集中在一个项目中开发,打成一个包部署。
2)分布式架构
将不同的功能进行拆分,每个功能作为不同的独立项目进行开发,称为一个服务。
3)微服务
微服务是一种经过良好架构设计的分布式架构方案,微服务架构特征:
注意:微服务架构也是分布式架构,微服务拆的更彻底,更细粒度 ,去中心化
在SpringCloud还未出现之际,蚂蚁金服内部就已经有了一套比较完整的金融级分布式架构Sofa
1)Sofa
Sofa将应用系统拆分为多个模块(bundle),各个模块之间各司其职,负责独立的业务,模块之间通过JVM/RPC接口调用。
2)SpringCloud
SpringCloud将应用系统拆分为多个微服务,模块之间通过RPC/HTTP方式进行调用。
<?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.0</modelVersion>
<groupId>com.lmlsj</groupId>
<artifactId>lmspringcloud</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>eurekaserver</module>
<module>ServiceProvider</module>
<module>entityclass</module>
<module>serviceconsumer</module>
<module>gateway</module>
</modules>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.2.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--统一添加依赖-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
<scope>provided</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.SR3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
(1)pom文件
(2)配置文件
server:
port: 8761
eureka:
client:
register-with-eureka: false
fetch-registry: false
service-url:
defaultZone: http://localhost:8761/eureka/
(3)创建启动类
(4)启动查看注册中心
(1)基础配置
启动后注册到注册中心去
(2)单独创建一个student服务实例
(3)完善服务提供者内容
StudentRepositoryImpl.java
@Repository
public class StudentRepositoryImpl implements StudentRepository {
private static Map<Long,Student> studentMap;
//暂时在这里初始化student
static {
studentMap = new HashMap<>();
studentMap.put(1L,new Student(1L,"add",20));
studentMap.put(2L,new Student(2L,"delete",22));
studentMap.put(3L,new Student(3L,"update",24));
studentMap.put(4L,new Student(4L,"search",20));
}
@Override
public Collection<Student> findAll() {
return studentMap.values();
}
@Override
public Student findById(long id) {
return studentMap.get(id);
}
@Override
public void saveOrUpdate(Student student) {
studentMap.put(student.getId(),student);
}
@Override
public void deleteById(long id) {
studentMap.remove(id);
}
}
StudentHandler.java
@RestController
@RequestMapping(value = "/stu")
public class StudentHandler {
@Autowired
private StudentRepository studentRepository;
@GetMapping("/list")
public Collection<Student> findAll(){
return studentRepository.findAll();
}
@GetMapping("/findById/{id}")
public Student findById(@PathVariable("id") long id){
return studentRepository.findById(id);
}
@PostMapping("/save")
public void save(@RequestBody Student student){
studentRepository.saveOrUpdate(student);
}
@GetMapping("/update")
public void update(@RequestBody Student student){
studentRepository.saveOrUpdate(student);
}
@GetMapping("/deleteById/{id}")
public void deleteById(@PathVariable("id") long id){
studentRepository.deleteById(id);
}
}
(3)运行访问
(1)基础配置
(2)消费类
@RestController
@RequestMapping("/stuconsumer")
public class StuConsumerHandler {
@Autowired
private RestTemplate restTemplate;
@GetMapping("/findAll")
public Collection<Student> findAll(){
return restTemplate.getForObject("http://localhost:8010/stu/list",Collection.class);
}
@GetMapping("/findAll2")
public Collection<Student> findAll2(){
return restTemplate.getForEntity("http://localhost:8010/stu/list",Collection.class).getBody();
}
@GetMapping("/findById/{id}")
public Student findById(@PathVariable("id") long id){
return restTemplate.getForEntity("http://localhost:8010/stu/findById/{id}",Student.class,id).getBody();
}
@GetMapping("/findById2/{id}")
public Student findById2(@PathVariable("id") long id){
return restTemplate.getForObject("http://localhost:8010/stu/findById/{id}",Student.class,id);
}
@PostMapping("/save")
public void save(@RequestBody Student student){
restTemplate.postForEntity("http://localhost:8010/stu/save",student,null).getBody();
}
@PostMapping("/save2")
public void save2(@RequestBody Student student){
restTemplate.postForObject("http://localhost:8010/stu/save",student,null);
}
}
(3)运行测试
1)POM文件
<?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">
<parent>
<artifactId>lmspringcloud</artifactId>
<groupId>com.lmlsj</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>gateway</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<version>2.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
<version>2.0.2.RELEASE</version>
</dependency>
</dependencies>
</project>
2)配置文件
server:
port: 8088
spring:
application:
name: CloudGateway
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
zuul:
routes:
StuProivder: /api/p/**
3)启动文件
4)结果
Spring Cloud Ribbon 是一套基于 Netflix Ribbon 实现的客户端负载均衡和服务调用工具。
1)基本配置
2)启动类
3)测试
(1)服务提供类新增一个方法
(2)创建两个启动类
分别修改port为不同的端口启动
(3)ribbon负载均衡测试
Feign是声明式的web service客户端,整合了Ribbon和Hystrix。
在使用Ribbon + RestTemplate时,利用RestTemplate对Http请求的封装处理,形成了一套模板化的调用方法。Feign在此基础上做了进一步的封装,简化此类操作。