目录
- SpringCloud简介
- SpringCloud的场景模拟
- 创建父工程
- 创建服务提供者
- 创建服务调用者
- 发现问题
SpringCloud简介
- SpringCloud是Spring旗下的项目之一,官网地址:http://projects.spring.io/spring-cloud/Spring最擅长的就是集成,把世界上最好的框架拿过来,集成到自己的项目中。
- SpringCloud也是一样,它将现在非常流行的一些技术整合到一起,实现了诸如:配置管理,服务发现,智能路由,负载均衡,熔断器,控制总线,集群状态等等功能。其主要涉及的组件包括:
- Eureka:注册中心
- Zuul:服务网关
- Ribbon:负载均衡
- Feign:服务调用
- Hystix:熔断器
- SpringCloud的版本命名比较特殊,因为它不是一个组件,而是许多组件的集合,它的命名是以A到Z的为首字母的一些单词组成:
SpringCloud的场景模拟
创建父工程
- 创建一个新的工程
- 填写信息,然后核对,没有问题就一直next
- 创建成功后在pom.xml文件中配置
<?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.lwb</groupId>
<artifactId>cloud_demo</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.4.RELEASE</version>
<relativePath/>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Finchley.SR1</spring-cloud.version>
<mapper.starter.version>2.0.3</mapper.starter.version>
<mysql.version>5.1.32</mysql.version>
<pageHelper.starter.version>1.2.5</pageHelper.starter.version>
</properties>
<dependencyManagement>
<dependencies>
<!--springCloud-->
<dependency>
<groupId>org.springfamework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--通用Mapper启动器-->
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
<version>${mapper.starter.version}</version>
</dependency>
<!--分页助手-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>${pageHelper.starter.version}}</version>
</dependency>
<!--mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}}</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
创建服务提供者
- 对外提供一个查询服务
- 点击父工程,右键,选择new module,创建子工程
- 点击next,填写子工程名称
- 点击next,查看路径是否正确,看一看子工程是否在父工程下面
- 点击finish
- pom.xml文件中编写依赖
<?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>cloud_demo</artifactId>
<groupId>com.lwb</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>userservice</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
</dependencies>
</project>
- 在resource下创建springboot的配置文件application.yml
server:
port: 8081
spring:
datasource:
url: jdbc:mysql://localhost:3306/class
username: root
password: 123456
hikari:
maximum-pool-size: 20
minimum-idle: 10
mybatis:
type-aliases-package: com.lwb.userservice.domain
- 在java文件下配置启动类
@SpringBootApplication
@MapperScan("com.lwb.userservice.mapper")//扫描指定包中的接口
public class UserApplication {
public static void main(String[] args) {
SpringApplication.run(UserApplication.class);
}
}
- 并且将配置和启动类中的包创建出来
- 创建实体类
@Table(name = "user")
public class User implements Serializable{
@Id
private String id;
private String name;
private String password;
private String email;
private String telephone;
private Integer root;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getTelephone() {
return telephone;
}
public void setTelephone(String telephone) {
this.telephone = telephone;
}
public Integer getRoot() {
return root;
}
public void setRoot(Integer root) {
this.root = root;
}
@Override
public String toString() {
return "User{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
", password='" + password + '\'' +
", email='" + email + '\'' +
", telephone='" + telephone + '\'' +
", root=" + root +
'}';
}
}
- 创建UserMapper接口(内置了增删改查的接口)
@org.apache.ibatis.annotations.Mapper
public interface UserMapper extends Mapper<User>{
}
- 创建service对象
@Service
public class UserService {
@Autowired
public UserMapper userMapper;
public User findById(String id){
return userMapper.selectByPrimaryKey(id);
}
}
- 创建Controller对象
//如果在Controller添加了@RestController注解,那么Controller层的方法中无法重定向到jsp或者html页面,其返回的内容就是自定义的内容。
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/{id}")
public User findById(@PathVariable("id")String id){
return userService.findById(id);
}
}
- 启动测试
创建服务调用者
- 创建工作与上述差不多
- pom.xml的配置,因为是调用,所以只需要注入web依赖
<?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>cloud_demo</artifactId>
<groupId>com.lwb</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>consumer</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>
- 创建启动类
@SpringBootApplication
public class ConsumeApplication {
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(ConsumeApplication.class);
}
}
- 创建实体类
public class User implements Serializable{
private String id;
private String name;
private String password;
private String email;
private String telephone;
private Integer root;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getTelephone() {
return telephone;
}
public void setTelephone(String telephone) {
this.telephone = telephone;
}
public Integer getRoot() {
return root;
}
public void setRoot(Integer root) {
this.root = root;
}
@Override
public String toString() {
return "User{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
", password='" + password + '\'' +
", email='" + email + '\'' +
", telephone='" + telephone + '\'' +
", root=" + root +
'}';
}
}
- 创建controller对象远程调用userservice
@RestController
@RequestMapping("/consumer")
public class ConsumerController {
@Autowired
private RestTemplate restTemplate;
@RequestMapping("{id}")
public User findById(@PathVariable("id")String id){
String url = "http://localhost:8081/user"+id;
User user = restTemplate.getForObject(url,User.class);
return user;
}
}
- 启动测试
发现问题
- 回顾一下,刚才的流程:
- use-service-demo:一个提供根据id查询用户的微服务
- consumer-demo:一个服务调用者,通过RestTemplate远程调用user-service-demo
- 发现存在一些问题
- 在consumer中,我们把url地址硬编码到了代码中,不方便后期维护
- consumer需要记忆user-service的地址,如果出现变更,可能得不到通知,地址将失效
- consumer不清楚user-service的状态,服务宕机也不知道
- user-service只有1台服务,不具备高可用性
- 即便user-service形成集群,consumer还需自己实现负载均衡
- 将问题整合,主要分为以下几类
- 服务管理
- 如何自动注册和发现
- 如何实现状态监管
- 如何实现动态路由
- 服务如何实现负载均衡
- 服务如何解决容灾问题
- 服务如何实现统一配置