




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
Redis+Tomcat+Nginx集群實現(xiàn)Session蕃薯耀Java后端2019-11-點擊上?Java后端,選擇設(shè)為星標(biāo)作者蕃薯耀shuyao上篇35Java或者直接在附件中(版本為2.0.2,2017-11-27?前版本 :#-redishostsex::6379,:6379,:6380,#-redispassword(mons-logging-1.2.jar3.jedis-4.tomcat-cluster-redis-session-manager-壓縮?件中有使??法,?readMe.txtMovethedownloadedjarstotomcat/lib 22.Addtomcatsystemproperty就是配置?個環(huán)境變量,和Jdk配置的環(huán)境變量?樣,需要配置?個catalina.base的環(huán)境變量,值為TOMCAT33.Extractdownloadedpackage(tomcat-cluster-redis-session-manager.zip)toconfigureRediscredentialsinredis-data-*tomcat/conf/redis-data-把?錄下的配置?件h.oris到occ?錄下第四步:4.Addthebelowtwolinesin<ManagerclassName="tomcat.request.session.redis.SessionManager"LicensedtotheApacheSoftwareFoundation(ASF)underoneormorethisworkforadditionalinformationregardingcopyrightownership.TheASFlicensesthisfiletoYouundertheApacheLicense,Version2.0(the"License");youmaynotusethisfileexceptincompliancewiththeLicense.YoumayobtainacopyoftheLicenseatUnlessrequiredbyapplicablelaworagreedtoinwriting,softwaredistributedundertheLicenseisdistributedonan"ASIS"BASIS,SeetheLicenseforthespecificlanguage erningpermissionsandlimitationsundertheLicense.--><!--Thecontentsofthisfilewillbeloadedforeachwebapplication--<!--Defaultsetofmonitoredresources.Ifoneofthesechanges,the--<!--webapplicationwillbereloaded.-- mentthistodisablesessionpersistenceacrossTomcatrestarts--<Managerpathname=""-- mentthistoenableCometconnectiontacking(provideseventsonsessionexpirationaswellaswebapplifecycle)--><Valve etConnectionManagerValve"-- 55.Verifythesessionexpirationtime(minutes)in 2 2 在http{……}?加上upstreamupstreamupstreammyTomcatCluster{tomcatCluster和 server:9400weight=1failtimeout=5smaxweight表?權(quán)重,權(quán)重越?, location/location/locationlocation/#indexindex.htmllocation/myTomcatCluster對應(yīng)upstream 名進(jìn)?D:\soft\nginx-1.12.2啟動服務(wù):(啟動?閃?過,但打開進(jìn)程管理器能看到是已經(jīng)啟動的關(guān)閉服 令:nginx-s重新加載令:nginx-sreload,修改配置?件后,可以使?該命令直接加載,不需要重啟將已經(jīng)配置好的?個oct ?份,修改端?,然后再修改?下o的配置?件(v.xl)我的?個oc在:<Engine<EnginedefaultHost="localhost"其中tomcat9300端?的<Engine<EnginedefaultHost="localhost"jvmRoute="jvm9300"tomcat9400端?的<Engine<EnginedefaultHost="localhost"jvmRoute="jvm9400"<%@pagelanguage="java"contentType="text/html;charset=UTF-<!DOCTYPEhtmlPUBLIC"-//W3C//DTDHTML4.01<metahttp-equiv="Content-Type"content="text/html;charset=UTF-//HttpSessionsession=out.println("<br>SESSIONID:"+out.out.println("<br>SESSIONID:"+然后把這個項?分別部署 端?的個tomcat中,分別啟動,記得也啟動Nginx和redis然后打開瀏覽器通過地址項? ?論怎么刷新 (打開新的?也是(?新窗?))的都是900,也就是端?號為900的tct后綴.9400就是前?配置的:<Engine<EnginedefaultHost="localhost"jvmRoute="jvm9400" 使?i實現(xiàn)o共享的好處就是,把管理放在中,如果服務(wù)器重啟或,i保存在中,下次重啟后?樣?效,避免i失效,同樣最好也做集群,避免i重啟或。--END 可進(jìn)??? 理解InliJIDEA的項?配置和Web部Java4Git學(xué)Java, 萬汨Java后端2019-11-點擊上?Java?i另辟蹊徑,結(jié)合其有序隊列以及h編碼,實現(xiàn)了空間搜索功能,且擁有極?的運?效率。本?將從源碼?度對其算法原理進(jìn)?解析,并推算查詢時間復(fù)雜度。?Redis3.2開始,Redis基于geohash和有序集合提供了地理位置相關(guān)功能。RedisGeo模塊包含了以下6GEOPOS:從key??返回所有給定位置對象的位置(經(jīng)度和緯度);GEODIST:返回兩個給定位置之間的距離;GEOHASH:Geohash Redisgeo操作中只包含了“增”和“查”的操作,并沒有專?的“刪除”命令。主要是因為Redis內(nèi)部使?有序集合(zset)保在i源碼.的?件注釋中,只說明了該?件為EA、E和EEM的實現(xiàn)?件(其實在也實現(xiàn)了另三個命令)。從側(cè)?看出其他三個命令為輔助命令。 /*GEOADDkeylonglatname[long2lat2name2...longNlatNnameN] *c)/*Checkargumentsnumberforsanity.if((c->argc-2)%3!0)/*Needanoddnumberofargumentsifwegotthisfar...addReplyError(c,"syntaxerror.TryGEOADDkeyx1]y1]name1]""x2]y2]name2]...");}intelements(c->argc-2)/intargc2+elements*2;/*ZADDkeyscoreele...robj**argvzcalloc(argc*sizeof(robj*));argv0]crea argv1]c->argv1];/*key*/incrRefCount(argv1]);/*CreatetheargumentvectortocallZADDinordertoaddthescore,valuepairstotherequestedzset,wherescoreisanencodedversionoflat,long.for(i0;i<elements;i++)doublexy CERR)for(i0;i<argc; }GeoHashBitsrobj*valc->argv2+i*3+ Redisgeo轉(zhuǎn)換過的位置理論上會有約0.3*1.414=0.424?的誤差。范圍單位:m|km|ft|mi|||和和分別新增了GEORADIUSRO和GEORADIUSBYMEMBERRO兩個只讀命令。不過,在實際開發(fā)中筆者發(fā)現(xiàn)在javapackageRedis.s.jedis.params.geo的GeoRadiusParam參數(shù)類中并不包"member1""member1",distance1,longitude1,latitude1]]"member2",distance2,longitude2,O[COUNTcount][STOREkey][STORedisTkey]GEORADIUSBYMEMBERstoRedist0;/*0forSTORE,1forSTORedisT.doublexy2]{0if(flags&RADIUSCOORDS)}doubleradiusmeters0,conversionif((radiusmetersextractDistanceOrReply(c,c->argv+baseargs-&conversion))<0)}//獲取可選參數(shù)(withdist、withhash、withcoords、sort、intwithdist0,withhash0,withcoordsintsortSORTlonglongcountif(c->argc>baseargs)...}if(storekey&&(withdistwithhash{"STOREoptioninGEORADIUSisnotcompatiblewith""WITHDIST,WITHHASHandWITHCOORDSoptions");}if(count!0&& SORTNONE)sortSORTGeoHashRadiusgeoArray*gamembersOfAllNeighbors(zobj,georadius,xy0],xy1],radiusmeters,/*Ifnomatchingresults,theusergetsanemptyreply.if(ga->used0&&storekeygeoArray(ga);}的是geohashGetAreasByRadiusWGS84和membersOfAllNeighbors//geohashGeoHashRadiusgeohashGetAreasByRadiusWGS84(doublelongitude,doubledoubleradiusmeters)returngeohashGetAreasByRadius(longitude,latitude,radius}GeoHashRadiusgeohashGetAreasByRadius(doublelongitude,doublelatitude,double meters)//些參數(shù)設(shè)置GeoHashRangelongrange,latrange;GeoHashRadiusradius;GeoHashBitshash;GeoHashAreaarea;doubleminlon,maxlon,minlat,maxdoublebounds//計算?標(biāo)區(qū)域外接矩形的范圍(?標(biāo)區(qū)域為:以?標(biāo)為中?,半徑為指定距離的圓geohashBoundingBox(longitude,latitude,radiusmeters,bounds);minlonbounds0];minlatbounds1];maxlonbounds2];maxlatbounds3];stepsgeohashEstimateStepsByRadius(radius//設(shè)置最?最?值:-180<longitude<18085<latitude<//將待查按指定精度(steps)編碼成geohashgeohashEncode(&longrange,&latgeohashDecode(longrange,lat{GeoHashBitsneighborsunsignedinti,count0,lastprocessedintdebugmsgneighbors0]neighbors8]n.neighbors.southif(HASHISZERO(neighborsi]))}if(lastprocessedneighborsi].bits neighbors neighborslast{}count+membersOfGeoHashBox(zobj,neighborsi],ga,lon,lat,radius);lastprocessedi;}}intmembersOfGeoHashBox(robj*zobj,GeoHashBitshash,geoArray*ga,doublelon,doublelat,doubleradius)GeoHashFix52Bitsmin,max;returngeoGetPointsInRange(zobj,min,max,lon,lat,radius,}intgeoGetPointsInRange(robj*zobj,doublemin,doublemax,doublelon,doublelat,doubleradius,geoArray*ga)個的邊界范圍zrangespecrange{.minmin,.maxmax.minex0.maxex1sizetorigincountga->used;sds//搜索集合zobj可能有ZIPLIST和SKIPLIST兩種編碼?式,這?以SKIPLIST為例,邏輯是樣的 OBJENCODINGZIPLIST)}elseif(zobj->encodingOBJENCODING{zset*zszobj->ptr;zskiplist*zslzs->zsl;zskiplistNode*ln;if((lnzslFirstInRange(zsl, NULL)/*Nothingexistsstartingatourmin.Noresults.return}sdseleln-/*Abortwhenthenodeisnolongerinrange.if(!zslValueLteMax(ln->score,eleCERR)sds lnln->level}}returnga->used-}doubledistance,xy if(!decodeGeohash(score,xy))returnCERR;/*Can'tdecode.if(!geohashGetDistanceIfInRadiusWGS84(lon,lat,xy0],xyradius,{returnC}gp->longitudexy0];gp->latitudexy1];gp->distgp->membermember;gp->scorescore;returnCOK;}換句話說,h?格等級越?,所覆蓋的地理位置范圍就越?。當(dāng)我們根據(jù)輸?半徑和中?點位置計算出的能夠覆蓋?標(biāo)區(qū)域的最?等級的九宮格(?格)時,就已經(jīng)對九宮格外的元素進(jìn)?了篩除。這?之所以使?九宮格,?不?單個?格,主要原因還是為了避免邊界情況,盡可能縮?查詢區(qū)域范圍。試想以0為中?,就算查1?范圍,單個?格覆蓋的話也得查整個地球?先在每個o?格中的h下是有序集合的跳表數(shù)據(jù)結(jié)構(gòu):中EUS查找附近的?功能,時間復(fù)雜度為:+lM))。其中N為九宮格范圍內(nèi)的位置元素數(shù)量(要算距離);M是指定層級格?的數(shù)量,lM)是跳表結(jié)構(gòu)中找到每個格??元素的時間復(fù)雜度(這個過程?般會進(jìn)?9次)。結(jié)合i本?基于內(nèi)[1] [3] Redis持久化的?種?式-RDBJava后端2019-11-以下?章來源于Java 上?篇?千?MySQL內(nèi)存中的數(shù)據(jù)到磁盤,以便Redis重啟時能夠從磁盤中恢復(fù)原有的數(shù)據(jù),?整個過程就叫做Redis持久化。RedisRedisMemcachedMemcached快照?式(RDB,RedisDataBase)?件追加?式(AOFAppendOnlyFile),RDB(RedisDataBase)是將某?個時刻的內(nèi)存快照(Snapshot),?動觸發(fā)持久化的操作有兩個:save和bgsave,它們主要區(qū)別體現(xiàn)在:是否阻塞Redissave在客?端中執(zhí)?saveRedisRedisRDB持久化完成,才會響應(yīng)其他客?端發(fā)來令,所以在?產(chǎn)環(huán)境?定要慎?。savesave命令之后,持久化?件化。save命令執(zhí)?流程,如下圖所?:
dump.rdb的修改時間就變了,這就表 成功的觸發(fā)了RDB持bgsavebgsave(backgroundsave)既保存的意思,它
save命令最?的區(qū)別就是bgsave會forkfork(,Redis整個流程都阻塞的save命令來說,顯然bgsave命令更適合我們使?。bgsave命令使?,如下圖所?:①savemsave設(shè)置的觸發(fā)條件,?動執(zhí)??次bgsave命令。注意:當(dāng)設(shè)置多個savemn命令時,滿?任意?個條件都會觸發(fā)持久化。例如,我們設(shè)置了以下兩個savemn命令:save60save60060s10Redis60sRedis10次,那么Redis600s內(nèi),Redis②flushall命令?于清空Redis數(shù)據(jù)庫,在?產(chǎn)環(huán)境下?定慎?,當(dāng)Redis
flushall命令之后,則會觸發(fā)?動持久化,把在Redis主從 發(fā)Redis持久化。
RDB配置參數(shù)可以在RedisRDB#stop-wites-on-bgsave-eopessiondbchecksum.disavesave9001:表?900秒內(nèi)如果?少有1個keysave3001030010keysave60100006010000個key pression③rdbchecksumRedis中可以使?命令查詢當(dāng)前配置參數(shù)。查詢命令的格式為:configgetxxx,例如,想要獲取RDB?件的名稱設(shè)置,可以使?configgetdbfilename,執(zhí)?效果如下圖所?:RDB的?件?錄,可使?命令configgetdir,執(zhí)?效果如下圖所?:Redis使?命令?設(shè)置,例如,使?configsetdir"/usr/data"就是?于修改RDB的?錄注意:?動修改Redis配置?件的?式是全局?效的,即重啟Redis服務(wù)器設(shè)置參數(shù)也不會丟失,?使?命令修改的?式,在RedisRedisRedisRedis?貼?:Redis的配置?件位于Redis安裝?錄的根路徑下,默認(rèn)名稱為redis.conf?貼?:Redis的配置?件位于Redis安裝?錄的根路徑下,默認(rèn)名稱為redis.confRedisRedisRDBdump.rdb,RedisRDB?件恢復(fù)持久化數(shù)據(jù)。如果根?錄沒有dump.rdb?件,請先將dump.rdb?件移動到Redis的根?錄。src/redis-Redis在啟動時有?志信息,會顯?是否加載了RDB?件,我們執(zhí)?Redis啟動命令: ,如下圖所RDB對恢復(fù)?常有?,它是?個緊湊的?件,可以更快的傳輸?shù)椒?wù)器進(jìn)?Redis服務(wù)恢復(fù)盤,Redis主進(jìn)程并不會執(zhí)?磁盤I/O等操作;因為RDB只能保存某個時間間隔的數(shù)據(jù),如果中途Redis服務(wù)被意外終?了,則會丟失?段時間內(nèi)的Redis數(shù)據(jù);需要經(jīng)常CPU性能不佳,則可能導(dǎo)致Redis停?為客?端服務(wù)?毫秒甚??秒鐘。禁?持久化可以提?Redis的執(zhí)?效率,如果對數(shù)據(jù)丟失不敏感的情況下,可以在連接客?端的情況下,執(zhí)?configsetsave""命Redis的持久化,如下圖所?:通過本?我們可以得知,RDB持久化分為?動觸發(fā)和?動觸發(fā)兩種?式,它的優(yōu)點是?件?,Redis啟動時恢復(fù)數(shù)據(jù)?較快,缺點是有丟失數(shù)據(jù)的?險。RDB?件的恢復(fù)也很簡單,只需要把RDB?件放到Redis的根?錄,在Redis啟動時就會?動加載并【END 即可進(jìn)???告 項?中常?到的19條MySQL零基礎(chǔ)認(rèn)識SpringGit SpringBoot+Redis+注解+器來實現(xiàn)接?冪等性校Java后端1?6點擊上?Java作者189275403ed分布式鎖--redis(jedis、redisson)或zookeeper實現(xiàn)本?采?第2redistoken為需要保證冪等性的每?次請求創(chuàng)建?個唯?標(biāo)識tokentokentoken存?redistokenredis中刪除此tokentoken@ApiIdempotent注解+器對請求進(jìn)?壓測?具:jmeter本?重點介紹冪等性核?實現(xiàn),no如何集成ri、rn、no等細(xì)枝末節(jié)不在本?討論范圍之內(nèi),的 項?:@paramkey}}*publicStringset(Stringkey,Stringvalue,int{Jedisjedistryjedisreturnjedis.setex(key,expireTime, {log.error("setkey:{}value:{}expireTime:{}error",key,value,expireTime,e);returnnull;}{}}{Jedisjedistryjedis}catch(Exception{log.error("getkey:{}error",key,e);returnnull;}{}}publicLongdel(String{Jedisjedistryjedis}catch(Exception{log.error("delkey:{}error",key,e);returnnull;}{}}publicBooleanexists(String{Jedisjedistryjedis}catch(Exception{log.error("existskey:{}error",key,e);returnnull;}{}}publicLongexpire(Stringkey,int{Jedisjedistryjedisreturnjedis.expire(key.getBytes(),}catch(Exception{log.error("expirekey:{}error",key,e);returnnull;}{}}{Jedisjedistryjedis}catch(Exception{log.error("ttlkey:{}error",key,e);returnnull;}{}}privatevoidclose(Jedis{if(null!jedis){}}}?定義注解 publicclassApiIdempotentInterceptorimplementsHandlerInterceptorpublicbooleanpreHandle(HttpServletRequestrequest,HttpServletResponseresponse,Objectreturn}HandlerMethodhandlerMethod(HandlerMethod)handler;MethodmethodhandlerMethod.getMethod();ApiIdempotentmethodAnnotationif(methodAnnotation!null)}return}{}publicvoidpostHandle(HttpServletRequesthttpServletRequest,HttpServletResponsehttpServletResponse,Objecto,}public pletion(HttpServletRequesthttpServletRequest,HttpServletResponsehttpServletResponse,Objecto,}}publicclassTokenServiceImplimplementsTokenServiceprivatestaticfinalStringTOKENNAMEpublicServerResponse{StringstrRandomUtil.UUID32();StrBuildertokennewtoken.append(Constant.Redis.TOKENPREFIX).append(str);}publicvoidcheckToken(HttpServletRequest{Stringtokenrequest.getHeader(TOKENif(StringUtils.isBlank(token)){//header中不存在tokenrequest.getParameter(TOKENif(StringUtils.isBlank(token)){//parameter中也不存在}}if(!jedisUtil.exists(token))}Longdelif(del<0)}}}publicstaticvoidmain(String]{SpringApplication.run(TestApplication.class,}finalCorsConfigurationcorsConfigurationnewCorsConfiguration();urlBasedCorsConfigurationSource.registerCorsConfiguration("/**",returnnew}//接?冪等性 }publicApiIdempotentInterceptor{returnnew}}查看4jmeter測試?具模擬50token5、header或參數(shù)均不傳token,tokentokentoken值為上圖中,不能單純的直接刪除token?不校驗是否刪除成功,會出現(xiàn)并發(fā)安全性問題,因為,有可能多個線程同時?到第46?,此時tokenjedisUtil.del(token實際上只有?次真正的刪除操作,下?重現(xiàn)?下 springaop-ENDHashGit 神?003Java后端2?17 創(chuàng)建鎖的策略:e的普通e?般都允許覆蓋,A??t某個e后,B在t相同的e時同樣能成功,如果是鎖場景,那就?法知道到底是哪個??et成功的;這?ei的et?式為我們解決了這個問題,簡單原理是:當(dāng)A??先et成功了,那??e的時候就返回失敗,滿?了某個時間點只允許?個??拿到鎖。publicpublicbooleansetnx(Stringkey,String{}catch(Exceptionex)如下測試url,正常來說第?次返回了true,第?次返回了false,由于第?次請求的時候redis的key已存在,所以?法set功上?是創(chuàng)建鎖,同樣的具有有效時間,但是我們不能完全依賴這個有效時間,場景如:有效時間設(shè)置分鐘,本???后,沒遇到什么特殊情況正常?成了搶購訂單后,此時其他??應(yīng)該能正常下單了才對,但是由于有個分鐘后鎖才能?動釋放,那其他??在這分鐘?法正常下單(因為鎖還是??的),因此我們需要??操作完后,主動去 :這?也使?了jedis?式,直接執(zhí)?lua:根據(jù)val判斷其是否存在,如果存在就當(dāng);只不過直接通過eval執(zhí)?,這樣避免多?次操作了redis?已,縮短了原?操作的間隔。(不同?解請留?探討);同*privateStringqiang(Stringb)longstartTimewhile((startTime+timeout)>System.currentTimeMillis())if(nKuCuen<0)}if Key,b))"??{}拿到鎖...",tryif(nKuCuen<0)}try}catch(InterruptedException{}nKuCuen-("??{}搶單成功跳出...所剩庫存:{}",b,"??{}釋放鎖...", Key,}}else//if(b.equals("神?-50")||b.equals("神?-69"))//}}return}(startTime+timeout)>=System.currentTimeMillis():判斷未搶成功的??,timeout秒內(nèi)繼續(xù)獲取鎖 獲取鎖后并下單成功,最后釋放鎖 Key,-END 「focusoncode 更新?篇?質(zhì)量技術(shù)博?(??告 SpringBoot整合Java后端2?22作者艾神不??SpringBootRedis 點擊redis-server.exe開啟RedisRedisRedis?、整合到Spring1、在項?中加?Redis依賴,pom<!整合<!整合Reds緩存?持><groupId>org.spr redjedmaxactve:100maxdle:10maxwat:100000tmeout:50003、新建RedisConfiguration配置類,繼承CachingConfigurerSupport,@EnableCaching開啟注解。@Con@Con?guraton@EnableCachngpublcclassRedsCon?guratonextendsCachngCon?gurerSupport@OverrpublcKeyGenerator{returnnewKeyGenerator(){@OverrdepublcObjectgenerate(Objecto,Methodmethod,Object...objects)StrngBuldersb=newStrngBuppend(obj.toStrng());}System.out.prntln"調(diào)?Reds緩存Key:"+sb.toStrng());returnsb.toStrng();}}*@paramconnectpublcCacheManagercacheManager(RedsConnectonFactoryconnectonFactory)RedsCacheManagerredsCacheManage=RedsCacheManager.create(connectonFactory);returnredsCacheManager;}publcRed te<Strng,Strng>red te(RedsConnectonFactoryfactory)StrngRed te=newStrngRedsTemJackson2JsonRedsSeralzerjackson2JsonRedsSeralze=newJackson2JsonRedsSeralzer(Object.class);ObjectMapperom=newObjectMapper();jackson2JsonRedsSeralzer.setObjectMapper(om);temte.setValueSeralzer(jackson2JsonRedsSeralzer);temte.afterPropertesSet();returntem}}publcnterfaceRed*Hash結(jié)構(gòu)添加元素*@paramkeykey*@paramhashKeyhashKey*@paramdoman*Hash結(jié)構(gòu)獲取指定key所有鍵值對*@paramkey*Map<HK,T>hashFndAll(Str*Hash結(jié)構(gòu)獲取單個元素*@paramkey*@paramhashKey*ThashGet(StrvodhashRemove(Str*Lst結(jié)構(gòu)向尾部(Rght)添加元素*@paramkey*@paramdoman**Lst結(jié)構(gòu)向頭部(Left)添加元素*@paramkey*@paramdoman*LonglstUnshft(Strngkey,Tdoma*Lst結(jié)構(gòu)獲取所有元素*@paramkey*Lst<T>lstFndAll(Str*Lst結(jié)構(gòu)移除并獲取數(shù)組第?個元素*@paramkey*vodvaluePut(Strngkey,Tdoma*設(shè)置過期時間*@paramkey鍵*@paramtmeout時間*@paramtmeUntbooleanexprse(Strngkey,longtmeout,TmeUnttmeUnt)}5、下?是創(chuàng)建RedisHelperImpl//在構(gòu)造器中獲取redsTemte實例,key(nothashKey)默認(rèn)使?Strng類型prvateRedsTem te<Strng,T>redsTem prvateHashOperatons<Strng,HK,T>hashOperatons;prva stOperatons<Strng,T>lstOperatons;prvateSetOperatons<Strng,T>setOperatons;prvateValueOperatons<Strng,T>valueOperat//IDEA雖然報錯,但是依然可以注?成功,實例化操作對象后就可以直接調(diào)??法操作Reds數(shù)據(jù)庫@AutowredpublcRedsHelperImpl(Red te<Strng,T>red {ths.red te=red ths.hashOperatons=redsTem ths.lstOperatons=redsTem te.opsForLst();ths.zSetOperatons=redsTem ths.setOperatons=redsTem }@OverrpublcvodhashPut(Strngkey,HKhashKey,Tdoma}@OverrpublcMap<HK,T>hashFndAll(Str{returnhashOperatons.entr}@Overr{returnhashOperat}@OverrpublcvodhashRemove(Str{hashOperat}@OverrpublcLonglstPush(Strngkey,Tdoma}@OverrpublcLonglstUnshft(Strngkey,Tdoma{returnlstOperatons.leftPush(key,doma}@OverrpublcLst<T>lstFndAll(Str{ te.hasKey(key)){return}returnlstOperatons.range(key,0,lstOperatons.s}@OverrpublcTlstLPop(Strngkey){}@OverrpublcvodvaluePut(Strngkey,Tdoma}@OverrpublcTgetValue(Str}@Overrpublcvodremove(Str{red }@Overrpublcbooleanexprse(Strngkey,longtmeout,TmeUnttmeUn{returnred te.expre(key,tmeout,tmeUn}}編寫TestRedis@RunW@RunWth(SprngRunner.class)@SprngBootTestpublcclassTestRedsprvateStrngRed testrngRed prvateRed tered prvateRedsHelperImplredpublcvodtest() cepton strngRedsTem Assert.assertEquals("111",strngRed System.out.prntln(strngRedsTem Authoruser=newAuthor();user.setName(user.setIntrol("不會打籃球的程序不是好男?");redsHelper.valuePut("aaa",user);}publcvodtestObj() cept{Authoruser=newAuthor();user.setName("Jerry");user.setIntrolValueOperatons<Strng,Author>operatons=redsTem operatons.set("502",user);Thread.sleep(booleanexsts=redsTem f(exsts){System.out.prntln(red te.opsForValue().get(}System.out.prntln("exsts}//Assert.assertEquals("aa",operat}}@EnableCach@EnableCachng//開啟緩存@SprngBootApplcatonpublcclassPoetryApplcatonpublcstatcvodman(Strng[]args)SprngApplcaton.run(PoetyApplcat}}上?的Redis相關(guān)寫法是我們?定義設(shè)置并獲取的,那么我們經(jīng)常要在接?的地?去使?Redis進(jìn)?緩存相關(guān)實體publcclassAuthorController{prvate?nalstatcLoggerlogge=LoggerFactory.getLogger(AuthorController.class);@AutowredprvateAuthorRepostoryauthorRepos@Cacheable(value="poemInfo//?動根據(jù)?法?成緩存@PostMappng(value="/poemInfo")publcResult<Author>author(@RequestParam("authord")ntauthord,@RequestParam("authorname")Strngauthorname){f(StrngUtls.sEmpty(authord)StrngUtls.sEmpty(authorname)){returnResultUtls.error(ResultCode.INVALIDPARAM}Optonal<Author>optonal=authorRepostory.getAuthorByIdAndName(authord,authorname);f(optonal.sPresent()){author=optonal.l())){Strngs=author.getIntrol();Strngntro=s.splt("\\s+")[0];author.setIntrol(ntro);}}}returnResultUt}}這?-END 「focusoncode?更新?篇?質(zhì)量技術(shù)博?(??告 Redis Java后端2019-11-點擊上?Java后端,選擇設(shè)為星標(biāo)作者來源 但這并不能減少業(yè)務(wù)邏輯對數(shù)據(jù)庫的增刪改操作的IO Memcache的代碼層類似HashRedis特點如下:RedisRedis的效率很?,官?給出的數(shù)據(jù)是100000+QPS另外單線程也能處理?并發(fā)請求,還可以避免頻繁上下?切換和鎖的競爭,如果想要多核運?也可以啟動多個實例。數(shù)據(jù)結(jié)構(gòu)簡單,對數(shù)據(jù)操作也簡單,RedisMp,Mp最?的優(yōu)點就是存取的時間復(fù)雜度為O(1)。Redis使?多路I/O復(fù)?模型,為?阻塞IO注:Redis采?的I/O多路復(fù)?函數(shù):epoll/kqueue/evport/select閱讀關(guān)于SpringBootJava、Spring全家桶等技術(shù)?章,歡 :Java后因地制宜,優(yōu)先選擇時間復(fù)雜度為O(1)的I/O多路復(fù)?函數(shù)作為底層實現(xiàn)。由于Select要遍歷每?個IO,所以其時間復(fù)雜度為O(n),通常被作為保底?案。基于React設(shè)計模式I/O。最基本的數(shù)據(jù)類型,其值最?可512M,?進(jìn)制安全(Redis的String可以包含任何?進(jìn)制數(shù)據(jù),包含jpg對象等注:如果重復(fù)寫?keyString元素組成的字典,適?于對象String元素組成的?序集合,通過哈希表實現(xiàn)(增刪改查時間復(fù)雜度為O(1))另外,當(dāng)我們使?Smembers遍歷Set中的元素時,其順序也是不確定的,是通過Hash運算過后的結(jié)果。Sorted通過分?jǐn)?shù)來為集合中的成員進(jìn)?從?到?的排序。Redis?于計數(shù)的HyperLogLog、?于?持地理位置信息的Geo假設(shè)Redis中有?億條Key,如何從這么多Key中找到固定前綴的?法1:使?Keys[pattern]:查找所有符合給定模式Pattern的使?Keys[pattern]指令可以找到所有符合Pattern條件的Key,但是Keys會?次性返回所有符合條件的Key,所以會造成Redis的卡頓。假設(shè)RedisKey,對內(nèi)存的消耗在某些條件下也是keyskeystest*//返回所有以test為前綴的?法2:使?SCANcursor[MATCHpattern][COUNTMATCHpattern:查詢KeyCountSCANSCAN以00此命令并不保證每次執(zhí)?都返回某個給定數(shù)量的元素,甚?會返回0個元素,但只要游標(biāo)不是0,程序都不會認(rèn)為SCAN命令結(jié)束,但是返回的元素數(shù)量?概率符合Count參數(shù)。另外,SCAN?持模糊查詢。SCANSCAN0MATCHtest*COUNT10//每次返回10條以test為前綴的分布式鎖是控制分布式系統(tǒng)之間共同 共享資源的?種鎖的實現(xiàn)。如果?個系統(tǒng),或者不同系統(tǒng)的不同主機(jī)之間共享某分任意時刻只有?個客?端獲取到鎖,不能有兩個客?端同時獲取到鎖。鎖只能被持有該鎖的客?端刪除,不能由其他客?端刪除。死鎖:獲取鎖的客?端因為某些原因?宕機(jī)繼??法釋放鎖,其他客?端再也?法獲取鎖?導(dǎo)致死鎖,此時需要有特殊機(jī)容錯:當(dāng)各個節(jié)點,如某個RedisSETNX實現(xiàn),SETNXkeyvalueKey該命令時間復(fù)雜度為O(1),如果設(shè)置成功,則返回1,否則返回0。區(qū)之前先使?SETNX指令,查看是否設(shè)置成功。如果設(shè)置成功則說明前?沒有客?端正在該資源,如果設(shè)置失敗則說明有客?端正在該資源,那么當(dāng)前客?端就需由于SETNX并不?持傳?EXPIRE參數(shù),所以我們可以直接使?EXPIRE指令來對特定的Key來設(shè)置過期時間。RedisServiceRedisServiceredisServiceSpringUtils.getBean(RedisService.class);longstatusredisService.setnx(key,"1");}解決:從Redis2.6.12版本開始,我們就可以使?Set操作,將SETNX和EXPIREEXsecond:設(shè)置鍵的過期時間為Second秒。PXmillisecond:設(shè)置鍵的過期時間為MilliSecond毫秒。SETSETKEYvalueEXseconds]PXmilliseconds]NX注:SET操作成功完成時才會返回OK,否則返回nil有了SET我們就可以在程序中使?類似下?的代碼實現(xiàn)分布式鎖了:RedisServiceRedisServiceredisServiceStringresultredisService.set(lockKey,requestId,SETIFNOTEXIST,SETWITHEXPIRETIME,expireTime);}①使?Redis中的List使?上?所說的Redis的數(shù)據(jù)結(jié)構(gòu)中的List作為隊列Rpush?產(chǎn)消息,LPOP消費消息。此時我們可以看到,該隊列是使?Rpush?產(chǎn)隊列,使?LPOP消費隊列。缺點:LPOP彌補:可以通過在應(yīng)?層引?Sleep機(jī)制去調(diào)?LPOP重試。②使?BLPOPkeykey…]BLPOPkeykey…]timeout③Pub/Sub:訂閱者模KafkaRedis由于Redis將數(shù)據(jù) 在內(nèi)存?不是磁盤中,所以內(nèi)存?旦斷電,Redis中 所以Redis有持久化機(jī)制來保證數(shù)據(jù)的安全性。Redis?前有兩種持久化?式,即RDB和AOF,RDB是通過保存某個時間點的全量數(shù)據(jù)快照實現(xiàn)數(shù)據(jù)的持久化,當(dāng)恢復(fù)數(shù)據(jù)時,直接通過RDB?件中的快照,將數(shù)據(jù)恢復(fù)。RDB持久化會在某個特定的間隔保存那個時間點的全量數(shù)據(jù)的快照。RDB配置?件,redis.conf:savesave9001#在900s內(nèi)如果有1save30010#在300s內(nèi)如果有10save6010000#在60s內(nèi)如果有10000stop-writes-on-bgsave-erroryes#stop-writes-on-bgsave-error:①RDB的創(chuàng)建與載?SAVE:阻塞Redis的服務(wù)器進(jìn)程,直到RDB?件被創(chuàng)建完畢。SAVE?,由于RedisBGSAVE:該指令會Fork出?個?進(jìn)程來創(chuàng)建RDBRDB續(xù)接收客?端的請求。我們也可以通過使?lastsave指令來查看BGSAVE是否執(zhí)?成功,lastsave可以返回最后?次執(zhí)?成功BGSAVE的時②?動化觸發(fā)RDB持久化的?式?動化觸發(fā)RDB根據(jù)redis.conf配置?的SAVEmn定時觸發(fā)(實際上使?的是BGSAVE)。 執(zhí)?DebugReload執(zhí)?Shutdown且沒有開啟AOF持久化。③BGSAVE的原理檢查是否存在?進(jìn)程正在執(zhí)?AOF或者RDB的持久化任務(wù)。如果有則返回false調(diào)?Redis源碼中的rdbSaveBackground?法,?法中執(zhí)?fork()產(chǎn)??進(jìn)程執(zhí)?RDB操作。關(guān)于fork()中的Copy-On-Write。fork()在Linux中創(chuàng)建?進(jìn)程采?Copy-On-Write(寫時拷?技術(shù)),即如果有多個調(diào)?者同時要求相同資源(如內(nèi)存或磁 ④RDB持久化?式的缺點RDB持久化?式的缺點如下:I/O?嚴(yán)重影響性能。可能會因為Redis宕機(jī)?丟失從當(dāng)前?最近?次快照期間的數(shù)據(jù)。AOF持久化是通過保存Redis的寫狀態(tài)來記錄數(shù)據(jù)庫的。相對RDB來說,RDB持久化是通過備份數(shù)據(jù)庫的狀態(tài)來記錄數(shù)據(jù)庫,?AOF持久化是備份數(shù)據(jù)庫接收到的指令:AOF記錄除了查詢以外的所有變更數(shù)據(jù)庫狀態(tài)的指令。以增量的形式追加保存到AOF?件中。①打開redis.conf配置?件,將appendonly屬性改為yes②修改appendfsync屬性,該屬性可以接收三種參數(shù),分別是always,everysec,noalways表?總是即時將緩沖區(qū)內(nèi)容寫?AOF?件當(dāng)中,everysec表?每隔?秒將緩沖區(qū)內(nèi)容寫?AOF?件,no表?將寫??件操作交由操作系統(tǒng)決定。appendonlyappendonly#appendsyncalways#appendfsyncno?志重寫解決AOF隨著寫操作的不斷增加,AOF?件會越來越?。假設(shè)遞增?個計數(shù)器100RDB持久化?式,我們只要保存最終結(jié)果100即可。命令實際可以精簡為?條。RedisAOFCOW(寫時拷?。重調(diào)?fork?進(jìn)程把新的AOF寫到?個臨時?件?,不依賴原來的AOF?件。主進(jìn)程持續(xù)將新的變動同時寫到內(nèi)存和原來的AOF?。主進(jìn)程獲取?進(jìn)程重寫AOF的完成信號,往新AOF同步增量變動。使?新的AOF?件替換掉舊的AOF?件。AOF和RDB的優(yōu)缺點如下:RDB全量數(shù)據(jù)快照,?件?,恢復(fù)快。RDB?法保存最近?次快照之后的數(shù)據(jù)。優(yōu)點:Redis4.0之后推出了此種持久化?式,RDB作為全量備份,AOF的數(shù)據(jù),AOF則將Redis指令存??件中,這樣?會造成?件體積?,恢復(fù)時間?等弱點。在RDB-AOF?式下,持久化策略?先將緩存中數(shù)據(jù)以RDB?式全量寫??件,再將寫?后新增的數(shù)據(jù)以AOF的?式追加在RDB數(shù)據(jù)的后?,在下?次做RDB持久化的時候?qū)OF的數(shù)據(jù)重新以RDB的形式寫??件。在此種策略的持久化過程中,?進(jìn)程會通過管道從?進(jìn)程增量數(shù)據(jù),在以RDB格式保存全量數(shù)據(jù)時,也會通過管道數(shù)RDBAOF薦的?種持久化?式。RDB和AOF從圖可知,Redis啟動時會先檢查AOF是否存在,如果AOF存在則直接加載AOF,如果不存在AOF,則直接加載RDB?Pipeline和Linux的管道類似,它可以讓Redis批量執(zhí)?指令。畢后才能繼續(xù)執(zhí)?,這中間不僅僅多了RTT,還多次使?了系統(tǒng)IO。Pipeline由于可以批量執(zhí)?指令,所以可以節(jié)省多次IORedis?般是使??個Master節(jié)點來進(jìn)?寫操作,?若?個Slave節(jié)點進(jìn)?讀操作,Master和Slave分別代表了?個個不同的RedisServer實例。另外定期的數(shù)據(jù)備份操作也是單獨選擇?個Slave去完成,這樣可以最?程度發(fā)揮Redis的性能,為的是保證數(shù)據(jù)的弱?致另外,Master和Slave的數(shù)據(jù)不是?定要即時同步的,但是在?段時間后Master和Slave的數(shù)據(jù)是趨于同步的,這就是最Slave發(fā)送Sync命令到MasterMaster啟動? 進(jìn)程,將Redis中的數(shù)據(jù)快照保存到?件中Master將保存數(shù)據(jù)快照期間接收到的寫命令緩存起來。Master完成寫?件操作后,將該?件發(fā)送給Slave。使?新的AOF?件替換掉舊的AOF?件。Master將這期間收集的增量寫命令發(fā)送給Slave端。MasterMaster接收到??的操作指令,判斷是否需 到Slave將操作記錄追加到AOF?件。將操作到其他Slave:對?主從庫;往響應(yīng)緩存寫?指令。將緩存中的數(shù)據(jù)發(fā)送給Slave。RedisSentinel(哨兵主從模式弊端:當(dāng)Master宕機(jī)后,Redis集群將不能對外提供寫?操作。RedisSentinel可解決這?問題。解決主從同步Master宕機(jī)后的主從切換問題::提醒:通過API?動故障遷移:主從切換(在Master宕機(jī)后,將其中?個Slave轉(zhuǎn)為Master,其他的Slave從該節(jié)點同步數(shù)據(jù)Redis按照某種規(guī)則去劃分?jǐn)?shù)據(jù),分散在多個節(jié)點上。通過將數(shù)據(jù)分到多個Redis服務(wù)器上,來減輕單個Redis服務(wù)器的②?致性Hash算法既然要將數(shù)據(jù)進(jìn)?分?,那么通常的做法就是獲取節(jié)點的Hash但這樣的?法有明顯的弊端,當(dāng)Redis節(jié)點數(shù)需要動態(tài)增加或減少的時候,會造成?量的Key?法被命中。所以Redis中引?了?致性Hash算法。該算法對2^32取模,將Hash值空間組成虛擬的圓環(huán),整個圓環(huán)按順時針?向組織,每個節(jié)點依次為012…2^32-1之后將每個服務(wù)器進(jìn)?HashHashHash算法,將數(shù)據(jù)定位到特定的Redis服務(wù)器上。如果定位到的地?沒有Redis③Hash環(huán)的數(shù)據(jù)傾斜問題?部分集中在Redis集群的其中?臺或?臺服務(wù)器上。Hash算法運算后的數(shù)據(jù)?部分被存放在AB節(jié)點只存放了少量的數(shù)據(jù),久?久之A節(jié)點將被撐服務(wù)器節(jié)點,稱為虛擬節(jié)點,可以在服務(wù)器IP或者主機(jī)名后放置?個編號實現(xiàn)。例如上圖:將NodeA和NodeB兩個節(jié)點分為NodeA#1-A#3,NodeB#1-B#3【END 可進(jìn)???告 我們再來聊?聊Java hub?程Git ??梳理Redis張君鴻Java后端2019-09-點擊上?藍(lán)?字體,選擇“標(biāo)星”優(yōu)質(zhì)?章,第時間送達(dá)作者張君鴻RedisRedis?持多種不同的數(shù)據(jù)結(jié)構(gòu),包括5ListSortSet:有序集合Bitmaps:位圖,在string的基礎(chǔ)上進(jìn)?位操作,可以實現(xiàn)節(jié)省空間的數(shù)據(jù)結(jié)構(gòu)。Hyperloglog:?于估計?個set中元素數(shù)量的概率性的數(shù)據(jù)結(jié)構(gòu)。BloomFilter不同數(shù)據(jù)結(jié)構(gòu)的相同之處從上?的介紹,我們看到?持的數(shù)據(jù)結(jié)構(gòu)的不同,但其實,Redis的每?種數(shù)據(jù)結(jié)構(gòu)都由?個key和value?所有數(shù)據(jù)結(jié)構(gòu)的key的值都是任意合法的字符串,不同的數(shù)據(jù)結(jié)構(gòu)的區(qū)別就在于value的值的不同?不同?如,最簡簡單的String數(shù)據(jù)結(jié)構(gòu),其value為String,所以String?Hash數(shù)據(jù)結(jié)構(gòu),其value為?個哈希列表,所以Hash這?就列出String和Hash來講解說明,關(guān) RedisRedis官?將Redis令按照功能劃分為15個 分組,其中,Kyes令對所有的數(shù)據(jù)結(jié)構(gòu)都通?,因此,有必要在了解其他數(shù)據(jù)結(jié)構(gòu)命令前好好學(xué)習(xí)?下。keys命令的作?是列出Redis所有的ke,該命令的時間復(fù)雜度為O(N)N隨著Redis中key的數(shù)量增加?增加,因此Redis有?量的keykeys命令會執(zhí)?很?時間,?由于Rediskeys命令。"""otest1oneootest2oaobkeysheelo? expire設(shè)置expire設(shè)置key在多少秒之后過期,pexpire設(shè)置key在多少毫秒之后過期,成功返回1,失敗返回0expirekeypexpirekeyexists命令?于判斷?個或多個key是否存在,判斷多個key時,key之間?空格分隔,exists的返回值為整數(shù),表?當(dāng)前判斷有多少個key是存在的。existskey[keysetsettest1t1existstest1test2existstest3test3del命令?于刪除?個或多個key,多個key之間?空格分隔,其返回值為整數(shù),表?成功刪除了多少個存在的key,因此,如果只刪除?個key,則可以從返回值中判斷是否成功,如果刪除多個key,則只能得到刪除成功的數(shù)量。delkey[key...]tdeltestmsettest12test21deltest1test2test3deltest1test2msetmsettesttestvaluetest1test1expiretest10#設(shè)置10期expiretttttl和pttl命令?于獲取key的過期時間,其返回值為整型,代表的意義分為?種情況:當(dāng)key不存在或過期時間,返回-2。當(dāng)key存在且永久有效時,返回-1當(dāng)key有設(shè)置過期時間時,返回為剩下的秒數(shù)(pttlttlpttl?例(ttl的演?,pttlsettesttestsettesttest0ttlsettest1#永久有效ttltest1ttl設(shè)置key在某個時間戳過期,expreat參數(shù)時間戳?秒表?,?pexpireat則?毫秒表?,與expire和pexpire回10表?失敗。setsettesttestsettest1移除key的過期時間,將key設(shè)置為永久有效,當(dāng)key設(shè)置了過期時間,使?persist命令移除后返回1,如果key?就是永久有效的,則返回0persistkeysetsettesttestttltest效0(integer)1判斷key是什么類型的數(shù)據(jù)結(jié)構(gòu),返回值為string,list,set,hash,zset,分別表?我們前?介紹的Redis的5種基礎(chǔ)數(shù)據(jù)結(jié)geo,hyperloglog,bitmaps等復(fù)雜的數(shù)據(jù)結(jié)構(gòu),都是在這五種基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)上實現(xiàn),?如geo是zset類型,hyperloglog和bitmaps都為string。typetypesetsettesttesttypetesthsethtesttesttesttypehtest 樣除了負(fù)載均衡,Nginx快來薅當(dāng)當(dāng)?shù)??!聊聊Java數(shù)據(jù)庫不使?外鍵的9個理由 為什么RedisJava后端2019-11-點擊上?Java后端,選擇設(shè)為星標(biāo)作者draveness.me/redis-io-multiplexing最近在看UNIXRedisRedisI/O多路復(fù)?BlockingI/Oreadwrite(FileDescriptorFDRedis的就是I/O多路復(fù)?模型了: 關(guān)于select的具體使??法,在?絡(luò)上資料很多,這?就不過多展開介紹了;與此同時也有其它的I/O多路復(fù)?函數(shù)epoll/kqueue/evport,它們相?select性能更優(yōu)秀,同時也能? ReactorRedis服務(wù)采?Reactor的?式來實現(xiàn)? 處理器(每?個?絡(luò)連接其實都對應(yīng)?個?件描述符 處理器使?I/O多路復(fù)?模塊同時 多個FD,當(dāng)accept、read、write和close?件 會回調(diào)FD綁定的 處理器是在單線程上運?的,但是通過I/O多路復(fù)?模塊的引?,實現(xiàn)了同時對多個FD讀寫的 絡(luò)通信模型的性能,同時也可以保證整個Redis服務(wù)實現(xiàn)的簡單。I/Oselect、epoll、avportkqueueI/OstaticintaeApiCreate(aeEventLoopstaticintaeApiResize(aeEventLoop*eventLoop,intsetsize)staticvoidaeApi (aeEventLoop*eventLoop)staticintaeApiAddEvent(aeEventLoop*eventLoop,intfd,intmask)staticvoidaeApiDelEvent(aeEventLoop*eventLoop,intfd,intmask)staticintaeApiPoll(aeEventLoop*eventLoop,structtimeval*tvp)同時,因為各個函數(shù)所需要的參數(shù)不同,我們在每?個?模塊內(nèi)部通過?個aeApiState來需要的上下?信息{typedefstructaeApiState這些上下?信息 在eventLoop的void*state中,不 封裝selectselect可以FD的可讀、可寫以及出現(xiàn)錯誤的情況I/Oselectselect/*/*fileesreadable初始化?個可讀的fdset集合,保存需要可讀性的FD;使?FDSET將fd加?rfds;調(diào)?select?法rfds中的FD是否可讀selectFDRedisaeselectaeApiCreaterfdsstaticstaticintaeApiCreate(aeEventLoop{aeApiState*state=aeApiAddEventaeApiDelEventFDSETFDCLRfdsetFD整個aeselect?模塊中最重要的函數(shù)就是aeApiPoll,它是實際調(diào)?select函數(shù)的部分,其作?就是在I/O多路復(fù)?函數(shù)返回時,將對應(yīng)的FD加?aeEventLoop的fired數(shù)組中,并返回 staticstaticintaeApiPoll(aeEventLoop*eventLoop,structtimeval{aeApiState intretval,j,numevents=0;memcpy(&state->rfds,&state->rfds,sizeof(fdfor(j=0;j<=eventLoop->maxfd;{int mask=AEREADABLE;mask=AEWRITABLE;eventLoop->fired[numevents].fd=j;epollRedisepollepollcreateepollif(!state)return-{state->epfd=epollcreate(1024);/*1024isjustahintforthekernel{ ); return-returnstaticstaticintaeApiAddEvent(aeEventLoop*eventLoop,intfd,int{aeApiState*state=eventLoop-structepolleventee={0};/*avoidvalgrindwarning/*Ifthefdwasalreadymonitoredforsomeevent,weneeda*operation.OtherwiseweneedanADDoperation.if(mask&AEWRITABLE)ee.events=EPOLLOUT;ee.data.fd=fd;returnepollselectepollwaitFDepollwait回時會提供?個epollevent數(shù)組:typedeftypedefunionepolldata fd/**/uint64tu64;其
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 默契中考語文作文
- 物流搬運設(shè)備選型指南考核試卷
- 描寫北京初二上冊語文作文
- 健身器材制造業(yè)資本運作與投融資策略考核試卷
- 殘疾人權(quán)益倡導(dǎo)與法律援助考核試卷
- 空氣流量測量考核試卷
- 柑橘種植園農(nóng)業(yè)產(chǎn)業(yè)鏈優(yōu)化策略考核試卷
- 玻璃保溫容器行業(yè)人才培養(yǎng)與選拔考核試卷
- 傾聽高三語文作文
- 滾動軸承市場與發(fā)展趨勢考核試卷
- 高墩(40m高)安全專項施工方案(專家)
- 上消化道內(nèi)鏡操作課件
- 海洋環(huán)境監(jiān)測概述課件
- 汽車文化中的家庭與生活
- 輪狀病毒活疫苗
- 《大學(xué)語文》-《夢狼》
- 第十章-幼兒的個性-第一、二節(jié)
- JGT266-2011 泡沫混凝土標(biāo)準(zhǔn)規(guī)范
- 平安壽險退保 申請書
- 推進(jìn)中國教育數(shù)字化的戰(zhàn)略與政策
- 生育服務(wù)證辦理承諾書
評論
0/150
提交評論