微服务进阶整合学习初级篇--谷粒商城
配置运行环境
- 安装虚拟机Vitural box
- 安装Vagrant(我理解为虚拟机的管理工具,可以帮助我们管理虚拟机,有点类似于宝塔)
- 安装完成之后,win+R启动命令提示行,输入vagrant,提示指令信息表明安装成功
- 安装完重启电脑
- 安装Linux环境,通过命令提示行,输入vagrant init centos/7安装linux操作系统,成功后在C盘下用户文件下会出现一个VagrantFile文件
- 通过输入 vagrant up正式安装linux环境,该过程可能比较慢
- 安装完成之后,vitural box会自动运行该虚拟机,默认使用的是ssh链接,默认账户名为vargant
- 通过vargant ssh命令行可以连接上Linux虚拟机
- 输入exit退出虚拟机
配置端口映射
- 这一步的主要作用是将虚拟机内的服务端口与本机的端口建立映射关系,从而达到外部访问本地对应端口,即可访问虚拟机中相应的服务端口。如图所示:
- 具体的转口短发设置,在vitural box中 设置-网络-高级-端口转发,如图所示
- 也可以通过配置IP信息,通过IP地址建立本机与虚拟机的链接, 具体步骤是找到 C盘-用户-用户名-Vagrantfile文件,编辑如下图:
将#号去掉,将该ip改成你本机下虚拟机的IP地址,可以通过win + R,输入IPConfig找到虚拟机的ip地址。 - 可以在vitural box中重启虚拟机,或者在命令行输入 vagrant reload重启,以加载配置文件
- 在本机ping虚拟机,以及在虚拟机ping本地,若成功,则表是配置网络成功。
操作系统下安装docker
- Linux centos操作系统下安装docker
- 根据提示安装必要的工具(没装过docker,装过docker需卸载旧版本docker),如图所示
- 安装docker
- 启动docker
- 设置docker开机自启动,通过输入 sudo systemctl enable docker配置启动
配置docker镜像加速
- 登录阿里云,找到镜像容器服务
- 按照步骤配置镜docker镜像
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-‘EOF’
{
“registry-mirrors”: [“https://magantt5.mirror.aliyuncs.com”]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
docker安装mysql
- 上docker官网找到对应的需要下载的mysql版本,通过 docker pull mysql:版本名下载指定版本的mysql。
- 启动mysql
# --name指定容器名字 -v目录挂载 -p指定端口映射 -e设置mysql参数 -d后台运行
sudo docker run -p 3306:3306 --name mysql \
-v /mydata/mysql/log:/var/log/mysql \
-v /mydata/mysql/data:/var/lib/mysql \
-v /mydata/mysql/conf:/etc/mysql \
-e MYSQL_ROOT_PASSWORD=root \
-d mysql:5.7
说说自己的理解,docker本身内部的一个个容器,如mysql,redis等等,它本身实际上是在linux操作系统下存在的,一个容器,其实是一个完整的系统。因此如果我们想通过外层linux访问docker里面相关容器的内容,我们就要建立端口映射,通过 : 建立大环境下的linux与容器之间的端口映射关系。同时,由于每个容器都是独立的,如果我们想要操作容器的某些文件,如我们想看mysql容器的日志文件,我们就得通过输入命令行,如 docker exec(进入容器) -it(以交互模式)mysql(容器名字或id)进入该容器进行查看,很麻烦,因此,通过-v的方式,将容器内部的文件挂载到linux大环境下,从而达到修改外部文件,即可完成对容器内部文件的修改。
- 通过docker ps可以查看当前容器的运行情况(切换到root权限下,不是root权限需要加sudo,通过su root可切换到root用户)
docker安装redis
- 执行docker pull redis,不加端口号表示安装最新版本的redis。
- 配置文件挂载以及端口映射
mkdir -p /mydata/redis/conf
touch /mydata/redis/conf/redis.conf
docker run -p 6379:6379 --name redis
-v /mydata/redis/data:/data
-v /mydata/redis/conf/redis.conf:/etc/redis/redis.conf
-d redis redis-server /etc/redis/redis.conf—在后台启动,使用redis.conf配置文件
- 配置持久化文件
#由于配置了文件挂载,因此我们只需要去linux大环境下更改配置文件即可
#在redis.connf中,通过appendonly yes 开起持久化配置选项
appendonly yes
- 重启redis容器,通过使用 docker restart (容器名)
项目前准备
配置maven环境
微服务初了解
Nacos服务注册中心
服务注册中心,可以理解为一个接受服务的平台,用于管理服务。服务注册到服务中心即可被发现调用
- 下载Nacos
- pom.xml引入Nacos坐标
- 启动Nacos(点击startup.cmd)
- 开启Nacos发现注解
@EnableDiscoveryClient
- 配置yml文件,将服务注册到Nacos
spring:
application:
name: mall-order
cloud:
nacos:
discovery:
server-addr: localhost:8848
- 启动服务项目,访问Nacos
- 查看服务项是否配置成功
Nacos配置中心
使用Nacos配置中心,可以统一的对微服务配置项进行管理,无需重新重启部署项目。
- 引入依赖 spring-cloud-starter-alibaba-nacos-discovery
- 创建bootstarp.yml/properties配置文件
- 配置bootstarp文件,该文件主要配置两个地方,一个是服务名,一个是服务地址
spring.application.name=mall-coupon
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
-
到相应的进行了引用的类上加上
@RefreshScope
注解
-
到Nacos上进行配置管理
(注:当项目中的配置文件配置与Nacos配置中心中的配置重复,优先使用Nacos配置中心的配置) -
补充:
- 命名空间做环境隔离。在bootstrap.propertis下配置
spring.cloud.nacos.config.namespace=
命名空间,指定特定环境下的文件配置。- 也可以每一个微服务单独做一个命名空间。做到服务之间的隔离。
OpenFeign远程调用
OpenFeign的作用就是用于远程调用不同服务的接口
- pom.xml导入OpenFeign坐标
- 编写远程调用的接口类,如:
/**
* 该接口用于远程调用其他服务的功能
* @FeignClient 声明调用哪一个服务
* */
@FeignClient("mall-coupon")
public interface CouponFeignService {
/**
* 远程服务的完整路径以及方法名
* */
@RequestMapping("/coupon/coupon/member/list")
public R membercoupons();
}
- springboot启动类申明调用的服务端口
@SpringBootApplication
@MapperScan("com.cloud.mail.member.dao")
#该注解的意思是允许该服务被注册和发现
@EnableDiscoveryClient
#声明远程调用的接口
@EnableFeignClients("com.cloud.mail.member.Feign")
public class MailMemberApplication {
public static void main(String[] args) {
SpringApplication.run(MailMemberApplication.class, args);
}
}
- 调用该接口即可
@Autowired
CouponFeignService couponFeignService;
/**
* 测试远程接口调用
* */
@RequestMapping("/coupons")
public R test(){
MemberEntity memberEntity = new MemberEntity();
memberEntity.setNickname("张三");
//远程服务的接口
R membercoupons = couponFeignService.membercoupons();
return R.ok().put("member",memberEntity).put("coupons",membercoupons.get("coupons"));
}
GateWay网关
网关的作用主要可以用于限流、鉴权、路由转发等
- 导入依赖jar包
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
- 配置网关配置
spring:
qpplication:
name: mail-gateway
cloud:
gateway:
routes:
- id: admin_route
# lb:负载均衡到哪个服务
uri: lb://renren-fast
#predicates:断言,所有形如/api/开头的请求,全部路由给叫uri的服务
predicates:
- Path=/api/**
#filters:路径重写。将请求地址为/api/……的请求路由地址转换成/renren-fast/的地址
filters:
- RewritePath=/api/(?<segment>/?.*), /renren-fast/$\{segment}
nacos:
server-addr: 127.0.0.1:8848
server:
port: 88
- springboot启动类开启注解,允许该网关服务被Nacos注册发现
@EnableDiscoveryClient
- gateway统一解决跨域问题
@Configuration
public class MallCorsConfiguration {
@Bean
public CorsWebFilter corsWebFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration corsConfiguration = new CorsConfiguration();
//1、配置跨域
corsConfiguration.addAllowedHeader("*");
corsConfiguration.addAllowedMethod("*");
corsConfiguration.addAllowedOrigin("*");
corsConfiguration.setAllowCredentials(true);
source.registerCorsConfiguration("/**",corsConfiguration);
return new CorsWebFilter(source);
}
}
基础篇遇踩坑总结
- 无法生成对应的bean,session注入失败
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'attrAttrgroupRelationController':
Unsatisfied dependency expressed through field 'attrAttrgroupRelationService';
nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'attrAttrgroupRelationService': Unsatisfied dependency expressed through field 'baseMapper';
nested exception is org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'attrAttrgroupRelationDao' defined in file
解决:
网上方法参考之后判定不是注解的问题,也不是没有exlude的问题。初步判定为springboot版本问题。将springboot版本从2.3.10降至2.1.8,springcloud从H版降至G版即可。注意springboot-springcloud-springcloud alibaba三者之间对应的版本关系
javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)
### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection; nested exception is com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure
The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
### The error may exist in com/cloud/mail/product/dao/CategoryDao.java (best guess)
### The error may involve com.cloud.mail.product.dao.CategoryDao.selectList
### The error occurred while executing a query
### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection; nested exception is com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure
解决:
查询网上攻略,说是jdk1.8版本导致SSL调用权限出现问题。只需要在连接数据库的时候,加上userSSL=false即可。无需到java.security中删除SSLV3协议。
- 注意equals以及==的关系。
解决:
==在基本数据类型比较的是值相等,在引用类型比较的是指针地址。equals本质上也是比较的指针地址,但是在String,Int等类中方法被重写,比较的是值。而且值得注意的是,Int类型范围是-128~127,超出这个封你为会重新创建一个对象。
***************************
APPLICATION FAILED TO START
***************************
Description:
Application failed to connect to Nacos server: ""
Action:
Please check your Nacos server config
解决:
springboot项目整合springcloud-alibaba-nacos-config时一旦导入配置中心来做配置管理时的jar时,就必须配置管理中心的地址,报以上错误就是因为没有在bootstrap.properties/yml文件中配置相关地址
- IDEA无法引用自己的类
解决:
清空缓存,重启即可
VM3455 htmlfile:8 Uncaught DOMException: Blocked a frame with origin
解决:
检查发现,在Feign接口上没有著名是调用的哪个服务,在FeignClient后应该写上需要调用的微服务接口才行,如:@FeignClient(“mall-coupon”)
failed to req API:/nacos/v1/ns/instance after all servers([localhost:8848]) tried: failed to req API:localhost:8848/nacos/v1/ns/instance. code:500 msg: java.net.ConnectException: Connection refused: connect
解决:
不知道什么问题,重启Nacos服务器即可。
Lombok注解@Builder建造者模式与MybatisPlus不兼容?在使用@Builder建造者模式,使用mybatisPlus返回该实体类List集合数据的时候,报如下错误:
Cannot determine value type from string 'xxxxxx'
解决:
1、不使用建造者模式,通过新建对象的方式创造对象。
2、添加无参构造和有参构造即可。