微服務(wù)架構(gòu)
微服務(wù)
強(qiáng)調(diào)是一個服務(wù)的大小,關(guān)注的是一個點(diǎn)
專注個體,每個個體完成一個具體的任務(wù)或功能
微服務(wù)架構(gòu)
一種架構(gòu)模式择诈,單一應(yīng)用劃分一組小的服務(wù),服務(wù)之間相互配合出皇,為用戶提供最終價值羞芍。
SpringCloud和SpringBoot區(qū)別?
SpringBoot專注于快速方便的開發(fā)單個個體服務(wù)郊艘;
SpringCloud關(guān)注全局微服務(wù)的協(xié)調(diào)和整理荷科,它將SpringBoot開發(fā)的一個個單體微服務(wù)整合起來;
SpringBoot可以獨(dú)立使用開發(fā)纱注,但是SpringCloud離不開SpringBoot畏浆,屬于依賴關(guān)系;
SpringBoot屬于一個科室狞贱,SpringCloud是綜合醫(yī)院
Spring boot跨域
Controller 類 加 @CrossOrigin
mybatis-plus配置 mapper xml
mybatis-plus:
mapper-locations: classpath:mybatis/mapper/*.xml mybatis/mapper
前端數(shù)組對象傳遞
使用axios發(fā)出跨域請求刻获,跟的參數(shù),不允許是數(shù)組的格式
xxx?ids=[7,9]瞎嬉!也就是
不能使用 paramrs: JSON.stringfy(array)
改為xxx?0=7&1=9
解決方案
springmvc /springboot 接收List 入?yún)xu990128638的專欄-CSDN博客_springboot接收list參數(shù)
qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'indices' })
// 'a[0]=b&a[1]=c'
qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'brackets' })
// 'a[]=b&a[]=c'
qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'repeat' })
// 'a=b&a=c'
方案1
npm install qs
import qs from 'qs'
paramrs: qs.stringfy(array)
// 請求 url,get請求,參數(shù)projectIds和 controll方法對應(yīng)
http://192.168.0.182:8088/Artilce/xxx?projectIds=1,2,3
// controller方法
@RequestMapping("/analysis")
public JsonResult queryList ( @RequestParam("projectIds") List<Long> projectIds) {
...
}
方案二
post方式
// 發(fā)出post請求蝎毡,數(shù)據(jù)格式 json
{
"projectIds":[2,3]
}
// controller
@RequestMapping("/analysis")
public JsonResult queryList (@RequestBody ReqVo req) {
....
}
@Data
Class ReqVo {
private List<Integer> projectIds;
}
Redis緩存引入
依賴引入
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</art factId>
</dependency>
配置redis
server:
port: 8002
spring:
application:
name: edu-course-boot
redis:
host: 192.168.204.141
port: 6379
redis放在service層
- redis查詢數(shù)據(jù)
- redis沒有,去mysql查詢
- 將查詢結(jié)果緩存在redis中
@Service
public class CourseServiceImpl implements CourseService {
@Autowired
private CourseMapper courseMapper;
@Autowired
private RedisTemplate<Object,Object> redisTemplate;
@Override public List<Course> getAllCourse() {
//將redis內(nèi)存中的序列化的集合名稱用String重新命名(增加可讀性)
RedisSerializer rs = new StringRedisSerializer();
redisTemplate.setKeySerializer(rs);
System.out.println("查詢redis");
List<Course> list =
(List<Course>)redisTemplate.opsForValue().get("allCourses"); if(list == null){
//去數(shù)據(jù)庫
System.out.println("====MySql數(shù)據(jù)庫====");
list = courseMapper.getAllCourse();
// 把從數(shù)據(jù)庫查詢的集合放在redis內(nèi)存中(key,value,過期秒數(shù),秒的工具類)
redisTemplate.opsForValue().set("allCourses", list,10, TimeUnit.SECONDS);
}
return list;
}
高并發(fā)下的雙層檢測鎖
@Override
public List<Course> getAllCourse() {
RedisSerializer rs = new StringRedisSerializer(); redisTemplate.setKeySerializer(rs);
System.out.println("查詢redis");
List<Course> list =(List<Course>)redisTemplate.opsForValue().get("allCourses");
// 第一次檢測
if(list == null){
//排隊(duì)氧枣,讓第一個人進(jìn)沐兵,走一遍流程(后面的人就會走緩存了)
synchronized (this){
list = (List<Course>)redisTemplate.opsForValue().get("allCourses");
// 第二次檢測
if(list == null){
//去數(shù)據(jù)庫
System.out.println("====MySql數(shù)據(jù)庫====");
list = courseMapper.getAllCourse();
// 把從數(shù)據(jù)庫查詢的集合放在redis內(nèi)存中
redisTemplate.opsForValue().set("allCourses", list,10,TimeUnit.SECONDS);
}
}
}
return list;
}
保證redis中數(shù)據(jù)最新
- 如果課程中內(nèi)容發(fā)生變化,更新 挑胸,修改內(nèi)容的時候痒筒,會先將redis中的相關(guān)集合刪除宰闰。
- 然后將最新的數(shù)據(jù)保存到數(shù)據(jù)庫 而查詢數(shù)據(jù)時茬贵,因?yàn)閞edis中的數(shù)據(jù)已經(jīng)刪除了,所以會第一時間去數(shù)據(jù)庫查詢移袍,保證數(shù)據(jù)是最新 的解藻。
三步解決 IDEA ‘Error:java: 無效的源發(fā)行版: 11’
三步解決 IDEA ‘Error:java: 無效的源發(fā)行版: 11’_Java持續(xù)實(shí)踐-CSDN博客
IDEA集成Docker部署微服務(wù)
docker 安裝配置
yum -y install docker
systemctl start docker
vim /lib/systemd/system/docker.service
# 修改
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix://var/run/docker.sock
systemctl daemon-reload
#重啟
service docker restart
# 查看端口是否開啟
netstat -nlpt
# 驗(yàn)證端口是否生效
curl http://192.168.204.141:2375/info
idea安裝docker插件
Tcp socket :tcp://ip:2375
setting —>docker Registry address :https://owi3yzzk.mirror.aliyuncs.com
連接服務(wù)器
docker mavne插件
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>1.0.0</version>
<configuration>
<!--鏡像名稱 laosun/test-docker-demo-->
<imageName>laosun/${project.artifactId}</imageName>
<!--標(biāo)簽版本-->
<imageTags>
<imageTag>latest</imageTag>
</imageTags>
<!--基礎(chǔ)鏡像,相當(dāng)于Dockerfile里的from-->
<baseImage>openjdk:11.0.9.1-jdk-buster</baseImage>
<!--標(biāo)簽版本-->
<maintainer>laosun angiersun@lagou.com</maintainer>
<!--入口點(diǎn)葡盗,project.build.finalName就是project標(biāo)簽下的build標(biāo)簽下的filename標(biāo)簽內(nèi)容螟左,test-docker-demo-->
<!--相當(dāng)于啟動容器后,會自動執(zhí)行java -jar/test-docker-demo.jar-->
<entryPoint>["java", "-jar", "/${project.build.finalName}.jar"]</entryPoint>
<!--docker地址-->
<dockerHost>http://xxx:2375</dockerHost>
<!-- 這里是復(fù)制 jar 包到 docker 容器指定目錄配置 -->
<resources>
<resource>
<targetPath>/</targetPath>
<!--復(fù)制的根目錄觅够,target-->
<directory>${project.build.directory}</directory>
<!--把哪個文件上傳到docker胶背,相當(dāng)于Dockerfile里的add test-docker-demo.jar /-->
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
對項(xiàng)目進(jìn)行打包并構(gòu)建鏡像到docker上
mvn clean package docker:build