Spring Cloud微服务入门级教程(零基础,最详细,可运行)

目录

先大声BB几句

项目源码地址及导入进IDEA时可能会遇到的问题

第一步——创建maven项目

第二步——搭建服务注册中心

第三步——搭建服务提供者

第四步——搭建第二个服务提供者

第五步——搭建Gateway网关

第六步——在网关中加入熔断器Hystrix

小结


先大声BB几句

首先告诉大家,这不只是一篇简单的教程!!!

首先告诉大家,这不只是一篇简单的教程!!!

首先告诉大家,这不只是一篇简单的教程!!!

重要的事说三遍,为什么这么说呢?因为笔者在这篇文章里的示例,可以说是一个简单的微服务开发脚手架,你可以存起来,做微服务项目的时候把这个架子拉过去,直接用,节省你搭项目的时间。虽然说是简单的脚手架,但是也满足了大部分的开发场景,因为在这篇文章的示例中,我集成了Gateway网关、Hystrix熔断器、Eureka注册中心、两个服务提供者(达到了负载均衡的效果,可水平扩展)

可能有的人会说,你这东西也太少了,像什么OAuth 2.0、Redis、MQ、ElasticSearch等等都没有集成。呃,我想说两点,第一点就是这篇文章的定位还是一篇初级教程,重点是带领对Spring Cloud零基础的朋友搭建微服务开发环境;第二点是,没有哪个框架可以完全满足项目的架构,只能最大限度的去搭建一个可以共用的架子,至于里面具体的需求,需要你去实现定制化开发,去填充这个架子。

项目源码地址及导入进IDEA时可能会遇到的问题

源码请从百度网盘下载,无提取码,永久有效:

https://pan.baidu.com/s/173Ahef8-fMz9ncBd0vOShA

因为我的项目是一个大的maven项目下保护几个小的maven项目,所以导入IDEA时需要动点手脚,你导入进去可能是这样的:

Spring Cloud微服务入门级教程(零基础,最详细,可运行)_第1张图片

它只识别了最外层的maven项目,并没有把里面的几个小项目当作maven项目处理 ,怎么办?看下面几张图:

Spring Cloud微服务入门级教程(零基础,最详细,可运行)_第2张图片

Spring Cloud微服务入门级教程(零基础,最详细,可运行)_第3张图片 

在弹出的页面里选中这几个小项目的pom.xml文件,点击OK即可:

Spring Cloud微服务入门级教程(零基础,最详细,可运行)_第4张图片

第一步——创建maven项目

我们只是学习而非生成环境,没必要弄好几台机器去模拟,直接在本地创建几个项目就好。

同时又为了不打开好多个IDEA窗口,达到省事、看着心不烦的效果,我们先创建一个大的maven空项目,再在里面去添加若干个子项目。

首先我们点击新建项目

Spring Cloud微服务入门级教程(零基础,最详细,可运行)_第5张图片

然后选择Spring Initializr(这里提一句,IDEA是最好的Java开发工具!)

Spring Cloud微服务入门级教程(零基础,最详细,可运行)_第6张图片

 然后创建项目的maven坐标

小声BB:我这里的意思是,com.blog.wang说明这是我的一个博客项目(本人姓王),cloud说明这是一个Spring Cloud项目,你们没必要按着我的来,它就是一个项目名而已。

Spring Cloud微服务入门级教程(零基础,最详细,可运行)_第7张图片

然后选择依赖,因为我们目前只是创建一个项目文件夹,跳过,直接下一步

Spring Cloud微服务入门级教程(零基础,最详细,可运行)_第8张图片

然后设置项目的文件夹名称和路径,名称一般默认即可,路径自选

Spring Cloud微服务入门级教程(零基础,最详细,可运行)_第9张图片

然后等待IDEA加载项目,加载完成之后是如下效果

Spring Cloud微服务入门级教程(零基础,最详细,可运行)_第10张图片

Spring Cloud微服务入门级教程(零基础,最详细,可运行)_第11张图片 

由于我们这个项目文件夹并不保存实质的代码,只是作为包装其他子项目的容器,删除没用的东西,最终效果如下

没错,你没看错,src都不要!就剩这三个就行!

Spring Cloud微服务入门级教程(零基础,最详细,可运行)_第12张图片

第二步——搭建服务注册中心

微服务架构下,我们将项目按照功能或者业务拆分为若干个小的服务,那么这些服务应该如何进行管理?这就需要一个服务注册中心,可以把它理解为一个管理员,我们将所有的服务注册到这个管理员,由它去进行维护和管理。

注册到注册中心的每一个服务,都会有一个服务名称,如果出现了相同的服务名称,则认为是两个相同的服务,那么当客户端在调用这些服务的时候,会自动以负载均衡的方式去调用,将压力分担到不同的服务上,功能上类似于Nginx。此外,注册中心和注册中心之间也可以相互注册,达到高可用的服务集群效果。

