一、分布式架构
二、Spring Cloud与Spring Boot
2.1 Spring Cloud
Spring Cloud 是分布式的一站式整体解决方案,Spring Cloud为开发者提供了在分布式系统快速构建工具,使用Spring Cloud的开发者可以快速的启动服务或构建应用,同时能够快速和云平台资源进行对接
2.2 分布式系统
- 配置管理
- 服务发现
- 熔断机制
- 路由网关
- 控制总线
- 一次性token
- 全局锁
- 分布式Session
- 集群状态
- leader选举
- 微代理
? 2.3 Spring Cloud 与Spring Boot
2.4 Spring Cloud五大常用组件
- 服务发现:Netflix Eureka
- 客服端负载均衡:Netlfix Ribbon
- 熔断器:Netflix Hystrix
- 服务路由网关:Netflix Zuul
- 分布式配置:Spring Cloud Config
三、RestFul通信
使用父项目管理Spring Boot 与Spring Cloud
<!--依赖管理-->
<dependencyManagement>
<dependencies>
<!--Spring Boot依赖仲裁-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.2.5.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--Spring Cloud依赖仲裁-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.18</version>
</dependency>
<!--druid数据源-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
<!--mybaits-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.1</version>
</dependency>
<!--logback日志-->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.2.3</version>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.4</version>
</dependency>
</dependencies>
</dependencyManagement>
3.1 编写微服务
建立一个工程,编写一个测试的微服务Rest-Provider
指定端口号为8001
使用Druid数据源
导入jar
<!--web-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--Druid数据源-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
</dependency>
配置yml
#端口号
server:
port: 8001
spring:
#项目名称
application:
name: json-restful-provider-server
#数据源
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/cloud01?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true
username: root
password: root123
type: com.alibaba.druid.pool.DruidDataSource
#配置Druid相关配置
druid:
# 连接池的配置信息
# 初始化大小,最小,最大
initial-size: 5
min-idle: 5
maxActive: 20
# 配置获取连接等待超时的时间
maxWait: 60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
timeBetweenEvictionRunsMillis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
minEvictableIdleTimeMillis: 300000
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
# 打开PSCache,并且指定每个连接上PSCache的大小
poolPreparedStatements: true
maxPoolPreparedStatementPerConnectionSize: 20
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
# DruidFilterConfiguration
filter:
slf4j:
enabled: true
wall:
enabled: true
stat:
enabled: true
# 通过connectProperties属性来打开mergeSql功能;慢SQL记录
connectionProperties: druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000
# 配置DruidStatFilter
web-stat-filter:
enabled: true
url-pattern: "/*"
exclusions: "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*"
# 配置DruidStatViewServlet
stat-view-servlet:
url-pattern: "/druid/*"
# IP白名单(没有配置或者为空,则允许所有访问)
# allow: 127.0.0.1,192.168.46.120
# IP黑名单 (存在共同时,deny优先于allow)
# deny: 192.168.46.121
# 禁用HTML页面上的“Reset All”功能
reset-enable: false
# 登录名
login-username: admin
# 登录密码
login-password: 123456
#mybaits配置
mybatis:
type-aliases-package: com.json.springcloud.pojo
编写dao层
@Repository("studentMapper")
@Mapper
public interface StudentMapper {
@Select("select * from `student`")
List<Student> queryAllStudent();
@Delete("delete from `student` where `id` = #{id}")
int deleteStudentById(int id);
@Update("update `student` set `name` = #{name}, `age` = #{age} where `id` = #{id}")
int updateStudentById(Student student);
@Select("select * from `student` where `id` = #{id}")
Student queryStudentById(Integer id);
@Insert("insert into `student`(`name`, `age`) values (#{name}, #{age})")
int addStudent(Student student);
}
编写service层
//接口
public interface StudentService {
List<Student> queryAllStudent();
Student queryStudentById(Integer id);
int addStudent(Student student);
int deleteStudentById(int id);
int updateStudentById(Student student);
}
//实现
@Service("studentService")
@Transactional
public class StudentServiceImpl implements StudentService {
@Autowired
private StudentMapper studentMapper ;
public List<Student> queryAllStudent() {
return studentMapper.queryAllStudent();
}
public Student queryStudentById(Integer id) {
return studentMapper.queryStudentById(id);
}
public int addStudent(Student student) {
return studentMapper.addStudent(student);
}
public int deleteStudentById(int id) {
return studentMapper.deleteStudentById(id);
}
public int updateStudentById(Student student) {
return studentMapper.updateStudentById(student);
}
}
编写controller
@RestController
public class StudentController {
@Autowired
private StudentService studentService ;
@GetMapping("/queryAll")
public List<Student> queryAll(){
return studentService.queryAllStudent();
}
@GetMapping("/queryOne/{id}")
public Student queryOne(@PathVariable("id")Integer id){
return studentService.queryStudentById(id);
}
@PostMapping("/addStudent")
public String addStudent(@RequestBody Student student){
return studentService.addStudent(student)>=0? "success": "fail";
}
@PutMapping("/updateById")
public String upStudent(@RequestBody Student student){
return studentService.updateStudentById(student)>=0? "success": "fail";
}
@DeleteMapping("/deleteById/{id}")
public void deleteStudentById(@PathVariable("id")Integer id){
studentService.deleteStudentById(id);
}
}
注意:测试的是使用基于HTTP的RestFul远程调用,应该是使用另一个工程调用该工程中Controller的接口
由于基于RestFul风格,增删改查明确使用,分别对应:
- GetMapping:查
- PostMapping:增
- PutMapping:改
- DeleteMapping:删
如此,在地址栏访问PostMapping,PutMapping,DeleteMapping会报错
3.2 服务调用
远程调用微服务的方法有多种:
- 基于RPC
- Dubbo
- 基于HTTP
- HttpClient
- OkHttp
- RestTemplate
Spring Cloud是基于HTTP的RestFul风格的通信,所以使用的是RestTemple
建立一个工程,编写一个测试的服务Rest-Consumer
指定端口号为8080
该服务调用上述的微服务
导入jar
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
向容器注入RestTemple
@Configuration
public class BeanConfig {
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
编写Controller
@RestController
@RequestMapping("/rest")
public class StudentController {
@Autowired
private RestTemplate rt ;
private static final String PROVIDER_URL = "http://localhost:8001";
@RequestMapping("/queryAll")
public List queryAll(){
return rt.getForObject(PROVIDER_URL + "/queryAll", List.class);
}
@RequestMapping(