Spring Cloud简介
1. 什么是Spring Cloud?
Spring Cloud 其实就是一个微服务框架。
2. 什么又是微服务
微服务其实本身并没有严格的定义,微服务架构的风格就是将一个单一应用程序拆分为一组小型服务,每个服务运行在自己的进程中,服务之间采用轻量级的通信机制,这些服务可通过全自动部署机制独立部署,服务可用不同的语音开发,可以使用不同的数据存储技术,同时这些服务被集中式管理。
3. 微服务又有什么优点
(1)易于开发和维护:一般一个服务只针对一个特定的业务功能,代码和业务量都比较少,所以开发和维护都比较容易
(2)启动快,便于局部部署和修改:我们使用单个应用时,由于代码功能较多,每次启动时可能要消耗很长事件。只要有功能修改整个应用就要全部部署,微服务只需要重启修改的单个服务就可以
(3)易于扩展:新的需求可以无限扩展 原基础上的代码可能只需要做少量改动,降低了代码的耦合性
(4)开发语言不受限制:不同的微服务可有不同的语言开发,这样可以根据实际情况选择合适的语言开发
4. 微服务设计的原则有哪些
(1)单一职责原则:单一职责指一个单元只关注整个系统中单独有界限的部分
(2)服务自治原则:指每个服务要具备单独的业务能力和运行环境
(3)轻量级的通讯机制:微服务之间的通讯应通过轻量级的通信机制进行交互
(4)微服务的粒度:使用合理的粒度去划分微服务。不同的应用程序有不同的粒度,要更具实际情况合理的划分微服务。
4.Spring Cloud有什么优点
(1)约定优于配置,也称作按约定编程,是一种软件设计范式,旨在减少软件开发人员需做决定的数量,获得简单的好处,而又不失灵活性。
(2)适用于各种环境
(3)隐藏了复杂的组件,可快速启动和上手
(4)组件丰富功能齐全
(5)组件灵活开发人员可根据自身自行选择
5.编写Spring Cloud项目
Spring Cloud发展迅速 版本很多,下面的工程我们全部使用Greenwich.SR1版本,springboot 2.1.4;
微服务构建的是分布式系统,微服务之间通过网络通讯,我们使用服务提供者和服务消费者来描述微服务直接的调用关系。
例如我们的购物系统购物时需要获取用户信息,用户服务可作为单独的服务提供用户信息 我们称用户服务为服务提供者,购物系统为服务消费者
创建服务提供者
Spring Cloud是基于Springboot 构建的 所以学Spring Cloud之前一定要知道如何构建Springboot工程,不会的可以看我这篇博客教大家如何构建 Springboot+mybatis构建管理后台系统.
创建Springboot工程user-prodiver 并集成mybatis 创建用户表 在pom.xml中加入spring cloud依赖 具体的创建过程就不细说了 上篇博客都详细说明的,这里只贴出代码
<!-- 添加spring cloud的依赖-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencied</artifactId>
<version>Greenwich.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
建表语句
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(32) NOT NULL,
`password` varchar(32) NOT NULL,
`gender` varchar(16) DEFAULT NULL,
`phone` varchar(32) DEFAULT NULL,
`money` decimal(10,2) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES ('1', 'kim', '123456', '1', '1234567890', '200.00');
创建 User实体类
package com.xiong.user.model;
import java.math.BigDecimal;
public class User {
private Integer id;
private String name;
private String password;
private String gender;
private String phone;
private BigDecimal money;
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;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public BigDecimal getMoney() {
return money;
}
public void setMoney(BigDecimal money) {
this.money = money;
}
}
创建 UserMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.xiong.user.dao.UserMapper" >
<resultMap id="BaseResultMap" type="com.xiong.user.model.User" >
<id column="id" property="id" jdbcType="INTEGER" />
<result column="name" property="name" jdbcType="VARCHAR" />
<result column="password" property="password" jdbcType="VARCHAR" />
<result column="gender" property="gender" jdbcType="VARCHAR" />
<result column="phone" property="phone" jdbcType="VARCHAR" />
<result column="money" property="money" jdbcType="DECIMAL" />
</resultMap>
<sql id="Base_Column_List" >
id, name, password, gender, phone, money
</sql>
<select id="selectByUserName" resultMap="BaseResultMap" parameterType="java.util.Map" >
select
<include refid="Base_Column_List" />
from user
where name = #{name,jdbcType=VARCHAR}
</select>
</mapper>
创建 UserMapper.java
package com.xiong.user.dao;
import com.xiong.user.model.User;
import java.util.Map;
public interface UserMapper {
/**
* 根据用户名获取用户
* @param map
* @return
*/
User selectByUserName(String userName);
}
创建 UserService.java
package com.xiong.user.service;
import com.xiong.user.model.User;
public interface UserService {
User selectByUserName(String userName);
}
创建 UserServiceImpl.java
package com.xiong.user.service.impl;
import com.xiong.user.dao.UserMapper;
import com.xiong.user.model.User;
import com.xiong.user.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Override
public User selectByUserName(String userName) {
return userMapper.selectByUserName(userName);
}
}
application.yml的配置
spring:
datasource:
name: blog
url: jdbc:mysql://localhost:3306/buy_dev?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=Hongkong
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:
mapper-locations: classpath:mapping/*.xml
type-aliases-package: com.xiong.user.model
logging:
level:
com.xiong.blog.dao: debug
package com.xiong.user.controller;
import com.xiong.user.model.User;
import com.xiong.user.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class LoginController {
@Autowired
private UserService userService;
@RequestMapping("/login")
@ResponseBody
public Object login(@RequestParam(value = "name", required = false) String name) {
User user = userService.selectByUserName(name);
return user;
}
}
这里我们的服务提供者就写好了 提供了一个输入用户名获取用户的接口 我们在启动项目在浏览器中输入
http://localhost:8080/login?name=kim 就可以看到如下结果:
{“id”:1,“name”:“kim”,“password”:“123456”,“gender”:“1”,“phone”:“1234567890”,“money”:200.00}
创建服务消费者
创建一个新的springboot工程customer-buy 和上面工程一样在pom.xml中也加入spring cloud依赖 ,同时将User.class类copy到该项目中 在启动类中加入下面代码:
package com.xiong.buy;
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 CustomerBuyApplication {
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(CustomerBuyApplication.class, args);
}
}
新建一个UserController.java类
package com.xiong.buy.controller;
import com.xiong.buy.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.client.RestTemplate;
@Controller
public class UserController {
@Autowired
private RestTemplate restTemplate;
@RequestMapping("/user")
@ResponseBody
public Object user(@RequestParam(value = "name", required = false) String name) {
return this.restTemplate.getForObject("http://localhost:8080/login?name="+name, User.class);
}
}
修改下这个工程的启动端口号,修改配置文件application.yml
server:
port: 8081
启动工程在浏览器中输入http://localhost:8081/login?name=kim 可以看到我们也得到了相同的结果:
{“id”:1,“name”:“kim”,“password”:“123456”,“gender”:“1”,“phone”:“1234567890”,“money”:200.00}
这样一个简单的微服务就完成了;
但是这样的代码你可能也发现了有没有微服务其实没有任何区别,不要着急,这篇文章只是抛砖引玉,后续我会分篇介绍Spring Cloud中核心组件,从而真正体现微服务的价值;喜欢的可以关注微信公众号 码农冲天梯 获取更多文章;