中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁(yè) > news >正文

旅游網(wǎng)站模板源碼媒體發(fā)稿網(wǎng)

旅游網(wǎng)站模板源碼,媒體發(fā)稿網(wǎng),做視頻的軟件模板下載網(wǎng)站有哪些,建程網(wǎng)上的工程是真的嗎面試題: 緩存預(yù)熱、雪萌、穿透、擊穿分別是什么?你遇到過(guò)那幾個(gè)情況?緩存預(yù)熱你是怎么做的?如何造免或者減少緩存雪崩?穿透和擊穿有什么區(qū)別?他兩是一個(gè)意思還是載然不同?穿適和擊穿你有什么解…

面試題:

  • 緩存預(yù)熱、雪萌、穿透、擊穿分別是什么?你遇到過(guò)那幾個(gè)情況?
  • 緩存預(yù)熱你是怎么做的?
  • 如何造免或者減少緩存雪崩?
  • 穿透和擊穿有什么區(qū)別?他兩是一個(gè)意思還是載然不同?
  • 穿適和擊穿你有什么解決方案?如何避免?
  • 假如出現(xiàn)了緩存不一致,你有哪些修補(bǔ)方案?
  • 。。。。。。

緩存預(yù)熱

@PostConstruct初始化白名單數(shù)據(jù)

詳情地址可查看代碼:Redis BitMap/HyperLogLog/GEO/布隆過(guò)濾器案例_Please Sit Down的博客-CSDN博客

緩存雪崩

出現(xiàn)原因

  • redis主機(jī)掛了,redis全盤(pán)崩潰,偏硬件運(yùn)維
  • redis中有大量key同時(shí)過(guò)期大面積失效,偏軟件開(kāi)發(fā)

緩存+解決

1、redis中key設(shè)置為永不過(guò)期 or 過(guò)期時(shí)間錯(cuò)開(kāi)

2、redis緩存集群實(shí)現(xiàn)高可用

a、主從+哨兵
b、使用Redis集群
c、開(kāi)啟redis持久化機(jī)制aof/rdb,盡快恢復(fù)緩存集群

3、多緩存結(jié)合預(yù)防雪崩

ehcache本地緩存 + redis緩存

4、服務(wù)降級(jí)

Hystrix或者阿里sentinel限流&降級(jí)

緩存穿透

是什么

????????請(qǐng)求去查詢(xún)一條記錄,先查redis無(wú),后查mysq無(wú),都查詢(xún)不到該條記錄,但是清求每次都會(huì)打到數(shù)據(jù)庫(kù)上面去,導(dǎo)致后臺(tái)數(shù)據(jù)庫(kù)壓力暴增。這種現(xiàn)象我們稱(chēng)為緩存穿適,這個(gè)redis變成了一個(gè)擺設(shè)。

? ? ? ? 簡(jiǎn)單說(shuō)就是:本來(lái)無(wú)物,兩庫(kù)都沒(méi)有。既不在Redis緩存庫(kù),也不在mysql,數(shù)據(jù)車(chē)存在被多次暴擊風(fēng)險(xiǎn)。

解決

主要是防止惡意攻擊,解決方法:空對(duì)象緩存、bloomfilteri過(guò)濾器

方案一

空對(duì)象緩存或者缺省值。

????????第一種解決方案,回寫(xiě)增強(qiáng)。如果發(fā)生了緩存穿透,我們可以針對(duì)要查詢(xún)的數(shù)據(jù),在Redis里存一個(gè)和業(yè)務(wù)部門(mén)商量后確定的缺省值(比如,零、負(fù)數(shù)、defaultNull等)。

????????比如,鍵uid:abcdxxx,值defaultNull作為案例的key和value。先去redis查鍵uid:abcdxxx沒(méi)有,再去mysql查沒(méi)有獲得 ,這就發(fā)生了一次穿透現(xiàn)象。but,可以增強(qiáng)回寫(xiě)機(jī)制。mysql也查不到的話(huà)也讓redis存入剛剛查不到的key并保護(hù)mysql。第一次來(lái)查詢(xún)uid:abcdxxx,redis和mysql都沒(méi)有,返回null給調(diào)用者,但是增強(qiáng)回寫(xiě)后第二次來(lái)查uid:abcdxxx,此時(shí)redis就有值了??梢灾苯訌腞edis中讀取default缺省值返回給業(yè)務(wù)應(yīng)用程序,避免了把大量請(qǐng)求發(fā)送給mysql處理,打爆mysql。但是,此方法架不住黑客的惡意攻擊,有缺陷......,只能解決key相同的情況。

