多台机器相同的代码 来提供同一个服务
多台机器就是集群
服务与服务之间的调用是分布式的 但是集群内部未必是分布式的
https://vagrantcloud.com/centos/7
vagrant box add centos/7 CentOS-7-x86_64-Vagrant-1905_01.VirtualBox.box
169.254.49.111
sudo yum remove docker
docker-client
docker-client-latest
docker-common
docker-latest
docker-latest-logrotate
docker-logrotate
docker-engine
启动一个容器
docker run -itd redis:latest
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
docker run -p 6379:6379 --privileged=true --name redis
-v /home/docker/redis/redis.conf:/root/redis/redis.conf
-v /home/docker/redis/data:/data
-d --restart=always redis:latest redis-server --appendonly yes --requirepass " zhangsan2019@"
docker run -p 6379:6379 --privileged=true --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
–appendonly yes --requirepass “123456”
阿里云远程连接 要配置安全组开放端口,还要在防火墙把端口放出来
创建项目
项目启动 nacos
首先启动nacos
然后访问nacos服务可视化网址
http://127.0.0.1:8848/nacos/#/configurationManagement?dataId=&group=&appName=&namespace=
application:
name: renren-fast
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
pom.xml里加上common依赖, 修改jdk版本,
开启注册服务发现@EnableDiscoveryClient
nacos服务注册发现中心地址
是applicaion.properties
主要写明自身服务端口好以及名字即可 主要用于服务发现
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
spring.application.name=gulimall-gateway
server.port=88
bootstrap.properties
填写nacos配置中心地址
和命名空间等隔离服务的nacos配置功能
spring.application.name=gulimall-gateway
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
spring.cloud.nacos.config.namespace=bfa85f10-1a9a-460c-a7dc-efa961b45cc1
申请完商品服务的命名空间id 我们写到代码的配置文件中作为关联
以后直接修改nacos的配置即可
在服务管理当中申请服务的命名空间去代码配置文件关联
之后在配置中就可以在该命名空间下配置 yml或者properties
打开数据库
e:
vagrant up
vagrant ssh
sudo docker ps
打开网关 所有请求都经过网关
打开人人fast +vue 前后端都打开要操作后台 npm run dev启动前端
后台操作商品管理CRUD就要把对应的 商品服务打开
nginx
一定要访问域名 如果是在本地重定向 访问的本机地址:端口号 这种没走域名 前端的静态资源就不会显示
访问域名跳转到指定的服务器 可以在windows的host中进行配置
DNS在寻找域名对应的服务器的时候也是最先从host出发
配置本项目对外提供的域名 以及对应的服务器
但并不是域名配置完成直接就请求到服务器 公司的服务器是内网的 不向外暴露自己的 客户端无法直接访问 需要使用nignx反向代理 nignx与公司服务器在同一内网下
nignx去处理所有的请求 并带上域名将请求转发到网关 网关交给对应的微服务
nignx还有静态资源的功能
我们将所有的静态资源都放到nignx里
现在nginx里面已经有了静态资源 我们在nginx的设置当中把所有对static的请求都跳转到nginx里
然后将所有的请求替换到static
业务相关
attr_group
catelog都是类型
可以新增 属性 和 属性组
bug逻辑记录
我遇到这个问题
还以为找到了原因 后来还把主键给改成string类型的 char了
但主键最好是用int 用string就很难自增了 varchar要先二进制转换然后+1的ASCII码作为主键
所以以为自己解决了其实是没解决
应该还是用LONG 但是将自增的属性从1开始重置 auto_increment
即使到了主键自增的最大值 在这之前我们就已经分库分表了 所以没问题(面试之自增不够用怎么办)
重新设置下表的自增属性 auto_increment 就会从你希望的id开始自增
如果已经设置数据库主键自增 在写sql的时候就不为主键赋值 同样的在服务器端也不要Set主键值
前端打到服务器的json请求 id那一栏也是空的 到数据库层面会自己加上
选中三级分类修改 前端没有把catid回显出来 导致更新的时候没有catid 无法修改
数据库表自增这个事 http://www.360doc.com/content/19/0805/23/65638213_853212476.shtml
每次设置完自增的新的步长 很快就又变成max()+1 自增的值并不是连续的
由于是最大值 数字太长 又导致了JS失去精度四舍五入
所以存入数据库的时候是13156412598 但是经过前端的JS显示后就变成13156412600
导致选中13156412600 删除的时候 数据库中没有这个ID 无法删除
所以还是应该使用STRING 来存储ID
又或者我每次手动的改
业务逻辑
写代码记得先理清思路 然后写controller层 一层一层的往回写 先写外层 使用alt+enter在Serivice生成
- 在写service时尽量减少查询数据库的次数 可以一次数据库查询然后使用流操作或者逻辑操作来获得其他想从数据库中获得的信息
- 而且很喜欢用lamda的map来返回自己想要获得的东西 其实这是很普遍的
不要进行多表联查取获取另一个表的字段 而是用map->{ }在括号里以A表的ID 取B表单表查询 然后总结返回结果 - 使用场景 RespVo 返回结果VO的形成 就可以使用这个
List<AEntity> as=getRequest();
List<Bentity> bs=as.stream.map(
(a)->{
Bentity b=new Bentity();
操作(比如b.setName(a.setName))
return b;}
).collect(Collectors.toList());
刷新之后 查看交互数据
访问网关和人人后台管理项目发现
客户端登陆页面
请求会通过前端上图配置打到网关管理
但是网关将客户端的http url修改为请求到renren的后台controller代码的url
最后看到属于后台代码功能的验证码 已经显示了 功能可用
说明网管已经帮助客户端请求到人人后台代码
P53
查看最新的节点信息 比如客服A进入后台修改了
5分钟后B来又修改了 但是A10分钟后过来获取的还是A修改的
因为前端显示并没有获得最新的数据
而是根据当前A的token 登陆后台显示的还是A一开始点击页面显示的而不是最新的
把调用第三方服务的服务都写在一个服务里 命名为gulimall-third-party
在nacos里写配置文件 都是面向第三方服务的 毕竟第三方服务的变化多配置文件也经常变化 所以我们配置在nacos的配置文件中
学到新知识
TIPS:
服务端接收前端的请求参数 通常为了方便我们接收VO
但是业务代码操作传递过来的参数时 还是要操作数据库ENTITY
最后返回一个RESPVO 供页面使用
controller 只有三句话
1校验JR303
2调用service 封装控制层想要的数据
3处理返回结果 返给页面
-
数据库字段要加上deleted(是否逻辑删除) gmt_creted gmt_modified 阿里开发手册
-
BeanUtils.copyProperties(attr,attrEntity); 源数据 复制给谁 spring 的工具类
-
为什么有一次请求两个记录 因为一次是域检 第二次才是真正携带数据的请求
写配置类的时候不要忘了加@configration注解
真正很少删除数据库的记录 而是选择设置一个标志位boolean 去标识删除
逻辑删除强过物理删除 这也是建表的一个技巧 下图就是删除代表
mybatis plus逻辑删除
mybatis-plus:
mapper-locations: classpath:/mapper/**/*.xml
global-config:
db-config:
id-type: auto
logic-delete-field: flag # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2)
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
代码技巧
json指定类型转换 TypeReference
Map<String,List<Catelog2Vo>> result = JSON.parseObject(catalogJSON,new TypeReference<Map<String,List<Catelog2Vo>>>(){});
善用java8 map
- 不要联查数据库 如果想要这个数据库返回的id 去查另一个数据库获取值
以前会两个表join 现在要分步查询 查到id收集起来再查询第二个
- 如果是除去这些id 查询别的 还可以用filter+set来过滤第二个数据流
- 组装vo的时候 为什么常常用beanutils就是这么回事 而且以后再形成VO的时候
善于使用map组装
@Override
public void saveGroupCateRelation(List<AttrGroupRelationVo> attrGroupRelationVos) {
List<AttrAttrgroupRelationEntity> relationEntityList = attrGroupRelationVos.stream().
map((attrGroupRelationVo -> {
AttrAttrgroupRelationEntity attrAttrgroupRelationEntity = new AttrAttrgroupRelationEntity();
BeanUtils.copyProperties(attrGroupRelationVo, attrAttrgroupRelationEntity);
return attrAttrgroupRelationEntity;
})).collect(Collectors.toList());
if (relationEntityList != null && relationEntityList.size() > 0) {
this.saveBatch(relationEntityList);
}
}
- list转map 在进行list< obj >的数据进行重新排版id 对应什么值 的时候可以使用list转map
toMap()里面是function函数式接口
list.stream().collect(Collect.toMap(item->item.getid(),value->value.getObj))
将库存系统的skuid和是否还有库存值写入map 因为调用远程服务可能会有网络波动 所以都会加try catch 最后在后面判断是否map有值 是否有库存就可以设置布尔值
5. 还可以用map来做日志记录
上面这个map的代码 每一次都会查询数据库 这是非常耗时的 尽量遵循查询一次数据库 然后对返回值操作获取新值
查询数据库是非常耗时的 加索引 少与数据库交互都是改变性能的
redis
在redis中存储的格式一定是json 如果不是json 也一定要存储的是序列化的entity
将服务器的内存对象 远程保存到redis 服务器里边 需要网络传输 所以我们要把传输的数据序列化成一个二进制的流或者串 默认是JDK序列化
前后端交互流程
remove真正有效要前端向后端发送请求
@REQUESTBODY 注解是必须发送post请求
什么是token==
JR303
@NotNull 不可以为空 就是不能传递 null 举例不能传递( , “”) 逗号左侧就是空null 右侧就是empty 适合啥也不写
@NotEmpty 不可以为空 也不可以为empty (""," ") 左侧就是空 长度必须大于0 适合填了就
@NotBlank 要求严格在trim过后仍然长度>=1 适合必填而且对于内容有要求
JSR303 https://zhuanlan.zhihu.com/p/69663614
单纯一个注解是无法生效的 需要搭配校验器才可有效
A是关联什么注解 T是该注解校验器修饰的 参数属性是什么
JR303只是一种规范 真正实现的框架是herbinate validator
在controller 类的requestmapping 加上valatied 注解代表对于该entity 字段的校验标识
自定义校验注解还要搭配校验器与之配对
需要对于统一的异常处理进行返回错误信息说明 json拼装 可以搭配使用Controlleradvice 他的搭配发现注解是enablehandller
sql
一个参数不用标注 多个参数一定要写@param
编写的时候先在数据库里模拟sql 查找出来的列和dto要查出来的属性值最好相同
所以可以写别名
然后在mapper中将sql中赋值的地方替换为 #{}
测试
自己封装mapper 的返回类型Resultmap 带集合
代码技巧 封装类型 Integer Long
上述代码 如果count 写long 那么当查询返回为null时就会无法匹配抛异常
同时下面的count>0也是错误的 如果Long此时为null
null==count?false:count>0;
打断点
打断点可以在启动后再打呢 可以使用这个绿色的 含义是放行断点直到下一个断点
如果跳入到内层源码想要跳出来 就回到初始地方 立刻打一个断点 然后摁上面的按钮
idea操作
查看TODO地方
抽取方法
自启动
指向了网关
请求过来 先到虚拟机中 nginx监听到80端口的gulimall.com服务过来了
就转发到代理网关 因为再转发过程中会丢失host信息 所以会再location上面加上
现在请求转发到网关 网关负责分发
来自于nginx转发过来的请求我们要再网关配置文件中进行路径的重组
jmeter使用