(一)什么是微服务?

在了解什么是SpringCloud之前,我们有必要去了解一下什么是微服务。在传统的项目中,我们都是把所有的代码都放在一个单体应用中,这种方式配置方便,可以很好的运行部署,但是随着项目越来越大,这个单体应用就会越来越臃肿,再加上一个项目中融合了许多人不同的代码,可维护性越来越低。以至于现在一些企业的项目中所用到的代码还是很早期的框架和代码风格。这个时候,一种叫做微服务的架构方式出现了。

有人对微服务做了这样一个定义:“微服务架构是一种将单个应用程序开发为一组小服务的方法,每个小服务都在自己的进程中运行并与轻量级机制(通常是HTTP资源API)进行通信。这些服务围绕业务功能构建,并且可以由全自动部署机制独立部署。这些服务的集中管理几乎没有,可以用不同的编程语言编写并使用不同的数据存储技术。”

简单来说,微服务就是将一个项目中的小功能都分为一个个微小的服务,并且独立运行在自己的进程中,要用了再分别调用就行。

(二)什么是SpringCloud?

我们知道了什么是微服务,那么如何去实现微服务呢?这时SpringCloud就出现了。SpringCloud是一个目前比较流行的微服务框架,它不是一个崭新的框架,而是一系列框架的集合工具包,官网对SpringCloud的解释如下:

翻译过来的重点就是:SpringCloud为开发人员提供了一系列工具用来快速构建分布式系统中常见的模式,如:服务发现注册,配置中心,消息总线,负载均衡,断路器等等。给开发者留出了一套简单易懂、易部署和维护的分布式系统开发工具包。

(三)创建第一个微服务项目

(3.1)搭建整体项目框架:

理论了解再多没有实践就不是真正的理解,现在我们就用idea来模拟一个微服务项目:

首先新建project,选择maven,直接点击next

 输入项目信息,点击next

 然后在下一个页面选择路径,点击finish即可,这样我们就创建了一个空的maven项目,现在通过导入依赖把它变成SpringBoot的项目,把依赖加到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.sdxb</groupId>
    <artifactId>SpringCloudDemo</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.7.RELEASE</version>
    </parent>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>RTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.8</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Greenwich.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <repositories>
        <repository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>http://repo.spring.io/libs-snapshot-local</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>

    <pluginRepositories>
        <pluginRepository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>http://repo.spring.io/libs-snapshot-local</url>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </pluginRepository>
        <pluginRepository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>http://repo.spring.io/libs-milestone-local</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </pluginRepository>
    </pluginRepositories>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

这是总的微服务项目所需要的依赖,删除整个src文件夹,在总项目中不需要这个文件夹。

(3.2)搭建第一个微服务模块

点击项目右键,建立第一个微服务模块,因为我已经建立了user_service模块了,所以现在的比你们多了一个module:

还是一样选择maven,点击next

  起个名字叫user_service

 

点击next并点击finish创建成功,这是我们的第一个微服务模块,我只在这里实现最简单的功能:根据id查询数据库中User的信息,User_Service结构如下:

在User_Service模块的pom.xml中导入数据库相关的依赖即可

<dependencies>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.46</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jdbc</artifactId>
        <version>2.1.7.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>1.1.1</version>
    </dependency>
</dependencies>

在resources下新建一个application.properties用来配置相关设置,这里配置数据库的路径和服务端口号,数据库的路径请按照自己实际的修改

spring.datasource.url=jdbc:mysql://localhost:3306/springclouddemo?characterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

server.port=9001
spring.application.name=user_service

首先在数据库中新建一张user表,包含id、username和password。建立表的实体类User.java,这里使用lombok框架的@Data注解自动生成getter和setter方法

 

@Data
public class User {
    private int id;
    private String username;
    private String password;
}

在UserMapper中实现Mybatis对数据库的操作:

@Mapper
public interface UserMapper {
    @Select("select * from user where id=#{id}")
    User selectbyid(int id);
}

 在UserController中实现请求的获取,这些都是SpringBoot相关的知识: 

 

 

@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserMapper userMapper;
    @GetMapping("/{id}")
    public User user(@PathVariable("id") int id){
        User users = userMapper.selectbyid(id);
        return users;
    }
}

 最后新建一个启动类:UserApplication,用于启动整个项目

 

@SpringBootApplication
@EntityScan("com.sdxb.entity")
public class UserApplication {
    public static void main(String[] args) {
        SpringApplication.run(UserApplication.class,args);
    }
}

 

现在启动UserApplication,在浏览器中输入http://localhost:9001/user/1,我提前在数据库中已经插入了一条id为1的数据信息,看到访问结果:

(3.3)搭建第二个微服务模块

第二个模块我打算建一个admin管理员微服务,然后去调用user_service微服务获取用户的数据。这也正是微服务所需要去实现的内容。user_service使用9001端口提供一个http的接口,我们只需要使用get请求去访问http://localhost:9001/user/1,就能获取到id为1的用户数据。SpringCloud提供了RestTemplate来处理get请求和post请求。

和第二步一样点击项目右键创建一个module,命名为admin_service,目录结构如下:

其中application.properties和User直接复制user_service,并将application.properties中的端口号9001改为9002,在AdminApplication启动类中,我们需要使用Bean注解配置RestTemplate,代码如下:

@SpringBootApplication
@EntityScan("com.sdxb.admin.entity")
public class AdminApplication {
    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
    public static void main(String[] args) {
        SpringApplication.run(AdminApplication.class,args);
    }
}

在adminController自动注入restTemplate,并使用getForObject通过get请求获取User对象

 

@RestController
@RequestMapping("/admin")
public class adminController {

    @Autowired
    private RestTemplate restTemplate;
    @RequestMapping(value = "/{id}",method = RequestMethod.GET)
    public User getuser(@PathVariable int id){
        User user= restTemplate.getForObject("http://127.0.0.1:9001/user/1",User.class);
        return user;
    }
}

在浏览器中访问http://localhost:9002/admin/1,查看返回结果:

(四)总结

通过这个实例我们已经了解了什么是微服务,但是这个实例中也存在着一些问题,

第一:admin_service调用user_service时把url写进了代码中,这对后期维护来说是很困难的,解决的办法是加入一个API网关,帮我们去调用具体的微服务

第二:一个微服务中有些功能会经常被调用,而有些功能很少被调用,这个时候就需要做到负载均衡

第三:配置文件如果每一个微服务都写的话,是个很大的工作量,所以需要配置的统一管理

第四:如果一个微服务同时又调用其他的微服务,在排错时是很难找到问题的,所以就需要链路追踪

如果我们手动去解决这些问题是个很庞大的工程,这个时候我们就需要正式用到SpringCloud提供给我们的一系列框架。

附上github源码,与博客相对应的代码放在version1.0分支上:github源码

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