????????黑客或者惡意攻擊:黑客會(huì)對(duì)你的系統(tǒng)進(jìn)行攻擊,拿一個(gè)不存在的id去查詢(xún)數(shù)據(jù),會(huì)產(chǎn)生大量的情求到數(shù)據(jù)庫(kù)去查詢(xún)。可能會(huì)導(dǎo)數(shù)你的數(shù)據(jù)庫(kù)由于壓力過(guò)大而宕掉。

? ? ? ? 1、key相同打你系統(tǒng):第一次打到mysql,空對(duì)象緩存后第二次就返回defaultNull缺省值,避免mysql被攻擊,不用再到數(shù)據(jù)車(chē)中去走一圈了。

? ? ? ? 2、key不同打你系統(tǒng):由于存在空對(duì)象緩存和緩存回寫(xiě)(看自己業(yè)務(wù)不限死),redis中的無(wú)關(guān)緊要的key也會(huì)越寫(xiě)越多(記得設(shè)置redisi過(guò)期時(shí)間)

方案二

使用Google布隆過(guò)器Guava解決緩存穿透。

Guava中布隆過(guò)濾器的實(shí)現(xiàn)算是比較權(quán)威的,所以實(shí)際項(xiàng)目中我們可以直接使用Guava布隆過(guò)濾器。

Guava's BloomFilter源碼出處:https://github.com/google/guava/blob/master/guava/src/com/google/common/hash/BloomFilter.java

白名單過(guò)濾器案例:

說(shuō)明:會(huì)出現(xiàn)誤判問(wèn)題,但是概率小可以接受,不能從布隆過(guò)濾器刪除;全部合法的key都需要放入Guava版布隆過(guò)濾器+redis里面,不然數(shù)據(jù)就是返回null。

代碼實(shí)現(xiàn):

pom.xml

<!--guava Google 開(kāi)源的 Guava 中自帶的布隆過(guò)濾器-->
<dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>23.0</version>
</dependency>

yml

server.port=7777
spring.application.name=redis7# ========================redis單機(jī)=====================
spring.redis.database=0
# 修改為自己真實(shí)IP
spring.redis.host=192.168.111.185
spring.redis.port=6379
spring.redis.password=111111
spring.redis.lettuce.pool.max-active=8
spring.redis.lettuce.pool.max-wait=-1ms
spring.redis.lettuce.pool.max-idle=8
spring.redis.lettuce.pool.min-idle=0

測(cè)試1:

@Test
public void testGuavaWithBloomFilter(){// 創(chuàng)建布隆過(guò)濾器對(duì)象BloomFilter<Integer> filter = BloomFilter.create(Funnels.integerFunnel(), 100);// 判斷指定元素是否存在System.out.println(filter.mightContain(1));System.out.println(filter.mightContain(2));// 將元素添加進(jìn)布隆過(guò)濾器filter.put(1);filter.put(2);System.out.println(filter.mightContain(1));System.out.println(filter.mightContain(2));
}// 結(jié)果
// false false // true true

測(cè)試2:取樣本100W數(shù)據(jù),查查不在100W范圍內(nèi),其它10W數(shù)據(jù)是否存在

controller

import com.atguigu.redis7.service.GuavaBloomFilterService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;@Api(tags = "google工具Guava處理布隆過(guò)濾器")
@RestController
@Slf4j
public class GuavaBloomFilterController{@Resourceprivate GuavaBloomFilterService guavaBloomFilterService;@ApiOperation("guava布隆過(guò)濾器插入100萬(wàn)樣本數(shù)據(jù)并額外10W測(cè)試是否存在")@RequestMapping(value = "/guavafilter",method = RequestMethod.GET)public void guavaBloomFilter() {guavaBloomFilterService.guavaBloomFilter();}
}

service

