目录
前言:
一、在idea中创建一个父工程和两个子项目并运行
1、新建项目
2、引入依赖
3、编写配置文件
4、启动子项目
二、引入nacos服务注册发现中心
1、安装登录nacos客户端
2、引入nacos依赖
3、编写nacos的配置文件
4、启动服务
三、服务之间的远程调用-Feign
1、添加依赖,和启动类注解
2、编写feign客户端接口
3、测试调用
四、网关-Gateway
1、创建新模块-gateway
2、引入依赖
3、编写配置文件
4、启动gateway服务,测试
五、使用docker-compose部署微服务项目
1、项目打包
2、编写Dockerfile和docker-compose.yml文件
3、上传服务器并部署
六、问题总结
1、项目依赖以及版本
2、feign远程调用
3、项目部署
项目介绍:本次项目为一个简单的微服务项目,主要用到的技术栈有: springcloud,nacos,feign,gateway,docker-compose,linux。
项目目的:学习巩固搭建简易的微服务系统,并部署上线。
项目所用spring框架版本:
spring boot: 2.6.3、spring cloud: 2020.0.5、spring cloud alibaba: 2021.0.1.0
提示:本文章不做过多理论介绍,只注重实战
如果想要学习如何部署springboot单项目,可以跳转到 => 部署Boot项目
打开Idea,新建一个项目
添加Web依赖
再编写两个子项目
给父工程添加 alibaba.cloud 的依赖
org.springframework.cloud
spring-cloud-dependencies
2020.0.5
pom
import
com.alibaba.cloud
spring-cloud-alibaba-dependencies
2021.0.1.0
pom
import
mysql
mysql-connector-java
5.1.21
com.baomidou
mybatis-plus-boot-starter
3.5.2
org.projectlombok
lombok
1.18.24
在两个子项目中引入父项目
com.example.parent
cloud-demo
0.0.1-SNAPSHOT
在父项目中引入子项目
UserService
OrderService
分别在两个子项目中编写配置文件,可以利用以下模板
# 端口号
server:
port: 7002
# spring配置
spring:
application:
name: user-service
# mysql数据库配置
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://xxx.xxx.xxx.xxx:3306/yzcx?characterEncoding=utf-8&useSSL=false
username: xxx
password: xxx
# mybatis-plus配置
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
mapper-locations: classpath:com/example/userservice/teacher/mapper/xml/*.xml
添加启动类注解:
@MapperScan("com.example.*.*.mapper")
配置好以后编写controller层代码,然后启动两个子项目,并使用浏览器访问
两个项目均可以正常访问
我这里已经在服务器上安装好了,没安装的可以用docker拉取以下镜像然后运行,安装后启动nacos客户端,再打开以下网址:
http://xxx.xxx.xxx.xxx:8848/nacos/index.html
中间填上服务器ip地址,进入后登录客户端,账号密码均为nacos
在两个子项目中分别引入此依赖
这里要保持spring boot和spring cloud以及spring cloud alibaba版本对应
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-discovery
2021.1
分别在两个子项目中配置
# nacos配置
spring:
cloud:
nacos:
server-addr: xxx.xxx.xxx.xxx:8848
启动服务后再去nacos客户端中的服务列表查看,就可以看见两个子项目了
到这里就已经实现了服务发现
在orderservice服务中编写
org.springframework.cloud
spring-cloud-commons
3.1.3
org.springframework.cloud
spring-cloud-starter-openfeign
3.1.3
org.springframework.cloud
spring-cloud-starter-loadbalancer
3.1.3
再把nacos中的ribbon排除掉,防止依赖冲突
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-discovery
org.springframework.cloud
spring-cloud-starter-netflix-ribbon
2021.0.1.0
启动类注解为:
@EnableFeignClients
依旧在orderservice服务中编写
@FeignClient(value = "user-service",path = "/basic-api/hospital")
public interface UserClient {
@GetMapping("list")
Result findList();
}
再去orderservice服务的controller层中写一个请求调用这个接口
@Autowired
private UserClient userClient;
@GetMapping("lists")
public Result getList(){
return userClient.findList();
}
到浏览器中访问刚刚写的orderservice中的接口
访问成功!说明已经实现了服务之间的远程调用!
com.example.parent
cloud-demo
org.springframework.boot
spring-boot-starter-web
mysql
mysql-connector-java
com.baomidou
mybatis-plus-boot-starter
0.0.1-SNAPSHOT
org.springframework.boot
spring-boot-starter-test
test
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-discovery
org.springframework.cloud
spring-cloud-starter-netflix-ribbon
2021.0.1.0
org.springframework.cloud
spring-cloud-starter-gateway
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-webflux
3.1.3
org.springframework.cloud
spring-cloud-commons
3.1.3
org.springframework.cloud
spring-cloud-starter-openfeign
3.1.3
org.springframework.cloud
spring-cloud-starter-loadbalancer
3.1.3
org.springframework.boot
spring-boot-starter-webflux
server:
port: 7999
spring:
application:
name: gateway
cloud:
# nacos配置
nacos:
server-addr: xxx.xxx.xxx.xxx:8848
# 网关配置
gateway:
routes: # 网关配置路由
- id: user-service # 路由id,自定义,只要唯一即可
# uri: http://127.0.0.1:8080 # 路由的目标地址,http就是固定地址
uri: lb://user-service # 路由的目标地址 lb就是负载均衡,后面跟服务名称
predicates: # 断言:判断请求是否符合规则
- Path=/basic-api/hospital/**
- id: order-service # 路由id,自定义,只要唯一即可
# uri: http://127.0.0.1:8080 # 路由的目标地址,http就是固定地址
uri: lb://order-service # 路由的目标地址 lb就是负载均衡,后面跟服务名称
predicates: # 断言:判断请求是否符合规则
- Path=/basic-api/sys/**
编写完成后就可以启动整个项目了
可以发现,这里是通过7999端口访问的,所以可以得出结论:请求经过网关转发到了对应的服务地址!
到了这里,一个简单的微服务系统就已经完成了!
接下来尝试将它部署到Linux服务器中,“上线”这个项目!
前提:服务器中需要提前下载安装好mysql、nacos、docker-compose
docker-compose相比于普通的docker方式部署微服务,更加的方便,不需要重复操作,编写好构建文件一键操作即可!
如果需要学习安装nacos以及docker-compose可以跳转到 => 安装nacos和docker-compose
① 将项目中所有的ip地址修改为服务器中的容器名称
例如mysql,和nacos
url: jdbc:mysql://mysql:3306/yzcx?characterEncoding=utf-8&useSSL=false
server-addr: nacos:8848
② 将项目的pom文件中的打包依赖修改一下
加上
③ 清理、打包
使用maven依赖管理工具,先执行clean再执行package
项目打包好以后分别把 jar 包放在以下三个文件夹中
Dockerfile
# 将下面的代码放入Dockerfile文件中,复制三份分别放入三个文件夹
FROM java:8-alpine
COPY ./app.jar /tmp/app.jar
ENTRYPOINT java -jar /tmp/app.jar
docker-compose.yml
version: "3.2"
services:
nacos:
image: nacos/nacos-server
environment:
MODE: standalone
ports:
- "8848:8848"
userservice:
build: ./user-service
orderservice:
build: ./order-service
gateway:
build: ./gateway
ports:
- "7999:7999"
结果展示:
在linux目录下的tmp中创建一个cloud-demo文件夹。将此文件夹里面的文件全部上传到该文件夹中,然后运行以下命令:
# 新建文件夹
mkdir cloud-demo
# 构建镜像并运行
docker-compose up -d
第一次运行会报错,因为nacos在其他服务后启动,其他服务在此之前是注册不了的,只需要再重新启动其他三个服务即可,命令如下:
docker-compose restart gateway userservice orderservice
微服务项目部署已一键完成!接下来就可以去页面访问了~
温馨提示:
如果出现其他服务启动时立刻就挂掉的情况 , 检查是否因为nacos也随之重启了 , 如果nacos在服务之后又再次重启 , 那么其他服务是找不到nacos的 , 造成这个的原因是服务器内存太小 , 导致naocs被挤掉了
通过docker ps命令查看正在运行的容器 , 发现nacos的确被重启了~
解决方式:
可以在运行nacos容器的时候加以限制:
在此之前需要把nacos现有的容器删掉( docker rm -f ) , 然后运行
docker run --name nacos-yh-test -e PREFER_HOST_MODE=hostname -e SPRING_DATASOURCE_PLATFORM=derby -e MODE=standalone -e JVM_XMS=256m -e JVM_XMX=256m -p 8848:8848 -d nacos/nacos-server
这样给nacos一个限制 , 可以一定程度上缓解这个问题 , 如果实在不行 , 就尝试单独启动服务 , 或者更换一个内存更大的服务器 !
OK ! 已经大功告成 !
OK ! 已经大功告成 !
OK ! 已经大功告成 !
三大spring版本问题,版本一定要统一对应,以及子依赖版本
gateway模块依赖是不需要spring-cloud-starter-web的,而父工程和spring-cloud-starter-gateway里面包含了web依赖,需要剔除,其次注意gateway依赖中还包含了spring-boot-starter-webflux
引入feign依赖时还需要引入spring-cloud-starter-loadbalancer和它的父依赖spring-cloud-commons
如果是配合nacos使用的,还需要将nacos中的spring-cloud-starter-netflix-ribbon排除掉
先上图,这里的注解里面使用name和value属性都可以,但是path最好加上,填写被调用的类的路径前缀,否则就必须在GetMapping中写上完整路径
服务器内存尽可能的大一些,否则在部署微服务时可能会因为内存不足导致部署失败
nacos在运行时可以加以限制,如果还不行就单独启动各个服务
这里我就是单独启动了三个服务完成了测试哈哈~