金年会

每日经济新闻
要闻

每经网首页 > 要闻 > 正文

久草springboot与lettuce在线整合-腾讯云开发者社区-腾讯云

钱学森 2025-11-02 03:14:21

每经编辑|陈平原    

当地时间2025-11-02,jdsklfjkwebbkjfbsdkhjvbuigdbajhs,张婉莹mv精彩片段

云端java开发(fa)新纪(ji)元(yuan):springboot与(yu)lettuce的珠(zhu)联璧(bi)合

在飞(fei)速(su)发展的互(hu)联网时代(dai),java开(kai)发(fa)正经历着(zhe)一场深(shen)刻(ke)的变(bian)革(ge)。微服务架构的兴起,对应用(yong)的性(xing)能(neng)、可扩展(zhan)性(xing)及稳定性提(ti)出了前所未有的挑战。作为java开发领域(yu)两大明(ming)星技(ji)术(shu),SpringBoot凭(ping)借其(qi)“约(yue)定大(da)于配置”的理(li)念,极大地(di)简化了项(xiang)目的(de)搭建和(he)开发(fa)流程,让(rang)开发(fa)者能够更(geng)专(zhuan)注(zhu)于业(ye)务逻(luo)辑的(de)实(shi)现。

而Redis,作为(wei)一款(kuan)高(gao)性能的内(nei)存数(shu)据库,以其出色(se)的读(du)写速度和(he)丰富(fu)的(de)数据结(jie)构,在缓(huan)存(cun)、消息(xi)队列(lie)、分布式锁(suo)等(deng)场(chang)景(jing)中扮(ban)演(yan)着至关重要的(de)角色。如何(he)高效(xiao)、稳定(ding)地(di)将SpringBoot与Redis相(xiang)结合,一(yi)直(zhi)是(shi)众(zhong)多开(kai)发者(zhe)关注的(de)焦点(dian)。

传(chuan)统的(de)Java程序(xu)与Redis的(de)交(jiao)互,往往需要(yao)引入(ru)Redis客(ke)户(hu)端库(ku),如Jedis。Jedis虽(sui)然功能(neng)强大,但(dan)其基(ji)于(yu)连接(jie)池(chi)的模式(shi),在面对高并(bing)发(fa)请求时(shi),可(ke)能会(hui)出(chu)现(xian)连(lian)接耗(hao)尽、性能(neng)瓶(ping)颈(jing)等问(wen)题。而(er)且(qie),Jedis的API设(she)计相(xiang)对(dui)底(di)层,开发者(zhe)需要(yao)手动(dong)管(guan)理(li)连接、序列化(hua)与(yu)反序(xu)列(lie)化等操作,增(zeng)加了开发复杂(za)度。

正是(shi)在(zai)这样(yang)的(de)背景下(xia),Lettuce横(heng)空出(chu)世,为SpringBoot与Redis的整(zheng)合(he)带(dai)来了(le)全新(xin)的解决方案(an)。Lettuce是(shi)一(yi)个功(gong)能(neng)强(qiang)大(da)、高性能(neng)的(de)JavaRedis客户(hu)端,它(ta)基于Netty,采用(yong)了非(fei)阻(zu)塞、异步(bu)的I/O模型(xing),能够更(geng)有效(xiao)地处(chu)理高并(bing)发请(qing)求(qiu)。

与Jedis不同,Lettuce支(zhi)持Reactor模(mo)式,能(neng)够(gou)实现真正的异步(bu)操作,极大(da)地提(ti)升(sheng)了(le)Redis的(de)吞吐量和(he)响应速(su)度。更(geng)重要(yao)的是,Lettuce与SpringDataRedis进(jin)行了深度(du)整合(he),通(tong)过SpringBootStarter,开发者可(ke)以(yi)轻(qing)松地(di)将Lettuce集成到SpringBoot项(xiang)目中,享(xiang)受到SpringBoot的自(zi)动化配置(zhi)和强大的生态系统(tong)。

为何(he)选择(ze)Lettuce?性能(neng)与(yu)活力(li)的(de)双重(zhong)奏

选择Lettuce作为SpringBoot项目中(zhong)的Redis客(ke)户端(duan),并非偶然。它在(zai)性能上(shang)的(de)卓越(yue)表现,是吸(xi)引开发者的(de)一大关(guan)键(jian)。