import com.google.common.hash.BloomFilter;
import com.google.common.hash.Funnels;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;import java.util.ArrayList;
import java.util.List;@Service
@Slf4j
public class GuavaBloomFilterService{public static final int _1W = 10000;//布隆過(guò)濾器里預(yù)計(jì)要插入多少數(shù)據(jù)public static int size = 100 * _1W;//誤判率,它越小誤判的個(gè)數(shù)也就越少(思考,是不是可以設(shè)置的無(wú)限小,沒(méi)有誤判豈不更好)//fpp the desired false positive probabilitypublic static double fpp = 0.03;// 構(gòu)建布隆過(guò)濾器private static BloomFilter<Integer> bloomFilter = BloomFilter.create(Funnels.integerFunnel(), size,fpp);public void guavaBloomFilter(){//1 先往布隆過(guò)濾器里面插入100萬(wàn)的樣本數(shù)據(jù)for (int i = 1; i <=size; i++) {bloomFilter.put(i);}//故意取10萬(wàn)個(gè)不在過(guò)濾器里的值,看看有多少個(gè)會(huì)被認(rèn)為在過(guò)濾器里L(fēng)ist<Integer> list = new ArrayList<>(10 * _1W);for (int i = size+1; i <= size + (10 *_1W); i++) {if (bloomFilter.mightContain(i)) {log.info("被誤判了:{}",i);list.add(i);}}log.info("誤判的總數(shù)量::{}",list.size());}
}

結(jié)果:

現(xiàn)在總共有10萬(wàn)數(shù)據(jù)是不存在的,誤判了3033次,原始樣本:100W

不存在數(shù)據(jù):1000000W---1100000W ????

誤判率:3033 / 100000 = 0.03033

深刻分析代碼:核心BloomFilter.create方法

@VisibleForTestingstatic <T> BloomFilter<T> create(Funnel<? super T> funnel, long expectedInsertions, double fpp, Strategy strategy) {。。。。
}

這里有四個(gè)參數(shù):

  • funnel:數(shù)據(jù)類(lèi)型(通常是調(diào)用Funnels工具類(lèi)中的)

  • expectedInsertions:指望插入的值的個(gè)數(shù)

  • fpp:誤判率(默認(rèn)值為0.03)

  • strategy:哈希算法

問(wèn)題:為什么fpp設(shè)置成0.03?

情景一:fpp = 0.01

  • 誤判個(gè)數(shù):947

  • 占內(nèi)存大小:9585058位數(shù)
  • 解決的hash沖突函數(shù):7個(gè)

情景二:fpp = 0.03(默認(rèn)參數(shù))

  • 誤判個(gè)數(shù):3033

  • 占內(nèi)存大小:7298440位數(shù)
  • 解決的hash沖突函數(shù):5個(gè)

情景三:fpp=0.000000000000001

  • 占用內(nèi)存大小:67095408位數(shù)
  • 解決的hash沖突函數(shù):47個(gè)

情景總結(jié):

  • 誤判率能夠經(jīng)過(guò)fpp參數(shù)進(jìn)行調(diào)節(jié)
  • fpp越小,須要的內(nèi)存空間就越大:0.01須要900多萬(wàn)位數(shù),0.03須要700多萬(wàn)位數(shù)。
  • fpp越小,集合添加數(shù)據(jù)時(shí),就須要更多的hash函數(shù)運(yùn)算更多的hash值,去存儲(chǔ)到對(duì)應(yīng)的數(shù)組下標(biāo)里。(忘了去看上面的布隆過(guò)濾存入數(shù)據(jù)的過(guò)程)

上面的numBits,表示存一百萬(wàn)個(gè)int類(lèi)型數(shù)字,須要的位數(shù)為7298440,700多萬(wàn)位。理論上存一百萬(wàn)個(gè)數(shù),一個(gè)int是4字節(jié)32位,須要481000000=3200萬(wàn)位。若是使用HashMap去存,按HashMap50%的存儲(chǔ)效率,須要6400萬(wàn)位。能夠看出BloomFilter的存儲(chǔ)空間很小,只有HashMap的1/10左右。

上面的numHashFunctions表示須要幾個(gè)hash函數(shù)運(yùn)算,去映射不一樣的下標(biāo)存這些數(shù)字是否存在(0 or 1)。

布隆過(guò)濾器說(shuō)明:?

黑名單過(guò)濾器案例:

緩存擊穿

是什么

????????大量的請(qǐng)求同時(shí)查詢(xún)一個(gè)key時(shí),此時(shí)這個(gè)key正好失效了,就會(huì)導(dǎo)致大量的請(qǐng)求都打到數(shù)據(jù)庫(kù)上面去。簡(jiǎn)單說(shuō)就是熱點(diǎn)key突然失效了,暴打mysql

備注:穿透和擊穿,截然不同。

危害

會(huì)造成某一時(shí)刻數(shù)據(jù)庫(kù)請(qǐng)求量過(guò)大,壓力劇增。

