单体应用架构比较容易部署、测试、在项目的初期,单体应用可以很好的运行,但是需求的增加,代码库的增长出现很多问题
- 复杂性高,模块太多,便捷模糊、依赖关系不清晰、代码质量参差不齐、修改容易带来隐含缺陷
- 技术债务,时间推移、人员更迭、不坏不修,一修就出问题
- 部署频率低,代码量多,构建和部署时间长。全量部署耗时间、影响范围大、风险高。
- 可靠性差,某个BUG可能导致整个系统瘫痪
- 扩展能力受限,单体应用作为一个整体进行扩展,无法根据业务模块的需要进行伸缩。
- 阻碍技术创新,每个成员都使用相同的语言和框架
什么是微服务架构?
微服务架构风格是一种将单一应用程序开发为一组小型服务的方法,每个服务运行在自己的进程中,服务间通信采用轻量级通信机制(通常用HTTP资源API)。这些服务围绕业务能力构建并且可通过全自动部署机制独立部署。这些服务共用一个最小型的集中式的管理,服务可用不同的语言开发,使用不同的存储技术
- 每个服务可以运行在自己的进程里
- 一系列独立运行的微服务共同构建起整个系统
- 每个服务为独立的开发业务,一个微服务只关注某个特定的功能
- 微服务之间通过一些轻量的通信机制进行通信,列如RESTful API
- 可以使用不同的语言和存储技术
- 全自动部署机制

微服务架构的优点
- 易于开发和维护
- 单个微服务启动较快
- 局部修改容易部署
- 技术栈不受限
- 按需伸缩
面临的挑战
- 运维要求高
- 分布式固有的复杂性
- 接口调整成本高
- 重复劳动
微服务设计原则
- 单一职责原则
- 服务自治原则
- 轻量级通信机制
- 微服务粒度
微服务开发框架——Spring Cloud
springcloud的特点
- 约定优于配置
- 适用于各种环境
- 隐藏了组件的复杂性
- 开箱即用
- 轻量级的组件
- 组件丰富,功能齐全
- 选型中立、丰富,
- 灵活,开发人员可按需灵活挑选技术选型
简单的实战微服务
第一步、编写服务提供者
使用spring data jpa做持久层,H2作为数据库
ArtifactId:microservice-simple-provider-user
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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<!--pom文件遵循的maven的哪个版本-->
<modelVersion>4.0.0</modelVersion>
<!--引入spring boot 依赖-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.guxilong</groupId>
<artifactId>microservice-simple-provider-user</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>microservice-simple-provider-user</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!--自动天家tomcat.springmvc的依赖自动配置-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--dao层框架-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!--h2内存数据库-->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<!--测试类依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
</dependencies>
<!--引入spring cloud依赖-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Edgware.RELEASE</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>
</build>
</project>
在classpath下建schema.sql
drop table user if exists;
create table user (
id bigint generated by default as identity,
username varchar(40),
name varchar(20),
age int(3),
balance decimal(10,2),
primary key (id));
data.sql
insert into user (id, username, name, age, balance) values (1, 'account1', '张三', 20, 100.00);
insert into user (id, username, name, age, balance) values (2, 'account2', '李四', 28, 180.00);
insert into user (id, username, name, age, balance) values (3, 'account3', '王五', 32, 280.00);
Entry类
package com.guxilong.entity;
import java.math.BigDecimal;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column
private String username;
@Column
private String name;
@Column
private Integer age;
@Column
private BigDecimal balance;
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public String getUsername() {
return this.username;
}
public void setUsername(String username) {
this.username = username;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return this.age;
}
public void setAge(Integer age) {
this.age = age;
}
public BigDecimal getBalance() {
return this.balance;
}
public void setBalance(BigDecimal balance) {
this.balance = balance;
}
}
dao层
package com.guxilong.dao;
import com.guxilong.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
}
controller层
package com.guxilong.controller;
import com.guxilong.dao.UserRepository;
import com.guxilong.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserController {
@Autowired
private UserRepository userRepository;
@GetMapping("/{id}")
public User findById(@PathVariable Long id) {
User findOne = this.userRepository.findById(id).orElse(null);
return findOne;
}
}
yml文件
server:
port: 8000
spring:
jpa:
generate-ddl: false
show-sql: true
hibernate:
ddl-auto: none
datasource: # 指定数据源
platform: h2 # 指定数据源类型
schema: classpath:schema.sql # 指定h2数据库的建表脚本
data: classpath:data.sql # 指定h2数据库的数据脚本
logging: # 配置日志级别,让hibernate打印出执行的SQL
level:
root: INFO
org.hibernate: INFO
org.hibernate.type.descriptor.sql.BasicBinder: TRACE
org.hibernate.type.descriptor.sql.BasicExtractor: TRACE
## INFO
info:
app:
name: @project.artifactId@
encoding: @project.build.sourceEncoding@
java:
source: @java.version@
target: @java.version@
management:
security:
enabled: false

第二步、编写服务消费者
ArtifactId:microservice-simple-consumer-movie
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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.guxilong</groupId>
<artifactId>microservice-simple-consumer-movie</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>microservice-simple-consumer-movie</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!--自动天家tomcat.springmvc的依赖自动配置-->
<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>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<!--引入spring cloud依赖-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Edgware.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
实体类pojo
package com.guxilong.entity;
import java.math.BigDecimal;
public class User {
private Long id;
private String username;
private String name;
private Integer age;
private BigDecimal balance;
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public String getUsername() {
return this.username;
}
public void setUsername(String username) {
this.username = username;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return this.age;
}
public void setAge(Integer age) {
this.age = age;
}
public BigDecimal getBalance() {
return this.balance;
}
public void setBalance(BigDecimal balance) {
this.balance = balance;
}
}
启动类
package com.guxilong;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
public class MicroserviceSimpleConsumerMovieApplication {
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(MicroserviceSimpleConsumerMovieApplication.class, args);
}
}
@Bean是一个方法注解,作用是实例化一个Bean并使用该方法的名称命名。在本例中,添加@Bean注解的restTemplate方法,等价于RestTmeplate restTemplate = new RestTmeplate ();
创建controller
package com.guxilong.controller;
import com.guxilong.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
/**
* Created by gu_xi on 2019/11/14.
*/
@RestController
public class MovieController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("/user/{id}")
public User findById(@PathVariable Long id) {
return restTemplate.getForObject("http://localhost:8000/" + id, User.class);
}
}
application.yml
server:
port: 8010
结果
{"id":1,"username":"account1","name":"张三","age":20,"balance":100.00}
本文探讨了单体应用架构的局限性和微服务架构的优势,包括独立开发、部署和服务自治原则。通过Spring Cloud实现微服务架构,展示了如何构建服务提供者和消费者,涉及实体类、DAO层、Controller层及YAML配置。

1494

被折叠的 条评论
为什么被折叠?