异(yi)步(bu)非(fei)阻(zu)塞(sai)I/O:Lettuce基于(yu)Netty,天然支(zhi)持异步(bu)非阻塞I/O。这(zhe)意(yi)味(wei)着当一个(ge)Redis命令发(fa)送(song)出去(qu)后,应用程序(xu)不(bu)必等待命令执(zhi)行完(wan)毕,而是可(ke)以继续处(chu)理其(qi)他任(ren)务,直到收(shou)到Redis的响应。这(zhe)种(zhong)设计极大地提(ti)高了系统的并发处理能力,特(te)别是在(zai)高(gao)QPS(每秒(miao)请求(qiu)数(shu))的场(chang)景(jing)下,优势尤为(wei)明显(xian)。

相(xiang)比之(zhi)下(xia),Jedis虽(sui)然也提(ti)供了(le)连接(jie)池(chi),但(dan)其同步(bu)阻塞的(de)特性(xing)在(zai)高(gao)并发下容(rong)易(yi)成为性(xing)能(neng)瓶颈(jing)。连接(jie)复用(yong)与连(lian)接池:Lettuce同样(yang)支持(chi)连(lian)接(jie)池(chi),但其(qi)连(lian)接(jie)池(chi)的实现方(fang)式(shi)更加高(gao)效。它(ta)能(neng)够(gou)智能(neng)地管(guan)理连接的(de)生命(ming)周(zhou)期,并在(zai)必(bi)要(yao)时进(jin)行(xing)重连,保(bao)证了(le)连接(jie)的(de)可用性。Lettuce还(hai)支(zhi)持连(lian)接(jie)的复用,减少(shao)了(le)创建和销毁(hui)连接的(de)开(kai)销。

多(duo)线程安全(quan):Lettuce是(shi)线(xian)程安全的,这意(yi)味着(zhe)多个线程可以(yi)安全(quan)地共享同一(yi)个Lettuce连接(jie)实例(li),进一(yi)步(bu)简(jian)化(hua)了(le)多(duo)线程(cheng)环(huan)境下(xia)的(de)Redis操作(zuo)。丰富的(de)数据结构(gou)支持:Lettuce不(bu)仅(jin)支持(chi)Redis的String、List、Set、Hash、SortedSet等(deng)基本(ben)数据(ju)结构,还(hai)对(dui)Redis的Streams、Geo、HyperLogLog等(deng)高(gao)级数(shu)据(ju)结构(gou)提(ti)供(gong)了(le)良好的(de)支持,满足了开(kai)发者(zhe)日(ri)益(yi)增长(zhang)的功能需(xu)求(qiu)。

Sentinel与(yu)Cluster支持(chi):对于(yu)需要高(gao)可(ke)用(yong)和(he)分布(bu)式部(bu)署(shu)的(de)场景,Lettuce提(ti)供了(le)对(dui)RedisSentinel和RedisCluster的(de)完善支(zhi)持。这(zhe)意味着(zhe)我们可以(yi)轻(qing)松地构建高(gao)可用的Redis集群,并(bing)通(tong)过Lettuce客(ke)户端(duan)无缝地(di)进(jin)行连接(jie)和(he)管(guan)理,无(wu)需担(dan)心(xin)单点故障。

SpringBoot与(yu)Lettuce的“在线整合”:从(cong)配置(zhi)到实践(jian)

“在(zai)线(xian)整合(he)”并非指(zhi)某种(zhong)特定的技(ji)术(shu)名词,而是指在SpringBoot项目(mu)中,如何通过简(jian)单的配(pei)置和编码(ma),将Lettuce无缝地集成进来,从(cong)而实现与Redis的(de)“实(shi)时(shi)、在(zai)线(xian)”交(jiao)互(hu)。腾(teng)讯(xun)云(yun)开发者(zhe)社区的(de)这(zhe)篇(pian)文(wen)章,将(jiang)为(wei)你揭示这(zhe)一过(guo)程的精(jing)髓。

在(zai)SpringBoot项(xiang)目(mu)中(zhong)引(yin)入Lettuce的依赖(lai)。只需在pom.xml中添(tian)加(jia)以下(xia)依赖:

org.springframework.bootspring-boot-starter-data-redisio.lettucelettuce-core