服务注册中心有很多种,Dubbo,Eureka,Nacos……,本篇文章采用较简单的Eureka来搭建注册中心,在以后的博文中会陆续介绍其他的几个注册中心。

废话不多说,开始干!

首先,选中cloud文件夹,右键,new,module

Spring Cloud微服务入门级教程(零基础,最详细,可运行)_第13张图片

然后是熟悉的场景,不用多说了吧?下一步就好

Spring Cloud微服务入门级教程(零基础,最详细,可运行)_第14张图片

然后设置maven坐标

这里的意思是,表面这个子项目是一个注册中心

Spring Cloud微服务入门级教程(零基础,最详细,可运行)_第15张图片

然后选择依赖

因为我们这是一个Eureka的服务注册中心,所以我们要选中这个依赖。

Spring Cloud微服务入门级教程(零基础,最详细,可运行)_第16张图片

然后到了这一步,默认就好,点击完成

Spring Cloud微服务入门级教程(零基础,最详细,可运行)_第17张图片

然后等IDEA加载项目,加载完毕之后的效果

Spring Cloud微服务入门级教程(零基础,最详细,可运行)_第18张图片

Spring Cloud微服务入门级教程(零基础,最详细,可运行)_第19张图片 

然后我们对服务注册中心做一下配置,配置什么呢?注册中心在启动时,会寻找另一个注册中心进行注册,但是因为我们这是单机项目,不是集群式的,没必要搭建其他注册中心,所以我们要让这个注册中心扛起大旗,独立起来,做一个成熟的注册中心。也就是说,我们要禁止它注册它自己(另外,我把配置文件的格式改成.yml了):

# 端口号为8080(默认也是8080)
server:
  port: 8080
# 禁止注册自己
eureka:
  client:
    register-with-eureka: false
    fetch-registry: false

Spring Cloud微服务入门级教程(零基础,最详细,可运行)_第20张图片

然后我们在启动类上加@EnableEurekaServer注解,表示将这个项目作为 服务注册中心:

Spring Cloud微服务入门级教程(零基础,最详细,可运行)_第21张图片

然后我们启动项目(注意application.yml文件的编码格式需要是UTF-8)

另外,这里可能有坑,如果你出现了以下错误:

Caused by: java.nio.charset.MalformedInputException: Input length = 1

说明你的application.yml文件的编码格式不是UTF-8!!!解决办法:

Spring Cloud微服务入门级教程(零基础,最详细,可运行)_第22张图片

然后把application.yml文件删了,重新创建,内容复制一遍……我也没找到什么更好的办法。。。

如果启动成功,如下:

Spring Cloud微服务入门级教程(零基础,最详细,可运行)_第23张图片

我们打开浏览器,访问8080,可以看到以下页面,说明注册中心已经启动成功了,只不过没有任何服务注册进来:

Spring Cloud微服务入门级教程(零基础,最详细,可运行)_第24张图片

第三步——搭建服务提供者

到了这一步,服务提供者,往往就是我们项目里真正要提供API接口的部分,也就是我们的业务代码。

由于我们这里只是示例,所以不牵扯数据库,controller层直接返回模拟数据。

步骤跟上边创建注册中心一样,只贴出几个不一样的地方。

我们把项目叫做cloud-biz-1,表示这是一个服务提供者端点

Spring Cloud微服务入门级教程(零基础,最详细,可运行)_第25张图片

这里主要选择以下几个依赖:

Lombok,可以简化我们的开发,最主要的用途是省略getter和setter方法,减少代码篇幅

Spring Cloud微服务入门级教程(零基础,最详细,可运行)_第26张图片

另外,要在IDEA使用Lombok插件,需要进行安装,安装步骤:

Spring Cloud微服务入门级教程(零基础,最详细,可运行)_第27张图片

 Spring Web,选了这个依赖,我们的项目就具有提供web服务的能力了,主要是提供controller控制器

Spring Cloud微服务入门级教程(零基础,最详细,可运行)_第28张图片 

Eureka Discovery Client,可以使我们的项目拥有注册到Eureka服务中心的能力

 Spring Cloud微服务入门级教程(零基础,最详细,可运行)_第29张图片

 选了以上3个依赖,我们直接点击下一步,再点击完成,IDEA加载项目完毕之后

Spring Cloud微服务入门级教程(零基础,最详细,可运行)_第30张图片

 然后,我们创建一个实体类和一个Controller控制器

package com.blog.wang.cloudbiz1.entity;

import lombok.Data;

