Spring Cloud微服务入门级教程(零基础,最详细,可运行) 您所在的位置:网站首页 springcloud微服务项目实战派 Spring Cloud微服务入门级教程(零基础,最详细,可运行)

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

2024-06-11 02:35| 来源: 网络整理| 查看: 265

目录

先大声BB几句

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

第一步——创建maven项目

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

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

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

第五步——搭建Gateway网关

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

小结

2021-04-01更新

不知为何百度网盘的链接失效了,笔者把项目上传到了GitHub仓库,以后的项目代码也将通过GitHub进行上传,为大家带来的不便深感歉意!

https://github.com/QiuFengYanMeng/cloud-demo

  先大声BB几句

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

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

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

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

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

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

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

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

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

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

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

第一步——创建maven项目

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

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

首先我们点击新建项目:

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

 然后创建项目的maven坐标:

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

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

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

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

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

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

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

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

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

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

废话不多说,开始干!

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

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

然后设置maven坐标:

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

然后选择依赖:

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

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

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

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

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

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

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

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

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

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

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

如果启动成功,如下:

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

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

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

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

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

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

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

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

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

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

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

 

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

 然后,我们创建一个实体类和一个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; } }

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

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

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

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

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

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

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

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

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

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

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

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

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

访问8082,没毛病:

第五步——搭建Gateway网关

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

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

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

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

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

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

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

然后是依赖:

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

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注解,启动项目,可以看到已经注册到服务中心了:

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

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

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

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

可以看到,张三和李四是交替出现的,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; } }

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

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

小结

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

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



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有