一般技術(shù)部門(mén)需要知道熱點(diǎn)key是那些個(gè)?做到心里有數(shù)防止擊穿

解決

互斥更新、隨機(jī)退避、差異失效時(shí)間

熱點(diǎn)key失效問(wèn)題:時(shí)間到了自然清除但還波訪(fǎng)問(wèn)到;delete掉的key,剛I巧又被訪(fǎng)問(wèn)

方案1:差異失效時(shí)間,對(duì)于訪(fǎng)問(wèn)須繁的熱點(diǎn)key,干脆就不設(shè)置過(guò)期時(shí)間

方案2:互斥跟新,采用雙檢加鎖策略

????????多個(gè)線(xiàn)程同時(shí)去查詢(xún)數(shù)據(jù)庫(kù)的這條數(shù)據(jù),那么我們可以在第一個(gè)查詢(xún)數(shù)據(jù)的請(qǐng)求上使用一個(gè) 互斥鎖來(lái)鎖住它。其他的線(xiàn)程走到這一步拿不到鎖就等著,等第一個(gè)線(xiàn)程查詢(xún)到了數(shù)據(jù),然后做緩存。后面的線(xiàn)程進(jìn)來(lái)發(fā)現(xiàn)已經(jīng)有緩存了,就直接走緩存。

案例

天貓聚劃算功能實(shí)現(xiàn)+防止緩存擊穿(熱點(diǎn)key突然失效導(dǎo)致了緩存擊穿)

定時(shí)任務(wù)每次取20條記錄,取的過(guò)程中,突然失效,大量數(shù)據(jù)打到mysql

redis數(shù)據(jù)類(lèi)型選型:list

常規(guī)代碼

entity

import io.swagger.annotations.ApiModel;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;@Data
@AllArgsConstructor
@NoArgsConstructor
@ApiModel(value = "聚劃算活動(dòng)producet信息")
public class Product {//產(chǎn)品IDprivate Long id;//產(chǎn)品名稱(chēng)private String name;//產(chǎn)品價(jià)格private Integer price;//產(chǎn)品詳情private String detail;
}

service:采用定時(shí)器將參與聚劃算活動(dòng)的特價(jià)商品新增進(jìn)入redis中

