文章目录
学习目标
-
能够理解SpringCloud作用
- 理解SpringCloud出现的原因(全部都是对于微服务架构出现问题的解决方案)
- SpringCloud是基于SpringBoot开发的,SpringCloud整合了很多优秀的第三方微服务开源框架,用于解决各种对于的问题
-
能够使用RestTemplate发送请求
- 懂得其原理(封装了基于Rest的Http请求)
- 实现微服务与微服务之间的通信
-
能够熟练使用spring-data-jpa框架(持久层,提前透露:该框架不需要写sql语句,框架底层已经写好)
-
了解mybatis与spring-data-jpa的区别
-
能够搭建Eureka作为注册中心
- 用于管理服务、监控服务、服务路由
-
能够使用Ribbon负载均衡
- 用来实现负载均衡(实现消费方负载均衡)
-
能够使用Hystrix熔断器
- 做服务降级,防止程序发生雪崩效应
一、什么是Spring Cloud
Spring Cloud是基于Spring boot来开发的和封装的一系列集合框架的有序集合。
该集合框架可以用于解决很多问题。
如:
- spring cloud feign 是对RestTemplate的封装,用于解决远程调用的问题
- spring data jpa 是对数据库连接的封装,可以快速解决持久层连接数据库的问题
- spring cloud eureka 作为 注册中心,管理微服务的IP地址,服务端口号等配置文件
更多请看:spring官网
我们主要学习:
版本说明
SpringCloud是一系列框架组合,为了避免与框架版本产生混淆,采用新的版本命名方式,形式为大版本名+子版本名称
大版本名用伦敦地铁站名
子版本名称三种
SNAPSHOT:快照版本,尝鲜版,随时可能修改
M版本,MileStone,M1表示第一个里程碑版本,一般同时标注PRE,表示预览版
SR,Service Release,SR1表示第一个正式版本,同时标注GA(Generally Available),稳定版
小结:
微服务:根据功能拆分为不同的系统,这个系统是独立的可以完成业务功能。
Spring Cloud本身也是基于SpringBoot开发而来,SpringCloud是一系列框架的有序集合,也是把非常流行的微服务的技术整合到一起。
二、面对的问题
a. 微服务之间的通讯 怎么解决。--- dubbo , RPC ,HTTP
b. 如何解决并发量大的问题----集群
c. 过来的请求应该找哪个服务器(如果建立了集群)---nginx,dubbo负载均衡
d. 如何解决登入的问题(多个服务器,不同的服务器都需要登入,能不能只登入一次,将数据存储在session中 )
----spring session ,spring securtutyauthor2.0,cas ,shiro
e. 服务很多, 需要同一管理-------zookeeper
f. 为了防止以后报错,需要写日志,每个服务器都有日志
所以需要多日志进行管理
--elasticsearc+ logstash+kafka
g. 如何解决 多个服务一直调用,然后最下层的服务挂掉了
导致被调用的每一层都报错-----hystrix ,sentinel(哨兵),
服务降级(缓存)
Spring Cloud正是为了解决这些问题而提出来的,当然不止这些问题,一个问题对于了Spring Cloud的一个技术。使用这些技术的流程无一不是:起步依赖+注解+enablexxx
三、RestTemplate
RestTemplate是利用restTemplate去模拟restful(delete,get,post,put)在各个系统之间发送请求,进行沟通。 其底层封装了 http。
http的底层是使用 HttpClient,OkHttp,URLConnection等工具,所以真正干活的是这三种,而 spring cloud 则封装了 OKHttp(默认)
实例:
使用 Http实现微服务之前的远程调用:
作为客户端的代码:
目录结构:
pom.xml文件(引入依赖)
<parent>
<artifactId>spring-boot-starter-parent</artifactId>
<groupId>org.springframework.boot</groupId>
<version>2.1.4.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
引导类:application.java
将 RestTemplate 放入容器中,在controller层,需要用
@SpringBootApplication
public class application {
public static void main(String[] args) {
SpringApplication.run(application.class, args);
}
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
User.java
public class User {
private Integer id;
private String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
MovieController.java
模拟从服务端拿到id为2对于的User数据
@RestController
@RequestMapping("/movie")
public class MovieController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("/look")
public User look() {
//1、先使用RestTemplate 模拟浏览器发送请求给用户微服务
User user = restTemplate.getForObject("http://localhost:8081/user/2", User.class);
//2、将获取的参数封装成为pojo
//3、判断 用户信息是否正确,如果正常就可以看电影,并返回user对象
System.out.println("可以正常观看电源");
return user;
}
}
作为服务端的代码
pom.xml文件,User类与客户端相同。
创建一个application.yml配置文件
更改启动服务时的端口号,因为 默认8080已经被客户端占用
server:
port: 8081
引导类
application.java
@SpringBootApplication
public class application {
public static void main(String[] args) {
SpringApplication.run(application.class,args);
}
}
服务端的controller层
UserController.java
@RestController
@RequestMapping("/user")
public class UserController {
@GetMapping("/{id}")
public User findById(@PathVariable(name = "id") Integer id) {
//此处我们模拟从数据库中拿到id 为传过来的 user
System.out.println("================"+id);
User user = new User();
user.setId(id);
user.setName("jack");
return user;
}
}
说明:我们通过浏览器发送请求:http://localhost:8080/movie/look,浏览器给我们返回一个json类型的数据{id:2, name:jack}。
我们是发送请求给客户端,客户端的controller层接收到请求,利用依赖注入的restTemplate对象的getForObject方法给服务端发送了一个请求,服务端接收到请求之后,返回了一个User对象,客户端收到对象之后也返回了user对象。
四、spring-data-jpa(持久层框架)
优点:
直接将 实体类对象与数据库中的 对象 绑定,在底层中有sql语句,以至于我们不需要写sql语句,直接调用dao层的方法即可。
目录结构:
父pom文件(版本作用):
<!--父工程-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<!--SpringCloud包依赖版本的管理-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.SR1</version>
<type>pom</type>
<!--导入 统一版本控制-->
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
子pom.xml文件
<dependencies>
<!--jpa jar包-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!--添加 eureka 客户端依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
配置文件:
application.yml
#修改服务启动时的端口号
server:
port: 18081
#数据库连接时 需要的参数
spring:
datasource:
url: jdbc:mysql://localhost:3306/springcloud?userUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
driver-class-name: com.mysql.jdbc.Driver
username: root
password: root
#为该服务取一个名字
application:
name: user-provider
引导类
application.java
@EnableJpaRepositories//启动 jpa功能并IOC有关的类
@SpringBootApplication
public class application {
public static void main(String[] args) {
SpringApplication.run(application.class,args);
}
}