/**
 *  

* 学生实体类 *

* * @author 秋枫艳梦 * @date 2019-12-08 * */ @Data public class StudentEntity { //姓名 private String name; //年龄 private int age; }
package com.blog.wang.cloudbiz1.controller;

import com.blog.wang.cloudbiz1.entity.StudentEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 *  

* 学生模块,控制器 *

* * @author 秋枫艳梦 * @date 2019-12-08 * */ @RestController @RequestMapping(value = "/student") public class StudentController { /** * 获取一个学生 * @return JSON对象 * */ @GetMapping(value = "/detail") public Object getStudent () { StudentEntity student = new StudentEntity(); //可以看到,我们没有在实体类写get和set方法,但是我们依然可以调用这些方法 //这就是Lombok插件的好处,只需要在实体类加一个@Data注解 student.setName("张三"); student.setAge(18); return student; } }

Spring Cloud微服务入门级教程(零基础,最详细,可运行)_第31张图片

然后我们修改一下这个项目的application.yml

server:
  port: 8081
# 应用名称:client
spring:
  application:
    name: client
# 注册到我们本地的eureka注册中心,端口是8080
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8080/eureka/

然后在启动类上加@EnableEurekaClient注解,表面这是一个服务提供者

Spring Cloud微服务入门级教程(零基础,最详细,可运行)_第32张图片

然后启动这个服务提供者,成功之后刷新注册中心页面,可以看到名叫client的服务已经注册进来(只有一个节点)

Spring Cloud微服务入门级教程(零基础,最详细,可运行)_第33张图片

我们访问localhost:8081/student/list,如下

Spring Cloud微服务入门级教程(零基础,最详细,可运行)_第34张图片

可能有同学要说了,你不是都微服务了吗,怎么还是直接调8081端口?为什么不走服务中心啊?这样还不如我直接创建一个Spring Boot项目呢?

我们先不通过服务中心调接口,因为服务注册中心是根据服务名称去选择要进行业务处理的服务器,而通过服务名称调用接口,要么走Fegin,Ribbon的RestTemplate,这些都是需要用Java代码实现的,适用于系统内部之间的调用,不适用于直接访问的情况。如果你想直接以API接口的方式访问服务注册中心的服务并且达到负载均衡的效果,只有通过网关。网关的内容在下面,先不着急。

第四步——搭建第二个服务提供者

为了实现通过网关访问API接口,并达到负载均衡的效果,我们需要创建第二个服务节点,步骤和上面的一样,我就不细说了,唯一不一样的地方就是项目名称叫cloud-biz-2,里面的任何东西都一样,你可以创建完之后从cloud-biz-1复制一份。

但是请注意,有以下两点不一样的地方

第一个不一样的地方是服务的端口号是8082,不能冲突:

Spring Cloud微服务入门级教程(零基础,最详细,可运行)_第35张图片

第二个地方是controller里返回的数据不一样,因为我们要测试负载均衡吗,需要验证访问的是不同的服务器:

Spring Cloud微服务入门级教程(零基础,最详细,可运行)_第36张图片

 在启动类加上@EnableEurekaClient注解之后,启动项目,可以发现服务注册中心有两个client服务节点:

Spring Cloud微服务入门级教程(零基础,最详细,可运行)_第37张图片

访问8082,没毛病:

Spring Cloud微服务入门级教程(零基础,最详细,可运行)_第38张图片

第五步——搭建Gateway网关

网关,往往是我们真正暴露给用户进行访问的,用户调用网关,网关再去调用内部的各个服务。这样有什么好处呢?

第一,减轻业务服务器的压力。有人要说了,你特么只是通过网关转发了一下,最后不还是请求到了业务服务器么?怎么就减轻压力了?同学你想想,假如你的系统里对每一个API接口都有权限验证,如果没有网关的话,权限验证这件事也需要在业务服务器上进行处理,是不是所有请求都直接落在了你的业务服务器?但是如果你加一个网关,你就可以在网关层过滤一些请求,保证只有合法、有效的请求才落实到业务服务器,这样一来,权限验证这个事就从业务服务器转移到了网关服务器,难道不是减轻压力吗?

第二,保护业务服务器的安全。在部署这些微服务时,我们可以将所有的服务都部署在一个局域网里,网关和服务之间只通过内网调用,只把网关暴露出去,这样一来,即使网关的域名或者地址被攻破了,你的业务服务器还是安全的。此外,网关还可以在大量流量突然涌入时,做限流,一样保护了业务服务器的安全。

第三,可以配合Nginx搭建高可用的服务。在一个微服务系统中,往往一个网关是不够的,为什么?假如你的业务服务器一共有10个节点,但是你又不想暴露出去,只想把网关暴露给用户,那么所有的流量压力其实都到了网关身上,这时候我们可以注册多个网关,在网关的上层再去加一个Nginx,由Nginx转发到网关集群,再由不同的网关去转发到不同的业务节点,达到高可用、高性能的服务器。

话不多说,接下来我们就开始。这里采用目前比较流行的Gateway网关,这是Spring Cloud团队自己研发的网关,功能很强大,由于篇幅原因,此处博主就带领大家体验基本的功能。

依然是创建子项目,跟上边创建服务提供者一样,我就不一一罗列了,只贴出不一样的地方:

首先项目名称叫cloud-gateway,不贴图了。

然后是依赖:

Spring Cloud微服务入门级教程(零基础,最详细,可运行)_第39张图片

Spring Cloud微服务入门级教程(零基础,最详细,可运行)_第40张图片

 在网关项目的配置文件添加如下内容:

server:
  #网关端口8083
  port: 8083
spring:
  application:
    #在服务中心的应用名称
    name: gateway
  cloud:
    gateway:
      discovery:
        locator:
          #自动映射eureka下的服务路由
          enabled: true
          #开启服务名称小写
          lower-case-service-id: true
# 注册到服务中心
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8080/eureka/

然后在启动类加上@EnableEurekaClient注解,启动项目,可以看到已经注册到服务中心了:

Spring Cloud微服务入门级教程(零基础,最详细,可运行)_第41张图片

接下来我们测试一下通过网关访问我们的client服务,如何访问呢?

前面我们说到网关是通过服务名,去注册中心寻找相应的节点的,假如我们访问localhost:8083/client/student/detail,那么它就会去服务注册中心寻找叫做client的服务节点,并将后面的/student/detail转发到对应的节点,所以最后访问的真正地址也就是我们的localhost:8081/student/list。如果有多个相同名称的节点,则会以负载均衡的方式去分配到不同的服务节点。当然了,这都是gateway默认的转发方式,它有很多灵活的转发方式,都可以配置,比如忽略服务名前缀啊、从端口号后的第几个路径开始截图转发等等。

也就是说,网关默认的访问方式是:主机名(或者IP、域名):网关端口号/服务名称/请求的url

落实到我们这个例子里,就是localhost:8083/client/student/list,访问效果:

Spring Cloud微服务入门级教程(零基础,最详细,可运行)_第42张图片

Spring Cloud微服务入门级教程(零基础,最详细,可运行)_第43张图片 

可以看到,张三和李四是交替出现的,Gateway网关为我们实现了负载均衡。

Gateway的玩法有很多,由于篇幅原因以后再给大家介绍。

第六步——在网关中加入熔断器Hystrix

在微服务中,各个系统之间相互调用,难免出现某个服务挂掉的情况,此时熔断器机制就很重要,我们可以利用熔断器,将超时的请求予以异常处理,避免形成死循环的调用链。

由于我们刚才在搭建网关时没用选择熔断器依赖,所以在网关项目的pom.xml手动添加以下依赖:


            org.springframework.cloud
            spring-cloud-starter-netflix-hystrix
        

然后修改配置文件:

server:
  #网关端口8083
  port: 8083
spring:
  application:
    #在服务中心的应用名称
    name: gateway
  cloud:
    gateway:
      discovery:
        locator:
          #自动映射eureka下的服务路由
          enabled: true
          #开启服务名称小写
          lower-case-service-id: true
      #服务熔断,降级
      default-filters:
        - name: Hystrix
          args:
            name: fallbackcmd
            fallbackUri: forward:/fallback

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8080/eureka/
      
# hystrix熔断器,3秒后自动超时
hystrix:
  command:
    fallbackcmd:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 3000

上面配置里的fallbackUri,是指熔断时的回调地址,也就是说一旦服务响应超过了3秒,会转发到这个地址,执行自定义的业务操作,我们往往是返回一个错误码。注意,这个回调的controller,是要写到网关里的,所以我们在网关项目里新建如下:

package com.blog.wang.cloudgateway.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

@RestController
public class ErrorController {

    /**
     *  服务响应超时的回调
     * @return 错误码
     * */
    @RequestMapping(value = "/fallback")
    public Object fallback () {
        Map result = new HashMap<>();
        result.put("code" , 0);
        result.put("msg" , "服务器繁忙");
        result.put("state" , false);
        return result;
    }
}

Spring Cloud微服务入门级教程(零基础,最详细,可运行)_第44张图片

然后我们在第一个服务节点里,添加如下代码,模拟超时:

Spring Cloud微服务入门级教程(零基础,最详细,可运行)_第45张图片

再通过我们的网关访问API接口,发现每当请求到达第一个服务节点时,就会提示服务器繁忙:

Spring Cloud微服务入门级教程(零基础,最详细,可运行)_第46张图片

小结

以上就是基本的Spring Cloud脚手架,相信还是可以满足大多数人的开发需求的。不足的地方有很多,比如处理跨域、线上环境的注册中心配置、Gateway网关的多种配置、熔断器的各种配置,以后都会慢慢地补上,还请大家海涵吧!

码字不易,欢迎各位的转发、分享、支持!

你可能感兴趣的:(企业级开发框架)