import cn.hutool.core.date.DateUtil;
import com.atguigu.redis7.entities.Product;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;@Service
@Slf4j
public class JHSTaskService {public  static final String JHS_KEY="jhs";public  static final String JHS_KEY_A="jhs:a";public  static final String JHS_KEY_B="jhs:b";@Autowiredprivate RedisTemplate redisTemplate;/*** 偷個(gè)懶不加mybatis了,模擬從數(shù)據(jù)庫(kù)讀取100件特價(jià)商品,用于加載到聚劃算的頁(yè)面中* @return*/private List<Product> getProductsFromMysql() {List<Product> list=new ArrayList<>();for (int i = 1; i <=20; i++) {Random rand = new Random();int id= rand.nextInt(10000);Product obj=new Product((long) id,"product"+i,i,"detail");list.add(obj);}return list;}@PostConstructpublic void initJHS(){log.info("啟動(dòng)定時(shí)器淘寶聚劃算功能模擬.........."+ DateUtil.now());new Thread(() -> {//模擬定時(shí)器一個(gè)后臺(tái)任務(wù),定時(shí)把數(shù)據(jù)庫(kù)的特價(jià)商品,刷新到redis中while (true){//模擬從數(shù)據(jù)庫(kù)讀取100件特價(jià)商品,用于加載到聚劃算的頁(yè)面中List<Product> list=this.getProductsFromMysql();//采用redis list數(shù)據(jù)結(jié)構(gòu)的lpush來(lái)實(shí)現(xiàn)存儲(chǔ)this.redisTemplate.delete(JHS_KEY);//lpush命令this.redisTemplate.opsForList().leftPushAll(JHS_KEY,list);//間隔一分鐘 執(zhí)行一遍,模擬聚劃算每3天刷新一批次參加活動(dòng)try { TimeUnit.MINUTES.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }log.info("runJhs定時(shí)刷新..............");}},"t1").start();}
}

controller

import com.atguigu.redis7.entities.Product;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;@RestController
@Slf4j
@Api(tags = "聚劃算商品列表接口")
public class JHSProductController {public  static final String JHS_KEY="jhs";@Autowiredprivate RedisTemplate redisTemplate;/*** 分頁(yè)查詢(xún):在高并發(fā)的情況下,只能走redis查詢(xún),走db的話(huà)必定會(huì)把db打垮* @param page* @param size* @return*/@RequestMapping(value = "/pruduct/find",method = RequestMethod.GET)@ApiOperation("按照分頁(yè)和每頁(yè)顯示容量,點(diǎn)擊查看")public List<Product> find(int page, int size) {List<Product> list=null;long start = (page - 1) * size;long end = start + size - 1;try {//采用redis list數(shù)據(jù)結(jié)構(gòu)的lrange命令實(shí)現(xiàn)分頁(yè)查詢(xún)list = this.redisTemplate.opsForList().range(JHS_KEY, start, end);if (CollectionUtils.isEmpty(list)) {//TODO 走DB查詢(xún)}log.info("查詢(xún)結(jié)果:{}", list);} catch (Exception ex) {//這里的異常,一般是redis癱瘓 ,或 redis網(wǎng)絡(luò)timeoutlog.error("exception:", ex);//TODO 走DB查詢(xún)}return list;}
}

至此步驟,上述聚劃算的功能算是完成,請(qǐng)思考在高并發(fā)下有什么經(jīng)典生產(chǎn)問(wèn)題?

答案:熱點(diǎn)k突然失效導(dǎo)致可怕的緩存擊穿,delete命令執(zhí)行的一瞬間有空隙,其它請(qǐng)求線(xiàn)程繼續(xù)找Redis為null,打到了mysql,暴擊…

最終目的:2條命令原子性還是其次,主要是防止熱key突然失效暴擊mysq打爆系統(tǒng)

加固代碼

采用差異失效時(shí)間

sevice

import cn.hutool.core.date.DateUtil;
import com.atguigu.redis7.entities.Product;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;@Service
@Slf4j
public class JHSTaskService {public  static final String JHS_KEY_A="jhs:a";public  static final String JHS_KEY_B="jhs:b";@Autowiredprivate RedisTemplate redisTemplate;/*** 偷個(gè)懶不加mybatis了,模擬從數(shù)據(jù)庫(kù)讀取100件特價(jià)商品,用于加載到聚劃算的頁(yè)面中* @return*/private List<Product> getProductsFromMysql() {List<Product> list=new ArrayList<>();for (int i = 1; i <=20; i++) {Random rand = new Random();int id= rand.nextInt(10000);Product obj=new Product((long) id,"product"+i,i,"detail");list.add(obj);}return list;}@PostConstructpublic void initJHSAB(){log.info("啟動(dòng)AB定時(shí)器計(jì)劃任務(wù)淘寶聚劃算功能模擬.........."+DateUtil.now());new Thread(() -> {//模擬定時(shí)器,定時(shí)把數(shù)據(jù)庫(kù)的特價(jià)商品,刷新到redis中while (true){//模擬從數(shù)據(jù)庫(kù)讀取100件特價(jià)商品,用于加載到聚劃算的頁(yè)面中List<Product> list=this.getProductsFromMysql();//先更新B緩存this.redisTemplate.delete(JHS_KEY_B);this.redisTemplate.opsForList().leftPushAll(JHS_KEY_B,list);this.redisTemplate.expire(JHS_KEY_B,20L,TimeUnit.DAYS);//再更新A緩存this.redisTemplate.delete(JHS_KEY_A);this.redisTemplate.opsForList().leftPushAll(JHS_KEY_A,list);this.redisTemplate.expire(JHS_KEY_A,15L,TimeUnit.DAYS);//間隔一分鐘 執(zhí)行一遍try { TimeUnit.MINUTES.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }log.info("runJhs定時(shí)刷新雙緩存AB兩層..............");}},"t1").start();}
}

controller

import com.atguigu.redis7.entities.Product;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;@RestController
@Slf4j
@Api(tags = "聚劃算商品列表接口")
public class JHSProductController {public  static final String JHS_KEY_A="jhs:a";public  static final String JHS_KEY_B="jhs:b";@Autowiredprivate RedisTemplate redisTemplate;@RequestMapping(value = "/pruduct/findab",method = RequestMethod.GET)@ApiOperation("防止熱點(diǎn)key突然失效,AB雙緩存架構(gòu)")public List<Product> findAB(int page, int size) {List<Product> list=null;long start = (page - 1) * size;long end = start + size - 1;try {//采用redis list數(shù)據(jù)結(jié)構(gòu)的lrange命令實(shí)現(xiàn)分頁(yè)查詢(xún)list = this.redisTemplate.opsForList().range(JHS_KEY_A, start, end);if (CollectionUtils.isEmpty(list)) {log.info("=========A緩存已經(jīng)失效了,記得人工修補(bǔ),B緩存自動(dòng)延續(xù)5天");//用戶(hù)先查詢(xún)緩存A(上面的代碼),如果緩存A查詢(xún)不到(例如,更新緩存的時(shí)候刪除了),再查詢(xún)緩存Bthis.redisTemplate.opsForList().range(JHS_KEY_B, start, end);//TODO 走DB查詢(xún)}log.info("查詢(xún)結(jié)果:{}", list);} catch (Exception ex) {//這里的異常,一般是redis癱瘓 ,或 redis網(wǎng)絡(luò)timeoutlog.error("exception:", ex);//TODO 走DB查詢(xún)}return list;}
}

總結(jié)

http://www.risenshineclean.com/news/9573.html

相關(guān)文章:

  • 最新中國(guó)b2b網(wǎng)站排名南寧seo做法哪家好
  • 獨(dú)立網(wǎng)站怎么做seo當(dāng)陽(yáng)seo外包
  • php 開(kāi)源企業(yè)網(wǎng)站百度網(wǎng)盤(pán)網(wǎng)頁(yè)版入口
  • 懷化 網(wǎng)站建設(shè)2345網(wǎng)址導(dǎo)航設(shè)為主頁(yè)
  • 合肥萬(wàn)戶(hù)網(wǎng)絡(luò)科技有限公司搜索引擎優(yōu)化的主要工作
  • 上虞網(wǎng)站設(shè)計(jì)城關(guān)網(wǎng)站seo
  • 沈陽(yáng)做網(wǎng)站公司重慶seo排名
  • 國(guó)內(nèi)課程網(wǎng)站建設(shè)現(xiàn)狀永久免費(fèi)低代碼開(kāi)發(fā)平臺(tái)
  • 新華社兩學(xué)一做網(wǎng)站seo整合營(yíng)銷(xiāo)
  • 編輯網(wǎng)站內(nèi)容有沒(méi)有批量辦法什么是seo關(guān)鍵詞
  • 網(wǎng)站程序和空間區(qū)別網(wǎng)絡(luò)推廣優(yōu)化網(wǎng)站
  • 寧波網(wǎng)站建設(shè)推廣公司青島百度快速排名優(yōu)化
  • 零食網(wǎng)站頁(yè)面模板湖南專(zhuān)業(yè)seo公司
  • 房產(chǎn)信息網(wǎng)站模板電商平臺(tái)怎么加入
  • 音樂(lè)網(wǎng)站開(kāi)發(fā)參考文獻(xiàn)百度指數(shù)代表什么意思
  • 雞西公司做網(wǎng)站關(guān)鍵詞分為哪幾類(lèi)
  • 哪有專(zhuān)做注冊(cè)小網(wǎng)站的客戶(hù)資源買(mǎi)賣(mài)平臺(tái)
  • wordpress懸浮bar深圳seo網(wǎng)站優(yōu)化公司
  • 企業(yè)網(wǎng)站怎么做推廣比較好網(wǎng)站模板建站公司
  • 二手車(chē)網(wǎng)站建站海豹直播nba
  • 做蛋糕有哪些網(wǎng)站域名查詢(xún)網(wǎng)
  • 網(wǎng)站360做的標(biāo)記如何取消市場(chǎng)營(yíng)銷(xiāo)策劃方案3000字
  • wordpress定時(shí)插件seo是什么意思seo是什么職位
  • 濰坊哪家網(wǎng)站制作公司好關(guān)鍵詞歌詞任然
  • 網(wǎng)站開(kāi)發(fā)工程師自學(xué)個(gè)人開(kāi)發(fā)app可以上架嗎
  • 營(yíng)口市代做網(wǎng)站三只松鼠口碑營(yíng)銷(xiāo)案例
  • 網(wǎng)站的標(biāo)簽怎么修改做國(guó)外網(wǎng)站
  • 射陽(yáng)網(wǎng)站設(shè)計(jì)b站大全永不收費(fèi)2023入口在哪
  • 區(qū)塊鏈開(kāi)發(fā)是什么意思常德網(wǎng)站優(yōu)化公司
  • 江西省城鄉(xiāng)建設(shè)培訓(xùn)網(wǎng)-官方網(wǎng)站關(guān)鍵詞優(yōu)化簡(jiǎn)易