javascript
JSD-2204-续Docker命令-布隆过滤器的测试-秒杀业务完善-ELK-配置中心-Day18
1.續(xù) Docker命令
1.1ps命令
docker ps可以查看當前docker中運行的所有容器的狀態(tài)
ps命令中常見的選項如下:
- -a:顯示所有容器,如果不加只顯示正在啟動運行的容器,停止的不會顯示。
- -l:顯示最近的啟動創(chuàng)建的容器。
- -n=[數字]:顯示最近n個容器。
- -q:只顯示容器id。經常和-a一起使用,獲得當前宿主機所有容器id參數集合。
ps命令顯示的標題內容如下
- container id:容器id,很多操作容器命令都需要用到的參數。
- image:容器創(chuàng)建使用的鏡像。
- command:容器中在運行的進程或者命令。
- created:創(chuàng)建時間。
- status:容器狀態(tài)。
- ports:容器的端口映射情況,這里沒有用到端口。
- names:容器的名字,啟動沒有指定--name選項,會默認使用一個名字。
1.2stop\rm命令
docker stop?可以停止正在運行的容器
stop只是停止容器.并不會刪除容器
如果想刪除容器需要使用rm命令
注意:這里rm刪除的是容器,不是本地鏡像,和rmi命令要區(qū)分
首先使用docker ps命令查詢所有正在運行的容器
docker stop [容器id] docker rm [容器id]rm的選項有:
-f:強制刪除容器,無論是否運行,如果不加,運行的容器無法刪除。
1.3啟動redis
搜索redis
拉取鏡像參考之前的筆記
自己搜docker啟動Redis的命令
docker run -itd --name redis-test -p 6379:6379 redis啟動之后可以本地訪問客戶端
docker exec -it redis-test redis-cli1.4關閉防火墻
如果當前windows系統(tǒng)要連接Linux中的資源
一般都要關閉Linux的防火墻
實際開發(fā)中,不會徹底關閉防火墻,而是開放指定的端口號
systemctl stop firewalldsystem:系統(tǒng)
ctl:control:控制
2.酷鯊商城前臺虛擬機
給大家的大壓縮包
Virtualbox 4.15G
VMware 3.55G
解壓之后啟動
Linux:
用戶名:root
密碼:12345678(不要用小鍵盤)
啟動后使用
ifconfig | more觀察ip地址
可以利用HS嘗試連接虛擬機的數據庫
一般情況下ip地址為:192.168.137.150
數據庫密碼是:
tarena2017Up;
注意分號也是密碼的一部分,不寫連不上
注意如果需要停止虛擬機,選擇快速休眠,不要關機
2.1酷鯊商城前臺項目配置修改
因為現(xiàn)版本酷鯊商城連接的都是本地項目
下面我們要連接的是虛擬機軟件,所以要修改一下java項目的配置文件
front
addr: 192.168.137.150mall-leaf
leaf.properties
leaf.jdbc.url=jdbc:mysql://192.168.137.150:3306/leafdb?useUnicode=true&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=trueleaf.jdbc.password=tarena2017Up;mall-order
addr: 192.168.137.150password: tarena2017Up;mall-product
addr: 192.168.137.150password: tarena2017Up;mall-search
addr: 192.168.137.150mall-seckill
addr: 192.168.137.150password: tarena2017Up;rabbitmq:host: ${my.server.addr}port: 5672username: userpassword: 123456virtual-host: /mall-sso
addr: 192.168.137.150 # 有兩個密碼要改!!!!adminpassword: tarena2017Up;userpassword: tarena2017Up;2.2布隆過濾器的測試
因為上面我們啟用了虛擬機
我們在虛擬機中安裝的redis是一個特殊版本的Redis
這個版本內置了lua腳本,支持布隆過濾的方法
我們可以直接使用,實現(xiàn)布隆過濾器
csmall-stock-webapi的pom文件?添加依賴
<!-- redis依賴 --> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId> </dependency>在dev-yml文件中添加redis的配置
spring:redis:host: 192.168.137.150port: 6379password:操作布隆過濾器有一個專門的類
實現(xiàn)對布隆過濾器的新增元素,檢查元素等方法的實現(xiàn)
在酷鯊前臺大項目中的seckill-webapi下的utils包里
RedisBloomUtils類復制到需要使用布隆過濾器的項目中
當前Stock模塊
有一個周期輸出時間的方法
我們可以借助這個運行,測試布隆過濾器的功能(如果這個方法已經編寫了別的代碼可以先注釋掉)
quartz包下QuartzJob
// 操作支持布隆過濾器redis的對象 @Autowired private RedisBloomUtils redisBloomUtils;@Override public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {// 實現(xiàn)一個簡單的任務做演示// 例如輸出當前時間System.out.println("-------------------"+ LocalDateTime.now() +"--------------------");// 先定義要保存到布隆過濾器的元素數組String[] colors={"red","origin","yellow","green","blue","pink","white"};// 執(zhí)行向布隆過濾器中保存上面數組元素的指令final String COLOR_BLOOM="color_bloom";redisBloomUtils.bfmadd(COLOR_BLOOM,colors);// 下面開始檢查一個指定的字符串是否在布隆過濾器中String elm="zhanghl";// 判斷該元素是否在數組中System.out.println(elm+"是否在定義的數組中:"+redisBloomUtils.bfexists(COLOR_BLOOM,elm)); }3.秒殺業(yè)務完善
3.1秒殺準備時加載布隆過濾器
我們在開發(fā)秒殺業(yè)務時,事先進行了準備工作
在秒殺開始前5分鐘,預熱了sku的庫存數和spu的隨機碼
但是沒有將當前批次的spuId保存在布隆過濾器中
導致業(yè)務有漏洞
現(xiàn)在,我們準備了支持布隆過濾器的Redis
我們可以將允許用戶查詢到的秒殺商品,保存到布隆過濾器中
這樣非當前秒殺商品,用戶就不能查詢數據庫了,防止緩存穿透
在seckill-webapi模塊中
seckill.timer.job包中,新建SeckillBloomInitialJob
public class SeckillBloomInitialJob implements Job {@Autowiredprivate RedisBloomUtils redisBloomUtils;@Autowiredprivate SeckillSpuMapper seckillSpuMapper;@Overridepublic void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {// 首先查詢下個批次的所有數據// 有需求要求查詢兩個批次或更多批次的數據// 因為可能允許更多批次的商品被用戶提前瀏覽// 我們可以預熱今天和明天的秒殺商品(我們的需求是一天一批)// 獲取今天的key(正在進行秒殺的商品)// "spu:bloom:filter:2022-09-13"String bloomTodayKey= SeckillCacheUtils.getBloomFilterKey(LocalDate.now());// 獲取明天的keyString bloomTomorrowKey=SeckillCacheUtils.getBloomFilterKey(LocalDate.now().plusDays(1));// 實際開發(fā)中,可以按照實際去查詢對應批次的所有秒殺商品// 學習過程中因為數據庫數據量少,所以只查詢同一批次即可// 根據時間,查詢在這個時間正在進行秒殺的商品的所有id數據Long[] spuIds=seckillSpuMapper.findAllSeckillSpuIds();// 布隆過濾器支持保存的是字符串數組// 所以我們要將Long[]轉換成String[]String[] spuIdsStr=new String[spuIds.length];// 遍歷spuIds,將其中元素轉換賦值到spuIdsStrfor(int i=0;i<spuIds.length;i++){spuIdsStr[i]=spuIds[i]+"";}// 將賦值完畢的字符串數組數據保存到布隆過濾器中// 實際開發(fā)應該按照對應的批次保存,學習過程中就不分批次了redisBloomUtils.bfmadd(bloomTodayKey,spuIdsStr);redisBloomUtils.bfmadd(bloomTomorrowKey,spuIdsStr);System.out.println("兩個批次的布隆過濾器加載完成");} }下面在seckill.timer.config包中添加布隆過濾器相關的調度配置
繼續(xù)在QuartzConfig類中添加綁定信息
// 布隆過濾器的加載 @Bean public JobDetail seckillBloomJobDetail(){return JobBuilder.newJob(SeckillBloomInitialJob.class).withIdentity("SeckillBloom").storeDurably().build(); } @Bean public Trigger seckillBloomTrigger(){return TriggerBuilder.newTrigger().forJob(seckillBloomJobDetail()).withIdentity("SeckillBloomTrigger").withSchedule(CronScheduleBuilder.cronSchedule("0 0/1 * * * ?")).build(); }下面可以測試布隆過濾器的運行
保證虛擬機啟動正常
啟動product\seckill
如果沒有虛擬機的同學,敲一遍代碼熟悉即可
3.2布隆過濾器判斷spuId是否存在
現(xiàn)在Redis中保存了布隆過濾器
我們需要用戶根據SpuId查詢商品時,進行判斷和過濾
如果spuId不存在,就應該發(fā)生異常,給出提示
SeckillSpuServiceImpl類中getSeckillSpu進行修改,添加布隆過濾器的判斷
@Autowired private RedisBloomUtils redisBloomUtils; // 根據SpuId查詢Spu詳情(包含秒殺信息和spu普通信息) @Override public SeckillSpuVO getSeckillSpu(Long spuId) {// 先使用布隆過濾器對參數有spuId進行判斷// 如果判斷結果是spuId不存在于數據庫中,直接拋出異常// 獲得本次布隆過濾器的KeyString bloomTodayKey=SeckillCacheUtils.getBloomFilterKey(LocalDate.now());log.info("當前批次布隆過濾器的key為:{}",bloomTodayKey);if(!redisBloomUtils.bfexists(bloomTodayKey,spuId+"")){// 進入這個if表示當前spuId不在布隆過濾器保存的數據中// 為了防止緩存穿透,拋出異常,終止程序throw new CoolSharkServiceException(ResponseCode.NOT_FOUND,"您訪問的商品不存在(布隆過濾器判斷)");}// 聲明返回值類型的對象SeckillSpuVO seckillSpuVO=null;// 其它代碼無變化略...... }重啟Seckill模塊
訪問10007
查詢SpuId如果不存在于秒殺表中,是否能被過濾器攔截
4.ELK簡介
4.1什么是ELK
ELK:
E:Elasticsearch?全文搜索引擎
L:logstash?日志采集工具
K:Kibana ES的可視化工具
ELK是當今業(yè)界非常流行的日志采集保存和查詢的系統(tǒng)
我們編寫的程序,會有很多日志信息,但是日志信息的保存和查詢是一個問題
idea控制臺是臨時顯示的位置,我們可以將它保存在文件中
但是即使保存在文件中,海量日志信息要想查詢需要的條目也是問題
所以我們使用ELK來保存
4.2為什么需要ELK
保存并能夠快速便捷的查詢查看日志信息就是新出現(xiàn)的需求了
ELK這個組合可以完成這個任務
Elasticsearch負責將日志信息保存,查詢時可以按關鍵字快速查詢
那么這些日志怎么收集呢?
利用logstash這個軟件可以監(jiān)聽一個文件,將這個文件中出現(xiàn)的內容經過處理發(fā)送到指定端口
我們就可以監(jiān)聽我們程序輸出的日志文件,然后將新增的日志信息保存到ES中
Kibana來負責進行查詢和查看結果
日志的管理工具還有一套叫鏈路追蹤
和ELK有類似的效果,感興趣的同學可以自己搜索
4.3Logstash
4.4什么是logstash
Logstash是一款開源的日志采集,處理,輸出的軟件,每秒可以處理數以萬計條數據,可以同時從多個來源采集數據,轉換數據,然后將數據輸出至自己喜歡的存儲庫中(官方推薦的存儲庫為Elasticsearch)
上面圖片數據源可以是任何產生數據的介質,數據庫,redis,java的日志文件均可
輸出目標一般也是能夠保存數據的媒體,數據庫,redis,ES等
LogStash內部有3個處理數據的步驟
- input 將數據源的數據采集到Logstash
- filter (非必要)如果需要可以對采集到的數據進行處理
- output 將處理好的數據保存到目標(一般就是ES)
其中采集數據的用法比較多樣,還支持各種插件
4.5logstash實現(xiàn)數據庫和ES數據的同步
logstash還有一個非常常見的用法
就是能夠自動完成數據庫數據和ES中數據的同步問題
實現(xiàn)原理
我們可以配置logstash監(jiān)聽數據庫中的某個表
一般設計為監(jiān)聽表中數據的變化,在規(guī)范的數據表結構中,logstash可能監(jiān)聽gmt_modified列
只要gmt_modified列數據有變化,就收集變化的數據行,將這行數據的信息更新到ES
下面我們就在虛擬機環(huán)境下實現(xiàn)搜索操作
4.6實現(xiàn)虛擬機ES搜索功能
之前我我們已經修改了yml文件,將搜索的目標更換為虛擬機中的ES
在虛擬機的連接環(huán)境中,我們使用SpuEntity來實現(xiàn)ES的連接
我們可以看到SpuEntity類中沒有任何編寫分詞的屬性
原因是為了更高效的實現(xiàn)分詞,logstash將所有需要分詞的列拼接組合成了一個新列search_text
?
當需要查詢時只需要查詢search_text字段即可
4.7添加新的持久層
在search-webapi模塊中的repository包下,創(chuàng)建新的持久層接口SpuEntityRepository
@Repository public interface SpuEntityRepository extendsElasticsearchRepository<SpuEntity,Long> {// 根據用戶輸入的關鍵字查詢ES中匹配的數據// Logstash將所有查詢字段拼接成了search_text字段,SpuEntity并不存在// 所以我們的查詢直接搜索search_text,而且不能利用SpringData給的定義方法名查詢的功能@Query("{\"match\":{\"search_text\":{\"query\":\"?0\"}}}")Page<SpuEntity> querySearchByText(String keyword, Pageable pageable);}4.8業(yè)務邏輯層接口
因為實體類泛型類型的變化
ISearchService接口中的返回值泛型也要修改一下
public interface ISearchService {// ES分頁查詢spu的方法// ↓↓↓↓↓↓↓↓↓↓↓JsonPage<SpuEntity> search(String keyword, Integer page, Integer pageSize);// 向ES中加載數據的方法void loadSpuByPage(); }4.9實現(xiàn)業(yè)務邏輯層代碼
原來的業(yè)務邏輯層實現(xiàn)類,要廢棄,可以刪除
如果不想刪除也要把之前代碼注釋,還有必須刪除@Service注解
原有SearchServiceImpl修改為
//@Service //@Slf4j @Deprecated public class SearchServiceImpl {// 其中所有代碼均可注釋 }新建SearchRemoteServiceImpl實現(xiàn)ISearchService接口,代碼如下
// 實現(xiàn)查詢遠程服務器(虛擬機Linux系統(tǒng))ELK系統(tǒng)的業(yè)務邏輯層 @Service @Slf4j public class SearchRemoteServiceImpl implements ISearchService {@Autowiredprivate SpuEntityRepository spuEntityRepository;@Overridepublic JsonPage<SpuEntity> search(String keyword, Integer page, Integer pageSize) {// 執(zhí)行調用按關鍵字進行查詢的方法Page<SpuEntity> spuEntities=spuEntityRepository.querySearchByText(keyword, PageRequest.of(page-1,pageSize));// 將Page<SpuEntity>轉換為JsonPage<SpuEntity>JsonPage<SpuEntity> jsonPage=new JsonPage<>();// 賦值相關分頁信息jsonPage.setPage(page);jsonPage.setPageSize(pageSize);//總條數和總頁數jsonPage.setTotal(spuEntities.getTotalElements());jsonPage.setTotalPage(spuEntities.getTotalPages());// 將查詢到的數據賦值到jsonPagejsonPage.setList(spuEntities.getContent());// 最后別忘了返回return jsonPage;}// 加載和同步數據完全由logstash完成,無需編寫下面加載數據的方法@Overridepublic void loadSpuByPage() {} }4.10修改控制層代碼
修改SearchController中的代碼
// ↓↓↓↓↓↓↓↓↓↓↓ public JsonResult<JsonPage<SpuEntity>> searchByKeyword(String keyword,Integer page, Integer pageSize){// ↓↓↓↓↓↓↓↓↓↓↓JsonPage<SpuEntity> jsonPage=searchService.search(keyword,page,pageSize);return JsonResult.ok(jsonPage); }啟動product/passport/search
先進行jwt登錄的復制,復制到search模塊的全局參數中
可以搜索手機查詢效果
啟動虛擬機
如果不能查詢出數據庫中正確的對應的信息
需要在數據庫工具軟件中運行下面代碼
USE mall_pms; UPDATE pms_spu SET gmt_modified=NOW() WHERE 1=1;以激活logstash對spu表的監(jiān)聽,并向ES中保存數據
這個操作可能有些延遲,稍等即可
再次查詢,就有能夠正確搜索信息了!
4.11Logstash下ES的運行流程
安裝配置好相關軟件后
logstash會自動監(jiān)聽指定的表(一般指定監(jiān)聽gmt_modified列)
當gmt_modified列值變化時,logstash就會收集變化的行的信息
周期性的向ES進行提交
數據庫中的變化的數據就會自動同步到ES中了
這樣,我們在程序中,就無需編寫任何同步ES和數據庫的代碼
5.配置中心
5.1什么是配置中心
所謂配置中心:將項目需要的配置信息保存在配置中心,需要讀取時直接從配置中心讀取,方便配置管理的微服務工具
我們可以將部分yml文件的內容保存在配置中心
一個微服務項目有很多子模塊,這些子模塊可能在不同的服務器上,如果有一些統(tǒng)一的修改,我們要逐一修改這些子模塊的配置,由于它們是不同的服務器,所以修改起來很麻煩
如果將這些子模塊的配置集中在一個服務器上,我們修改這個服務器的配置信息,就相當于修改了所有子模塊的信息,這個服務器就是配置中心
使用配置中心的原因就是能夠達到高效的修改各模塊配置的目的
5.2配置中心的使用
Nacos既可以做注冊中心,也可以做配置中心
Nacos做配置中心,支持各種格式\類型的配置文件
properties\yaml(yml)\txt\json\xml等
5.3Nacos數據結構
 
 
namespace:命名空間
group:分組
Service/DataId:具體數據
命名空間
namespace是Nacos提供的最大的數據結構
一個Nacos可以創(chuàng)建多個命名空間
一個命名空間能夠包含多個group
每一個group中又可以包含多條配置信息
在nacos中創(chuàng)建命名空間
?
在上圖連接的位置可以新增命名空間,填寫命名空間名稱和描述即可
Nacos有默認的命名空間public不能刪除和修改
添加命名空間后,我們在Nacos中注冊的服務或添加的配置就可以指定命名空間了
因為多個命名空間可以隔離項目,每個項目使用自己的命名空間,互不干擾
分組
一個命名空間中可以有多個分組,進行進一步分離
我們使用時,如果不需要進一步分組,推薦使用group名稱:DEFAULT_GROUP
服務或配置
確定了命名空間和分組之后
我們就可以添加服務或配置了
之前我們啟動的各種模塊都是服務,之前都是默認保存在public命名空間中
下面我們主要使用配置中心的功能,在命名空間中添加配置
添加配置就是設置DataId
實際在Nacos中定位一個配置的結構為
Namespace>Group>DataId
5.4Nacos添加配置
Nacos首頁->配置管理->配置列表->添加配置(右側的大"+"號)
添加cart模塊數據庫連接配置
?
總結
以上是生活随笔為你收集整理的JSD-2204-续Docker命令-布隆过滤器的测试-秒杀业务完善-ELK-配置中心-Day18的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: Android计算器(计算表达式,能计算
- 下一篇: ol4通过ImageCanvas实现大量