SpringBootStarterDataRedis会(hui)自动配(pei)置(zhi)RedisTemplate,并默(mo)认(ren)使用(yong)Lettuce作为其客(ke)户端(duan)。在application.properties或application.yml文(wen)件(jian)中配(pei)置Redis连(lian)接信息:

#application.propertiesspring.redis.host=localhostspring.redis.port=6379spring.redis.password=#如(ru)果有密码spring.redis.database=0

或(huo)者在application.yml中:

#application.ymlspring:redis:host:localhostport:6379password:#如果(guo)有(you)密(mi)码database:0

配置完成(cheng)后(hou),SpringBoot就会自动实(shi)例化一(yi)个RedisTemplateBean,该Bean已经(jing)集成(cheng)了Lettuce客户端(duan),可(ke)以直接在代(dai)码中(zhong)使(shi)用。

RedisTemplate:SpringDataRedis的(de)核(he)心抽象

RedisTemplate是(shi)SpringDataRedis提供(gong)的核心(xin)抽(chou)象,它(ta)屏蔽(bi)了(le)底层Redis客(ke)户端的差异,提供了一(yi)套统一(yi)的(de)、面向对(dui)象的(de)操作(zuo)API。通(tong)过RedisTemplate,我们(men)可以(yi)方(fang)便(bian)地进(jin)行各种(zhong)Redis操(cao)作,例(li)如:

String操作:opsForValue().set("mykey","myvalue"),opsForValue().get("mykey")List操作:opsForList().leftPush("mylist","item1"),opsForList().rightPop("mylist")Hash操(cao)作:opsForHash().put("myhash","field1","value1"),opsForHash().get("myhash","field1")Set操(cao)作:opsForSet().add("myset","member1"),opsForSet().members("myset")SortedSet操(cao)作:opsForZSet().add("myzset","member",1.0),opsForZSet().range("myzset",0,-1)

RedisTemplate默(mo)认使(shi)用JdkSerializationRedisSerializer进(jin)行序(xu)列化和反(fan)序(xu)列(lie)化。在很多场景(jing)下,这(zhe)可(ke)能不(bu)够(gou)高效(xiao),或(huo)者(zhe)与其(qi)他系统不兼容(rong)。因此(ci),我们通常(chang)需要(yao)自定义RedisTemplate的(de)序列(lie)化(hua)器(qi),例如(ru)使用(yong)Jackson的GenericJackson2JsonRedisSerializer来支持JSON序列(lie)化(hua),或者(zhe)使用StringRedisSerializer来存(cun)储字符(fu)串。

