微服务简介
微服务就是将传统的单体项目将其中具体业务的各个模块拆分为独立的子项目,项目之间使用轻量级的通讯协议进行交互的一种系统架构,且每个微服务拥有自己的数据库与独立容器。当下使用较为广泛的微服务实现为SpringCloud,其基于SpringBoot整合了一系列的微服务组件,为微服务项目的开发提供了极大的便利。
SoringCloud项目搭建
第一步: 创建一个Maven项目作为父工程。
第二步: 配置父工程的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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>clouddemo</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>cloud-commons-api</module>
</modules>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<mysql.version>5.1.47</mysql.version>
<druid.version>1.1.10</druid.version>
<junit.version>4.1.2</junit.version>
<lombok.version>1.16.10</lombok.version>
<log4j.vsrsion>2.18.0</log4j.vsrsion>
</properties>
<!-- 因为是总项目 所以用dependencyManagement来管理 因为其他的子项目就不会来管理版本了了 可以直接引用 -->
<dependencyManagement>
<dependencies>
<!-- springcloud的依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>2021.0.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- springboot的依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.6.6</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- 数据库-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>
<!-- springboot启动器-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<!--单元测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!-- lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.8</version>
</dependency>
<!-- log4j-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.vsrsion}</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>
由于父工程不需要写业务代码,所以可以将符工程的src文件夹删除。 自此父工程就创建完毕了,接下来就可以在父工程中添加各个模块,也就是各个微服务组件。
第三步: 右键父项目创建子项目(具体微服务)
此时我们完成了第一个微服务的就创建,该项目为一个公共的实体类服务。接下来开始配置此微服务。
第四步: 配置此微服务的POM.xml文件。引入该微服务需要的依赖包。这里我们引入了Hutool这个jar包,它是一个常用的Java基础工具类,对文件、流、加密解密、转码、正则、线程、XML等JDK方法进行封装。
<?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>clouddemo</artifactId>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud-commons-api</artifactId>
<dependencies>
<!--springboot-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!--Hutool工具包-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.3.1</version>
</dependency>
</dependencies>
</project>
第五步: 编写实体类
package com.cloudtest.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class BSResult<T> {
private Integer code;
private String message;
private T data;
public BSResult(Integer code,String message){
this(code,message,null);
}
}
package com.cloudtest.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.io.Serializable;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class User implements Serializable {
// 微服务 一个服务对应一个数据库,同一个信息可能存在不同的数据库
private long userId;
private String userName;
private String userGender;
}
第六步: 创建服务提供者
步骤同创建实体类的步骤相同,(创建一个models子项目,引入所需以来,编写业务代码),不过服务提供者需要启动项目,所以需要创建一个SpringBoot启动类并且需要编写配置文件。
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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>clouddemo</artifactId>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud-provide-userInfo</artifactId>
<dependencies>
<!-- 引入实体的包-->
<dependency>
<groupId>org.example</groupId>
<artifactId>cloud-commons-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
<!--mysql-connector-java-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--jdbc-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
创建一个三层目录结构
在cloudtest包下创建SpringApplication启动类。
在rescources文件夹下创建配置文件
配置文件内容:
#服务端口
server:
port: 8081
#spring相关配置
spring:
application:
name: service-userinfo
datasource:
url: jdbc:mysql://localhost:3306/dbcloud?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false
username: root
password: 123456
driver-class-name: org.gjt.mm.mysql.Driver #老版本的jdbc和com.mysql.cj.jdbc.Driver一样
type: com.alibaba.druid.pool.DruidDataSource #数据源操作类型
#mybatis配置
mybatis:
mapper-locations: classpath:mybatis/mapper/*.xml
#控制台看到执行的SQL语句
logging:
level:
com:
mapper: debug
编写具体业务代码
controller:
package com.cloudtset.controller;
import com.cloudtest.pojo.BSResult;
import com.cloudtest.pojo.User;
import com.cloudtset.service.UserInfoService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
@RestController
@Slf4j
public class UserInfoController {
@Autowired
private UserInfoService userInfoService;
@Value("${server.port}")
private int serverPort;
@PostMapping("/userinfo/create")
public BSResult create(@RequestBody User user){
int i = userInfoService.create(user);
log.info("########插入成功########"+i);
if(i>0){
return new BSResult(200,"数据插入成功"+"server-port:"+serverPort);
}else{
return new BSResult(444,"数据插入失败");
}
}
@GetMapping("/userinfo/get/{id}")
public BSResult queryById(@PathVariable("id")Long id){
User user= userInfoService.queryById(id);
log.info("***************查询成功*********"+user);
if(user!=null){
return new BSResult(200,"查询成功"+"server-port:"+serverPort,user);
}else{
return new BSResult(444,"查询失败",null);
}
}
}
service:
接口:
package com.cloudtset.service;
import com.cloudtest.pojo.User;
import org.apache.ibatis.annotations.Param;
public interface UserInfoService {
Integer create(User user);
User queryById(@Param("id")long userId);
}
实现类:
package com.cloudtset.service.Imp;
import com.cloudtest.pojo.User;
import com.cloudtset.service.UserInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserInfoServiceImp implements UserInfoService {
@Autowired
UserInfoDao userInfoDao;
@Override
public Integer create(User user) {
return userInfoDao.create(user);
}
@Override
public User queryById(long userId) {
return userInfoDao.queryById(userId);
}
}
dao:
package com.cloudtset.dao;
import com.cloudtest.pojo.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
@Mapper
@Repository
public interface UserInfoDao {
int create(User user);
User queryById(@Param("id")long id);
}
之后再使用mybatis编写查询语句
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dqueryByidtd/mybatis-3-mapper.dtd">
<mapper namespace="com.cloudtset.dao.UserInfoDao">
<resultMap id="BaseResultMap" type="com.cloudtest.pojo.User">
<id column="id" property="userId" jdbcType="BIGINT"/>
<id column="name" property="userName" jdbcType="VARCHAR"/>
<id column="gender" property="userGender" jdbcType="VARCHAR"/>
</resultMap>
<insert id="create" parameterType="com.cloudtest.pojo.User" useGeneratedKeys="true" keyProperty="id">
insert into user (name,gender) values (#{userName},#{userGender});
</insert>
<select id="queryById" resultType="com.cloudtest.pojo.User" parameterType="Long" resultMap="BaseResultMap">
select * from user where id = #{id};
</select>
</mapper>
最后创建数据库,以下为sql语句
CREATE TABLE `user` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',
`name` varchar(200) COLLATE utf8_unicode_ci DEFAULT NULL,
`gender` varchar(200) COLLATE utf8_unicode_ci DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
insert into user ('id','name','gender') values (1,'tom','male'),(2,'lucy','female');
此时第一个服务提供者就编写完毕。
第七步: 创建服务消费者
创建步骤与之前的的服务提供者相同
目录结构:
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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>clouddemo</artifactId>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud-consumer-search</artifactId>
<dependencies>
<!--实体包-->
<dependency>
<groupId>org.example</groupId>
<artifactId>cloud-commons-api</artifactId>
<version>${project.version}</version>
</dependency>
<!--web服务-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--actuator检测-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
</project>
启动类:
配置文件:
server:
port: 7071
spring:
application:
name: service-order #服务名
服务消费者需要通过http向服务提供者发起业务请求,本项目中使用RestTemplate(封装了http客户端的模板方法api)进行实现。 在config包下创建Spring配置类将RestTemplate注入进Spring容器:
package com.cloudtest.config;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@SpringBootConfiguration
public class ApplicationContext {
@Bean
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
在controller包下编写查询业务代码:
package com.cloudtest.controller;
import com.cloudtest.pojo.BSResult;
import com.cloudtest.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;
@RestController
public class QueryUser {
@Autowired
RestTemplate restTemplate;
//调用的服务端的ip+端口号
public static final String USERINFO_URL="http://localhost:8081";
//根据id查询用户信息
@GetMapping("/search/user/{id}")
public BSResult<User> queryUserById(@PathVariable("id") Long id){
//通过restTemplate向服务端发起请求
return restTemplate.getForObject(USERINFO_URL+"/userinfo/get/"+id,BSResult.class);
}
}
此时我们的第一个springcloud微服务项目就搭建完成了,启动项目后,我们可以打开浏览器对功能进行测试。
之后我们还可以向项目中添加更多的微服务来扩充项目的功能,如注册中心,负载均衡等,其基本创建过程与以上的几个微服务创建过程大致相同。