亚洲精品中文免费|亚洲日韩中文字幕制服|久久精品亚洲免费|一本之道久久免费

      
      

            <dl id="hur0q"><div id="hur0q"></div></dl>

                Java打怪之路-谷粒商城Nginx與Redis

                Java打怪之路-谷粒商城Nginx與Redis

                一、商品上架流程

                product

                1、根據(jù)spuid查詢所有sku信息

                2、將sku信息封裝成skuModel(向es中存儲的是skuModel VO)

                不一致信息:

                庫存信息

                發(fā)送遠(yuǎn)程調(diào)用 查詢系統(tǒng)中是否存在庫存

                熱度評分

                品牌和分類的名字

                檢索屬性

                查出當(dāng)前sku中所有可以被檢索的屬性

                3、將數(shù)據(jù)發(fā)給es進(jìn)行保存,調(diào)用gulimall-search微服務(wù)進(jìn)行保存

                (1)在es中建立索引,建立號映射關(guān)系(doc/json/product-mapping.json)

                (2)在es中保存這些數(shù)據(jù)

                (3)設(shè)置成功失敗狀態(tài)

                二、Nginx反向代理配置

                1、什么是nginx反向代理

                正向代理:我們要訪問谷歌,但是被墻,所以將請求發(fā)送給代理服務(wù)器,由代理服務(wù)器來訪問,這叫正向代理

                反向代理:服務(wù)器部署在內(nèi)網(wǎng)中,客戶端訪問服務(wù)器不能直接訪問服務(wù)器的內(nèi)網(wǎng)地址,通常需要根據(jù)域名來訪問(www.baidu.com)。所以需要反向代理服務(wù)器來將外網(wǎng)的ip轉(zhuǎn)換成內(nèi)網(wǎng)ip來訪問。

                2、反向代理如何實(shí)現(xiàn)

                只代理到商品服務(wù):客戶端發(fā)送gulimall.com請求,在windows中映射gulimall.com是虛擬機(jī)ip(192.168.56.10)所以會訪問虛擬機(jī)。虛擬機(jī)中的nginx監(jiān)聽80端口。在配置文件中,會設(shè)置nginx代理到的路徑http://192.168.56.1:10000。這樣就訪問到了商品服務(wù)里的首頁(首頁在商品服務(wù)中)

                location/{proxy_pass http://192.168.56.1:10000}

                代理到網(wǎng)關(guān): 客戶端發(fā)送gulimall.com請求,在windows中映射gulimall.com是虛擬機(jī)ip(192.168.56.10)所以會訪問虛擬機(jī)。虛擬機(jī)中的nginx監(jiān)聽80端口。在配置文件中nginx.config中配置上游服務(wù)器gulimall http://192.168.56.1:88。然后繼續(xù)在配置文件gulimall.config中nginx代理到的路徑http://gulimall。

                需要注意的是,nginx代理給網(wǎng)關(guān)會丟失一部分信息。解決如下

                三、壓力測試

                1、JVM堆棧垃圾回收

                2、優(yōu)化方式

                加內(nèi)存(提升JVM堆中eden區(qū)和old區(qū)的內(nèi)存空間,避免頻繁的gc)

                數(shù)據(jù)庫優(yōu)化,加索引

                打開模板緩存,設(shè)置日志為error時記錄

                靜態(tài)資源快速返回 動靜分離

                優(yōu)化代碼 減少循環(huán)查表

                3、Nginx實(shí)現(xiàn)動靜分離

                (1)將所有的靜態(tài)資源移動到nginx中

                (2)/static/**下的所有內(nèi)容由nginx返回,在nginx中進(jìn)行相關(guān)配置,gulimall-conf中設(shè)置

                location /static/{ root /usr/share/nginx/html }

                4、優(yōu)化三級分類數(shù)據(jù)獲取

                直接查詢所有分類的結(jié)果,只查一次表,將其他循環(huán)查表的過程抽取為一個函數(shù)

                四、緩存與分布式

                為什么使用緩存

                如何使用redis

                引入data-redis-starter

                org.springframework.boot spring-boot-starter-data-redis

                簡單配置redis的host

                使用自動配置好的String Redis Template redis

                String Redis Template redis中 存儲鍵值對 鍵與值都是String類型

                //將數(shù)據(jù)放入緩存@Overridepublic Map getCatelogJson() { String catelogJson = redisTemplate.opsForValue().get(“catelogJson”); if (StringUtils.isEmpty(catelogJson)){ //緩存中沒有 Map catelogJsonFromDB = getCatelogJsonFromDB(); redisTemplate.opsForValue().set(“catelogJson”,JSON.toJSONString(catelogJsonFromDB)); return catelogJsonFromDB; } //因為轉(zhuǎn)化的對象是復(fù)雜對象,所以通過TypeReference Map catelogJsonFromDB = JSON.parseObject(catelogJson,new TypeReference<Map>(){ }); return catelogJsonFromDB;}//從數(shù)據(jù)庫查詢數(shù)據(jù)public Map getCatelogJsonFromDB() { //將數(shù)據(jù)庫的多次交互,轉(zhuǎn)為一次,一次性查詢所有數(shù)據(jù) List allList = baseMapper.selectList(null); //查出所有分類 List level1Categorys = getParent_cid(allList,0L); //分裝數(shù)據(jù) Map resultMap = level1Categorys.stream().collect(Collectors.toMap(CategoryEntity::getCatId, v -> { //每一個的一級分類,查到這個一級分類的二級分類 List list = getParent_cid(allList,v.getCatId()); List catelog2VoList = null; if (!StringUtils.isEmpty(list)) { catelog2VoList = list.stream().map(item -> { Catelog2Vo catelog2Vo = new Catelog2Vo(v.getCatId().toString(), null, item.getCatId().toString(), item.getName()); //封裝二級分類的三級分類 List entityList = getParent_cid(allList,item.getCatId()); if (!StringUtils.isEmpty(entityList)){ List catelog3Vos = entityList.stream().map(m -> { Catelog2Vo.Catelog3Vo catelog3Vo = new Catelog2Vo.Catelog3Vo(item.getCatId().toString(),m.getCatId().toString(),m.getName()); return catelog3Vo; }).collect(Collectors.toList()); catelog2Vo.setCatalog3List(catelog3Vos); } return catelog2Vo; }).collect(Collectors.toList()); return catelog2VoList; } return catelog2VoList; })); return resultMap;}private List getParent_cid(List allList,Long parent_cid) { List collect = allList.stream().filter(item -> { return item.getParentCid().equals(parent_cid); }).collect(Collectors.toList()); return collect; // return baseMapper.selectList(new QueryWrapper().eq(“parent_cid”, v.getCatId()));}

                內(nèi)存溢出以及解決

                TODO 產(chǎn)生堆外內(nèi)存溢出OutOfDirectMemoryError:

                產(chǎn)生原因

                • springboot2.0以后默認(rèn)使用lettuce作為操作redis的客戶端,它使用netty進(jìn)行網(wǎng)絡(luò)通信
                • lettuce的bug導(dǎo)致netty堆外內(nèi)存溢出。netty如果沒有指定堆外內(nèi)存,默認(rèn)使用Xms的值,可以使用-Dio.netty.maxDirectMemory進(jìn)行設(shè)置

                解決方案:由于是lettuce的bug造成,不要直接使用-Dio.netty.maxDirectMemory 去調(diào)大虛擬機(jī)堆外內(nèi)存,治標(biāo)不治本。

                • 升級lettuce客戶端。
                • 切換使用jedis

                lettuce和jedis是操作redis的底層客戶端,RedisTemplate是再次封裝

                緩存失效 穿透、雪崩、擊穿

                **緩存穿透:**是指大量的并發(fā)請求訪問一個數(shù)據(jù)庫中從未出現(xiàn)的內(nèi)容,由于緩存中沒有這條內(nèi)容,所以會并發(fā)查表導(dǎo)致數(shù)據(jù)庫崩潰。

                **解決辦法:**將null也寫入緩存中

                **緩存雪崩:**是指設(shè)置緩存時,key使用了相同的過期時間,大量并發(fā)此時同時訪問這些過期緩存,導(dǎo)致同時查表導(dǎo)致數(shù)據(jù)庫崩潰。

                **解決辦法:**緩存過期時間在原來的基礎(chǔ)上設(shè)置隨機(jī)值。

                **緩存擊穿:**是指大量并發(fā)請求同時訪問一個熱點(diǎn)key,如果這個熱點(diǎn)key剛好在緩存中過期,導(dǎo)致這個key的數(shù)據(jù)查詢都落到數(shù)據(jù)庫導(dǎo)致數(shù)據(jù)庫崩潰。

                **解決辦法:**大量的并發(fā)只讓一個人去查,其他人等待,查到之后釋放鎖,其他人回去到鎖,查找緩存不會查找數(shù)據(jù)庫。加鎖方法使用synchronized(this),this表示當(dāng)前對象。

                注意:緩存時許問題,確認(rèn)緩存、查數(shù)據(jù)庫和結(jié)果放入緩存是一個原子操作,要在鎖內(nèi)實(shí)現(xiàn)。

                @Overridepublic Map getCatelogJson() { String catelogJson = redisTemplate.opsForValue().get(“catelogJson”); //緩存中沒有 if (StringUtils.isEmpty(catelogJson)) { //獲取數(shù)據(jù)返回 Map catelogJsonFromDB = getCatelogJsonFromDB(); return catelogJsonFromDB; } //因為轉(zhuǎn)化的對象是復(fù)雜對象,所以通過TypeReference Map catelogJsonFromDB = JSON.parseObject(catelogJson, new TypeReference<Map>() { }); return catelogJsonFromDB;}//從數(shù)據(jù)庫查詢數(shù)據(jù)public Map getCatelogJsonFromDB() { synchronized (this) { //判斷緩存是否已經(jīng)有數(shù)據(jù),防止之前的線程已經(jīng)放好數(shù)據(jù) String catelogJson = redisTemplate.opsForValue().get(“catelogJsonFromDB”); if (!StringUtils.isEmpty(catelogJson)) { //因為轉(zhuǎn)化的對象是復(fù)雜對象,所以通過TypeReference Map resultMap = JSON.parseObject(catelogJson, new TypeReference<Map>() { }); return resultMap; } //將數(shù)據(jù)庫的多次交互,轉(zhuǎn)為一次,一次性查詢所有數(shù)據(jù) List allList = baseMapper.selectList(null); //查出所有分類 List level1Categorys = getParent_cid(allList, 0L); //分裝數(shù)據(jù) Map resultMap = level1Categorys.stream().collect(Collectors.toMap(CategoryEntity::getCatId, v -> { //每一個的一級分類,查到這個一級分類的二級分類 List list = getParent_cid(allList, v.getCatId()); List catelog2VoList = null; if (!StringUtils.isEmpty(list)) { catelog2VoList = list.stream().map(item -> { Catelog2Vo catelog2Vo = new Catelog2Vo(v.getCatId().toString(), null, item.getCatId().toString(), item.getName()); //封裝二級分類的三級分類 List entityList = getParent_cid(allList, item.getCatId()); if (!StringUtils.isEmpty(entityList)) { List catelog3Vos = entityList.stream().map(m -> { Catelog2Vo.Catelog3Vo catelog3Vo = new Catelog2Vo.Catelog3Vo(item.getCatId().toString(), m.getCatId().toString(), m.getName()); return catelog3Vo; }).collect(Collectors.toList()); catelog2Vo.setCatalog3List(catelog3Vos); } return catelog2Vo; }).collect(Collectors.toList()); return catelog2VoList; } return catelog2VoList; })); //放入緩存 redisTemplate.opsForValue().set(“catelogJson”, JSON.toJSONString(resultMap),1L, TimeUnit.DAYS); return resultMap; }}private List getParent_cid(List allList, Long parent_cid) { List collect = allList.stream().filter(item -> { return item.getParentCid().equals(parent_cid); }).collect(Collectors.toList()); return collect; // return baseMapper.selectList(new QueryWrapper().eq(“parent_cid”, v.getCatId()));}

                上面的本地鎖只能鎖住當(dāng)前進(jìn)程,在分布式的情況下無法保證鎖住整個集群服務(wù)

                分布式鎖

                可以讓商品服務(wù)來占坑,當(dāng)一個商品服務(wù)拿到鎖后,其他商品服務(wù)必須等待

                設(shè)置分布式鎖需要考慮的問題

                一二階段為設(shè)置鎖需要考慮的問題,二三階段為刪除鎖需要考慮的問題

                • 第一階段
                • setnx會獲取鎖,然后執(zhí)行業(yè)務(wù),最后刪除鎖
                • 出現(xiàn)問題:當(dāng)執(zhí)行業(yè)務(wù)時發(fā)生宕機(jī),無法執(zhí)行刪除鎖的操作,其他線程無法拿到鎖。造成死鎖。
                • 解決問題:將鎖設(shè)置一個自動過期時間,來保證鎖肯定會被釋放

                方法名:getCateLogJsonFromDbWithRedisLock//占分布式鎖Boolean lock=redisTemplate.opsForValue().setIfAbsent(“lock”,”111″);if(lock){ //如果獲得鎖,執(zhí)行業(yè)務(wù)Map dataFromDb=getDataFromDb();//執(zhí)行完刪除鎖redisTemplate.delete(“lock”)return dataFromDb;}else{ return getCateLogJsonFromDbWithRedisLock();}

                改進(jìn)后為:

                方法名:getCateLogJsonFromDbWithRedisLock//占分布式鎖Boolean lock=redisTemplate.opsForValue().setIfAbsent(“lock”,”111″);if(lock){ //如果獲得鎖,執(zhí)行業(yè)務(wù)Map dataFromDb=getDataFromDb();//設(shè)置過期時間redisTemplate.expire(“key”,30,TimeUnit.SECONDS)//執(zhí)行完刪除鎖redisTemplate.delete(“lock”)return dataFromDb;}else{ return getCateLogJsonFromDbWithRedisLock();}

                • 第二階段
                • 出現(xiàn)問題:雖然設(shè)置了過期時間,但是如果在設(shè)置過期時間之前發(fā)生了宕機(jī),過期時間沒有設(shè)置上,又會導(dǎo)致死鎖問題。
                • 解決問題:設(shè)置過期時間和占位必須是原子操作

                //占分布式鎖//setIfAbsent方法的第三個參數(shù)是設(shè)置過期時間Boolean lock=redisTemplate.opsForValue().setIfAbsent(“lock”,”111″,300);if(lock){ //如果獲得鎖,執(zhí)行業(yè)務(wù)Map dataFromDb=getDataFromDb();//設(shè)置過期時間//redisTemplate.expire(“key”,30,TimeUnit.SECONDS)//執(zhí)行完刪除鎖redisTemplate.delete(“lock”)return dataFromDb;}else{ return getCateLogJsonFromDbWithRedisLock();}

                • 第三階段出現(xiàn)問題:由于設(shè)置了自動過期時間,如果當(dāng)前執(zhí)行的業(yè)務(wù)很長,刪除鎖的時候,鎖已經(jīng)自動過期了,此時刪除的可能是別人的鎖。解決問題:給每個鎖添加唯一的uuid,刪除的時候判斷一下,匹配的是自己的鎖才能刪除
                • 第四階段出現(xiàn)問題:判斷完成之后,需要刪除鎖前,鎖剛好過期,別人設(shè)置新的值,那么我們會刪除別人的鎖解決問題:刪除鎖必須保證原子操作(判斷與刪除同時進(jìn)行)采用redis+lua腳本實(shí)現(xiàn)

                String uuid = UUID.randomUUID().toString(); //設(shè)置redis分布式鎖,30s自動刪除鎖 Boolean isLock = redisTemplate.opsForValue().setIfAbsent(“lock”, uuid,300L,TimeUnit.SECONDS); if (isLock){ //搶鎖成功。。。執(zhí)行業(yè)務(wù) Map resultMap = null; try { resultMap = getLongListMap(); }finally { //lua腳本解鎖:讓獲取數(shù)據(jù)+對比數(shù)據(jù)成為原子操作 String script = “if redis.call(“get”,KEYS[1]) == ARGV[1] then” + ” return redis.call(“del”,KEYS[1])” + “else” + ” return 0″ + “end”; Long lock = redisTemplate.execute(new DefaultRedisScript(script, Long.class),Arrays.asList(“lock”),uuid); } return resultMap; }else { //搶鎖失敗。。。重試 try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } // 睡眠0.2s后,重新調(diào)用 //自旋 return getCatelogJsonFromDBWithRedisLock(); }

                Redisson

                Redisson使用

                • pom導(dǎo)入

                org.redisson redisson 3.13.4

                • 開啟配置,寫一個配置類

                @Configurationpublic class RedissonConfig { @Bean(destroyMethod = “shutdown”) public RedissonClient redissonClient(){ Config config = new Config(); config.setTransportMode(TransportMode.EPOLL); config.useClusterServers() //可以用”rediss://”來啟用SSL連接 .addNodeAddress(“redis://192.168.109.101:6379”); return Redisson.create(config); } }

                可重入鎖

                基于Redis的Redisson分布式可重入鎖RLock Java對象實(shí)現(xiàn)了java.util.concurrent.locks.Lock接口。同時還提供了異步(Async)、反射式(Reactive)和RxJava2標(biāo)準(zhǔn)的接口。

                • 什么是可重入鎖:A中調(diào)用B,A拿到鎖后,該鎖可以由B直接使用,這個鎖叫可重入鎖,不可重入鎖是 A拿到鎖后,A調(diào)用B,B需要等待A鎖的釋放,而A鎖需要等待B執(zhí)行完才釋放,造成死鎖。
                • 如何使用Redisson分布式可重入鎖

                @RequestBody@GetMapping(/”hello”)public String hello(){ //1、獲取鎖 鎖名字一樣就是同一把鎖RLock lock=redission.getLock(“lock”);//指定解鎖時間的鎖//2、枷鎖lock.lock();//阻塞式等待//指定解鎖時間的鎖//lock.lock(10,TimeUnit.SECONDS)try{ //3、執(zhí)行業(yè)務(wù)System.out.println(“執(zhí)行業(yè)務(wù)”);Thread.sleep(30000);}catch(Exception e){ }finally{ //解鎖lock.unlock();}}

                Question1:這與上節(jié)redis中自己設(shè)置的鎖有什么區(qū)別

                這里是對自己設(shè)置的鎖進(jìn)行了封裝:上節(jié)我們需要自己設(shè)置加鎖和解鎖時的原子操作。而Redisson直接封裝了這些原子操作。由于這里加鎖會自動設(shè)置過期時間,所以不會出現(xiàn)業(yè)務(wù)崩潰,鎖釋放不了導(dǎo)致死鎖問題。

                Question2:Redisson可重入鎖,如何保證業(yè)務(wù)時間長而導(dǎo)致鎖被自動刪除。

              1. Redisson可重入鎖提供了鎖的續(xù)期:如果業(yè)務(wù)時間超長,運(yùn)行期間會自動給鎖續(xù)上新的30s(看門狗默認(rèn)時間)。
              2. 這里有個疑問,看門狗在業(yè)務(wù)執(zhí)行的時候會不斷設(shè)置新的定時任務(wù)來給鎖續(xù)期,如果此時業(yè)務(wù)崩潰,看門狗是失效了嗎?如果是失效的話,那就相當(dāng)于不會再繼續(xù)進(jìn)行續(xù)期,鎖會在默認(rèn)事件之后自動刪除。
              3. Question3:看門狗如何進(jìn)行鎖的續(xù)期

                只要占鎖成功,就會啟動一個定時任務(wù),重新給鎖設(shè)置過期時間,新的過期時間就是看門狗的默認(rèn)時間。每隔(一個看門狗時間/3)=10s,會自動再次續(xù)期,續(xù)到30s

                Question4:如果指定自動解鎖時間會發(fā)生什么

                如果指定自動過期時間,看門狗會失效,不會再有鎖的續(xù)期。自動解鎖時間一定要大于業(yè)務(wù)執(zhí)行時間。(如果小于會出現(xiàn)業(yè)務(wù)沒執(zhí)行完,鎖已經(jīng)被釋放,此時別的進(jìn)程搶占鎖,當(dāng)前進(jìn)程刪除鎖是報錯)。

                分布式可重入讀寫鎖允許同時有多個讀鎖和一個寫鎖處于加鎖狀態(tài)。

                讀鎖被稱為共享鎖,寫鎖被稱為互斥鎖

                讀讀共享 讀寫/寫寫 都是互斥

                RReadWriteLock rwlock = redisson.getReadWriteLock(“anyRWLock”);// 最常見的使用方法rwlock.readLock().lock();// 或rwlock.writeLock().lock();// 10秒鐘以后自動解鎖// 無需調(diào)用unlock方法手動解鎖rwlock.readLock().lock(10, TimeUnit.SECONDS);// 或rwlock.writeLock().lock(10, TimeUnit.SECONDS);// 嘗試加鎖,最多等待100秒,上鎖以后10秒自動解鎖boolean res = rwlock.readLock().tryLock(100, 10, TimeUnit.SECONDS);// 或boolean res = rwlock.writeLock().tryLock(100, 10, TimeUnit.SECONDS);//…lock.unlock();

                生產(chǎn)者消費(fèi)者問題中出現(xiàn)。例如停車與離開

                信號量為存儲在redis中的一個數(shù)字,當(dāng)這個數(shù)字大于0時,即可以調(diào)用acquire()方法增加數(shù)量,也可以調(diào)用release()方法減少數(shù)量,但是當(dāng)調(diào)用release()之后小于0的話方法就會阻塞,直到數(shù)字大于0

                tryAcquire()返回一個布爾型量,表示當(dāng)前是否可以獲取數(shù)量,如果數(shù)量為0,返回false。但是不會阻塞。常用于分布式限流

                @GetMapping(“/park”)@ResponseBodypublic String park() { RSemaphore park = redissonClient.getSemaphore(“park”); try { park.acquire(2); } catch (InterruptedException e) { e.printStackTrace(); } return “停進(jìn)2”;}@GetMapping(“/go”)@ResponseBodypublic String go() { RSemaphore park = redissonClient.getSemaphore(“park”); park.release(2); return “開走2”;}

                緩存與數(shù)據(jù)一致性

                在對表進(jìn)行修改時,緩存中的內(nèi)容也需要修改,可以采用兩種模式來進(jìn)行修改

                • 雙寫模式:在寫完數(shù)據(jù)庫之后,再寫緩存。
                • 存在問題:會出現(xiàn)臟數(shù)據(jù)的問題
                • 失效模式:再寫完數(shù)據(jù)庫,刪除緩存中的數(shù)據(jù),下次再讀數(shù)據(jù)庫
                • 存在問題:也會產(chǎn)生臟數(shù)據(jù)
                • 解決臟數(shù)據(jù)問題:
                • 設(shè)置過期時間,數(shù)據(jù)過期之后下一次重新查找數(shù)據(jù)庫
                • 讀寫數(shù)據(jù)時,加上分布式鎖的讀寫鎖,經(jīng)常寫經(jīng)常讀會對性能有影響

                如果想要保證強(qiáng)一致性可以使用Canal

                Canal相當(dāng)于一個數(shù)據(jù)庫的從庫,業(yè)務(wù)更新數(shù)據(jù)庫后,它會及時的修改緩存。

                注意:實(shí)時更新的數(shù)據(jù)、一致性要求高的數(shù)據(jù)本就不應(yīng)該放到緩存中,緩存中加上過期時間保證每天拿到的數(shù)據(jù)是當(dāng)前最新數(shù)據(jù)就可。遇到實(shí)時更新的數(shù)據(jù)、一致性要求高的數(shù)據(jù)就應(yīng)該查找數(shù)據(jù)庫。

                鄭重聲明:本文內(nèi)容及圖片均整理自互聯(lián)網(wǎng),不代表本站立場,版權(quán)歸原作者所有,如有侵權(quán)請聯(lián)系管理員(admin#wlmqw.com)刪除。
                用戶投稿
                上一篇 2022年6月14日 06:04
                下一篇 2022年6月14日 06:05

                相關(guān)推薦

                • 寶可夢朱紫寶主順序怎么選擇?寶可夢朱紫寶主挑戰(zhàn)順序攻略

                  寶可夢朱紫寶主順序如何選擇?寶主挑戰(zhàn)的順序有很多玩家都加入了討論,大家想要了解清楚正確的挑戰(zhàn)順序,接下來小編就給大家簡單的介紹一下寶主挑戰(zhàn)的順序,各位趕緊通過下面的攻略多了解一下詳…

                  2022年11月25日
                • 5+3疫情防控從哪天開始算(遼寧疫情防控最新政策)

                  最近有關(guān)國內(nèi)各地的疫情大家也都有在持續(xù)關(guān)注,目前國內(nèi)各地疫情隔離時間也根據(jù)二十條防控措施有了新的調(diào)整。那么,5+3疫情防控從哪天開始算?對于密接的5+3隔離時間計算大家還是比較關(guān)心…

                  2022年11月25日
                • 藍(lán)碼怎么變綠碼需要幾天(藍(lán)碼怎么變綠碼需要幾天)

                  大家都知道健康碼的顏色有紅碼、綠碼、黃碼,近日湖南健康碼上線“藍(lán)碼”,不少小伙伴發(fā)現(xiàn)自己健康碼變藍(lán)了,都想趕緊恢復(fù)綠碼,那么藍(lán)碼怎么變綠碼需要幾天?下面小編為大家?guī)硭{(lán)碼變綠碼需要…

                  2022年11月25日
                • 拼多多百億補(bǔ)貼預(yù)售一般多久發(fā)貨(拼多多百億補(bǔ)貼預(yù)售)

                  拼多多里面有很多優(yōu)惠活動,其中百億補(bǔ)貼活動非?;鸨恍├锩娴臇|西價格比別的平臺便宜,質(zhì)量也有保障,還有預(yù)售的活動,那么拼多多百億補(bǔ)貼預(yù)售一般多久發(fā)貨?下面小編為大家?guī)砥炊喽喟賰|…

                  2022年11月25日
                • 北京疫情多久能解除封控(北京疫情還要多久結(jié)束)

                  最近一段時間北京疫情形勢備受關(guān)注,馬上就要到年底了,不少人想要去北京辦事,。都非常關(guān)注當(dāng)?shù)匾咔橄嚓P(guān)政策,那么 北京疫情多久能解除封控?北京疫情什么時候恢復(fù)正常生活?下面小編為大家?guī)А?/p>

                  2022年11月25日
                • 什么是推廣cpa一篇文章帶你看懂CPA推廣渠道

                  CPA渠道 CPA指的是按照指定的行為結(jié)算,可以是搜索,可以是注冊,可以是激活,可以是搜索下載激活,可以是綁卡,實(shí)名認(rèn)證,可以是付費(fèi),可以是瀏覽等等。甲乙雙方可以根據(jù)自己的情況來定…

                  2022年11月25日
                • 抖音直播帶貨有哪些方法技巧(抖音直播帶貨有哪些痛點(diǎn))

                  如今抖音這個短視頻的變現(xiàn)能力越來越突顯了,尤其是在平臺上開通直播,更具有超強(qiáng)的帶貨屬性,已經(jīng)有越來越多的普通人加入到其中了。不過直播帶貨雖然很火,但是也不是每個人都能做好的,那么在…

                  2022年11月24日
                • 英皇文化產(chǎn)業(yè):結(jié)束全部7間英皇UA電影城經(jīng)營

                  11月21日,英皇文化產(chǎn)業(yè)發(fā)布公告,英皇娛藝影院(廣東)有限公司(“中國附屬公司”)為英皇UA的全資附屬營運(yùn)公司。 董事會謹(jǐn)此知會公司股東,于2022年11月21日,英皇UA(作為…

                  2022年11月24日
                • 淘寶直播開通后帶貨鏈接怎么做(淘寶直播需要開通淘寶店鋪嗎)

                  直播帶貨無論是對于商家來說還是主播收益都是非??捎^的,所以不少平臺都有直播帶貨功能,一些小伙伴也想加入淘寶直播,那么淘寶直播開通后帶貨鏈接怎么做?下面小編為大家?guī)硖詫氈辈ラ_通后帶…

                  2022年11月24日
                • 明查|美國新冠后遺癥患者中有16%癥狀嚴(yán)重以致無法工作?

                  點(diǎn)擊進(jìn)入澎湃新聞全球事實(shí)核查平臺 速覽 – 網(wǎng)傳數(shù)據(jù)比例無權(quán)威信源佐證,該比例有可能是結(jié)合了美國疾病防控中心和布魯金斯學(xué)會的數(shù)據(jù)得出,但這兩個機(jī)構(gòu)的調(diào)研目的和樣本都不同…

                  2022年11月24日

                聯(lián)系我們

                聯(lián)系郵箱:admin#wlmqw.com
                工作時間:周一至周五,10:30-18:30,節(jié)假日休息