@ConfigurationpublicclassRedisConfig{@BeanpublicRedisTemplateredisTemplate(RedisConnectionFactoryfactory){RedisTemplatetemplate=newRedisTemplate<>();template.setConnectionFactory(factory);//使用Jackson2JsonRedisSerializer来(lai)序列(lie)化和(he)反序(xu)列化(hua)redis的value值GenericJackson2JsonRedisSerializerjacksonSeializer=newGenericJackson2JsonRedisSerializer();template.setValueSerializer(jacksonSeializer);//使用(yong)StringRedisSerializer来序(xu)列化(hua)和反(fan)序列(lie)化redis的key值template.setKeySerializer(newStringRedisSerializer());//hash的(de)key也Nên使(shi)用(yong)StringRedisSerializer来(lai)序列(lie)化template.setHashKeySerializer(newStringRedisSerializer());template.setHashValueSerializer(jacksonSeializer);template.afterPropertiesSet();returntemplate;}}

通(tong)过这样(yang)的配置(zhi),我们(men)就可(ke)以在(zai)SpringBoot应用(yong)中(zhong),高效、便(bian)捷地(di)使(shi)用Lettuce驱动的Redis服务(wu)了。这正(zheng)是SpringBoot与(yu)Lettuce“在线整合(he)”的(de)魅力所在(zai)——让复杂(za)的技术细(xi)节(jie)变(bian)得简单,让(rang)开发者(zhe)聚焦于(yu)业务价(jia)值的创造(zao)。

深(shen)入Lettuce:揭(jie)秘高(gao)性能背(bei)后(hou)的异(yi)步之(zhi)魂

在上一(yi)部分,我们已经(jing)领略了(le)SpringBoot与(yu)Lettuce整(zheng)合(he)的便捷(jie)性(xing)。但(dan)要(yao)真正驾(jia)驭这一(yi)技术组(zu)合,我们(men)还需要深(shen)入理(li)解Lettuce为何能(neng)够提(ti)供如(ru)此出(chu)色的性(xing)能,尤其(qi)是其(qi)异步(bu)非阻塞(sai)I/O的(de)精髓。

Lettuce之(zhi)所(suo)以能(neng)够实(shi)现(xian)高性能(neng),核(he)心在(zai)于(yu)其(qi)基于Netty的(de)事件驱动(dong)模型。Netty是(shi)一(yi)个高性能(neng)、异步事件(jian)驱动(dong)的(de)网络应(ying)用(yong)框(kuang)架,它(ta)采(cai)用Reactor模式来(lai)处(chu)理网(wang)络I/O。简单来说,Reactor模(mo)式(shi)包含(han)一个事(shi)件循(xun)环(huan)(EventLoop),负(fu)责监(jian)听网(wang)络套(tao)接(jie)字(zi)上的(de)事(shi)件(如连(lian)接建立(li)、数(shu)据可(ke)读(du)、数据可(ke)写等(deng))。

当事(shi)件发(fa)生时(shi),Reactor会将事(shi)件分派给相应的Handler进行(xing)处理(li)。

Lettuce利(li)用Netty的这个特性,将Redis命令(ling)的(de)发送与(yu)响(xiang)应(ying)处理(li)解耦。当一(yi)个Redis命令(ling)被发送(song)到Redis服务器时,Lettuce不(bu)会(hui)阻(zu)塞当前线(xian)程等待响(xiang)应(ying)。相(xiang)反(fan),它会(hui)注(zhu)册一(yi)个回调(diao)函(han)数(Callback),一(yi)旦Redis服(fu)务器返回(hui)响应,Netty的(de)事件循(xun)环(huan)就会(hui)触发这(zhe)个回调函(han)数,处(chu)理响(xiang)应(ying)数(shu)据。

这(zhe)种异(yi)步处(chu)理方(fang)式带(dai)来了(le)几个(ge)显著(zhu)的(de)优势:

高(gao)并发能力:在一(yi)个线程处理(li)多个Redis命令时,当一个(ge)命令(ling)在(zai)等待(dai)Redis服务器的响(xiang)应(ying)时,该(gai)线(xian)程(cheng)可(ke)以(yi)立即去(qu)处(chu)理下(xia)一个(ge)命(ming)令(ling),而不(bu)是像(xiang)同(tong)步阻塞(sai)模式那(na)样白(bai)白等(deng)待。这(zhe)使得(de)单(dan)个线程能够高(gao)效(xiao)地处理大量(liang)并发请求,极大(da)地提(ti)升(sheng)了系统(tong)的吞(tun)吐量(liang)。资源(yuan)利用率:异(yi)步非(fei)阻塞(sai)I/O避免(mian)了(le)为每个请求创建(jian)大(da)量线程来等(deng)待I/O操作完成,从而减少了线程(cheng)上下文切换的(de)开销,提(ti)高(gao)了CPU的利用率。

低延迟(chi):通过减(jian)少(shao)不(bu)必(bi)要的等(deng)待(dai)时间(jian),异(yi)步(bu)I/O模型有(you)助于降(jiang)低(di)整(zheng)体的(de)请求响应(ying)延(yan)迟。

Lettuce的(de)API风(feng)格:同步与(yu)异步的艺(yi)术

Lettuce提(ti)供了(le)两种主(zhu)要(yao)的API风格(ge):

同步API:RedisClient和(he)StatefulRedisConnection提供(gong)了一(yi)种同步(bu)阻塞的(de)API,其使(shi)用方(fang)式(shi)与(yu)Jedis类似(shi),适(shi)合于对(dui)异步(bu)编(bian)程(cheng)不(bu)熟悉的(de)开发(fa)者(zhe),或(huo)者(zhe)在(zai)不(bu)需要(yao)极(ji)致性(xing)能(neng)的场(chang)景(jing)下(xia)使(shi)用(yong)。异步API:RedisClient和StatefulRedisConnection同(tong)样可以(yi)通(tong)过(guo)commands()方法(fa)获取异(yi)步命令(ling)接口(kou),返(fan)回(hui)的是(shi)RedisFuture对象。

RedisFuture代表了一个异(yi)步操作(zuo)的(de)结(jie)果,它(ta)允(yun)许开(kai)发者(zhe)注册(ce)回调函数来处(chu)理(li)命(ming)令执(zhi)行(xing)的结果(guo),或者(zhe)使用get()方法(fa)(会阻塞(sai)当(dang)前线(xian)程)来(lai)获取结果(guo)。ReactiveAPI:Lettuce还提供了(le)基于(yu)Reactor和RxJava的响(xiang)应式API,如(ru)RedisReactiveCommands和RedisRxCommands。

这(zhe)种API风(feng)格更(geng)符(fu)合函数式编(bian)程的理念(nian),能够(gou)更优雅(ya)地处理(li)复杂的数(shu)据流和事(shi)件序列,非(fei)常(chang)适合(he)构建响(xiang)应式的(de)、高弹(dan)性(xing)的微(wei)服务。

在SpringDataRedis的整合中,默(mo)认使(shi)用的是(shi)Lettuce的(de)异步API。当(dang)你(ni)在代码中(zhong)调用redisTemplate.opsForValue().get("mykey")时(shi),SpringDataRedis底层会通(tong)过Lettuce执(zhi)行一个(ge)异步命(ming)令(ling),并在(zai)需要(yao)结果时(shi)等(deng)待其完(wan)成。

构建(jian)高可用的Redis集(ji)群(qun):Lettuce的Sentinel与Cluster支(zhi)持(chi)

在生(sheng)产环境(jing)中(zhong),为(wei)了(le)保证Redis服(fu)务的可(ke)用性和稳定性(xing),我们通(tong)常会部(bu)署(shu)RedisSentinel集群或RedisCluster。Lettuce对这(zhe)两种部(bu)署模式(shi)提(ti)供了良好的(de)支(zhi)持。

1.RedisSentinel集群

RedisSentinel是Redis的(de)高可用(yong)性(xing)解(jie)决(jue)方案,它负(fu)责监(jian)控Redis主(zhu)从(cong)节(jie)点,并(bing)在(zai)主(zhu)节(jie)点发生(sheng)故(gu)障(zhang)时自动进(jin)行故(gu)障(zhang)转移。

在(zai)SpringBoot中(zhong)配(pei)置(zhi)Lettuce连接Sentinel,只(zhi)需要在application.properties或(huo)application.yml中(zhong)指(zhi)定Sentinel的(de)地址(zhi)以(yi)及(ji)要连(lian)接的Redismaster名称(cheng):

#application.propertiesspring.redis.sentinel.master=mymasterspring.redis.sentinel.nodes=localhost:26379,localhost:26380,localhost:26381

SpringBootStarterDataRedis会(hui)自动(dong)配(pei)置RedisConnectionFactory,使(shi)其能够连(lian)接(jie)到(dao)Sentinel,并自动发现主(zhu)节点(dian)。这(zhe)样(yang),即使(shi)主节(jie)点发(fa)生故(gu)障,Sentinel也(ye)会自动(dong)进行故(gu)障转(zhuan)移,而(er)Lettuce连接会无缝地切换(huan)到(dao)新(xin)的主(zhu)节(jie)点,应用几(ji)乎(hu)感知(zhi)不到服(fu)务(wu)的中断。

2.RedisCluster集(ji)群(qun)

RedisCluster是Redis的分布式解决(jue)方案,它将数据分散(san)存储(chu)在(zai)多(duo)个Redis节(jie)点(dian)上,实(shi)现(xian)了数(shu)据的分片和(he)高可用。

配置(zhi)Lettuce连接(jie)RedisCluster,同样在application.properties或(huo)application.yml中(zhong)指定Cluster的节点地址:

#application.propertiesspring.redis.cluster.nodes=localhost:7000,localhost:7001,localhost:7002,localhost:7003,localhost:7004,localhost:7005

SpringBootStarterDataRedis同样会为(wei)Cluster模式自动配置RedisConnectionFactory。Lettuce客户端(duan)会连接到指定的Cluster节点,并(bing)自(zi)动获(huo)取Cluster的(de)拓扑信(xin)息。在进(jin)行Redis操作(zuo)时(shi),Lettuce会根(gen)据Key的(de)哈希(xi)值,自(zi)动将(jiang)请(qing)求路由(you)到正确的节点(dian)。

如果Cluster发生节点(dian)增减(jian)或(huo)故障转(zhuan)移,Lettuce也能够(gou)感知并(bing)自动更新其(qi)内(nei)部的Cluster拓扑视(shi)图。

腾(teng)讯(xun)云(yun)开发者社(she)区:赋(fu)能(neng)Java开(kai)发者(zhe),解(jie)锁(suo)云端(duan)开发(fa)新篇章

腾讯云开(kai)发者社(she)区,作(zuo)为国(guo)内(nei)领(ling)先的技(ji)术(shu)交流(liu)平台,汇聚了众(zhong)多优(you)秀的(de)Java开(kai)发(fa)者(zhe)和(he)技术专家(jia)。在这(zhe)篇文章(zhang)中(zhong),我们借助“久草(cao)springboot与lettuce在(zai)线(xian)整合”这一主(zhu)题,深入(ru)剖(pou)析了SpringBoot与Lettuce结合的(de)技术(shu)优势(shi),以及在云端(duan)开发中(zhong)的实(shi)践价值。

社(she)区不仅(jin)提供了详实(shi)的教程和(he)技术文(wen)章,还积(ji)极组织线(xian)上(shang)线(xian)下的技术(shu)分享和交流(liu)活(huo)动,为(wei)开发(fa)者提供了一个学习、成(cheng)长(zhang)和合作的(de)优(you)质(zhi)平台。通(tong)过(guo)对(dui)SpringBoot和(he)Lettuce等技(ji)术的(de)深入(ru)探(tan)讨,开(kai)发(fa)者可(ke)以更好地利用(yong)云(yun)原(yuan)生技术,构(gou)建高(gao)性(xing)能、高可用、易(yi)于(yu)扩展的(de)java应(ying)用。

总(zong)结

SpringBoot与Lettuce的(de)整合,是(shi)现代Java开(kai)发(fa)中构建(jian)高性(xing)能、高可用Redis应用(yong)的关键(jian)。Lettuce凭(ping)借其(qi)异步非阻(zu)塞I/O和(he)对Sentinel、Cluster的强大支持(chi),为开(kai)发者(zhe)提供(gong)了卓(zhuo)越(yue)的(de)性能(neng)和可(ke)靠(kao)性。而SpringBootStarterDataRedis的(de)出(chu)现,更是(shi)极大(da)地(di)简化了这一(yi)整合过(guo)程(cheng),让开发(fa)者能(neng)够以(yi)更低的(de)成(cheng)本、更(geng)高(gao)的(de)效率(lv),构(gou)建出(chu)满足业务(wu)需求的云(yun)端java应用。

腾讯(xun)云开发(fa)者社(she)区(qu),将(jiang)持续(xu)关(guan)注(zhu)并分享(xiang)这些(xie)前(qian)沿技术(shu),赋能(neng)每一位开(kai)发(fa)者,共(gong)同迈向(xiang)云端java开(kai)发(fa)的新(xin)纪元。

2025-11-02,少司缘黄化,汇丰人寿董事长落定!三重挑战当前,"双精算"掌舵者能否破局?

1.ysl口红水蜜桃色号6004,南京银行江志纯:积极践行价值分享理念 持续落实中期分红vpswindows野外app,翰博高新:不存在逾期担保

图片来源:每经记者 陈志荣 摄

2.拨萝人+Lutubu在线视频入口,联赢激光(688518)2025年中报简析:营收净利润同比双双增长,金年会应收账款体量较大

3.抖阴软件视频+触手面包车正版游戏,CounterPoint 报告 2025Q2 全球 OLED 面板出货量:中国 OLED 面板正加速渗透全球市场

口述在车里 我7次+各种黄频,光大同创:9月5日将召开2025年半年度业绩说明会

七猫精品只要有一个-七猫精品只要有一个最新版

封面图片来源:图片来源:每经记者 名称 摄

如需转载请与《每日经济新闻》报社联系。
未经《每日经济新闻》报社授权,严禁转载或镜像,违者必究。

读者热线:4008890008

特别提醒:如果我们使用了您的图片,请作者与本站联系索取稿酬。如您不希望作品出现在本站,可联系金年会要求撤下您的作品。

欢迎关注每日经济新闻APP

每经经济新闻官方APP

0

0

Sitemap