当前位置: 首页 > news >正文

苏州产品推广公司兰州模板网站seo价格

苏州产品推广公司,兰州模板网站seo价格,网站推广分销系统,个人网站怎么接广告1. 准备工作 环境说明 java 8;redis7.2.2,redis集成RedisSearch、redisJson 模块;spring boot 2.5在执行 redis 命令, 或者监控 程序执行的redis 指令时,可以采用 redisinsight查看,下载地址。 背景说明 需…

1. 准备工作

  1. 环境说明

    • java 8;redis7.2.2,redis集成RedisSearch、redisJson 模块;spring boot 2.5
    • 在执行 redis 命令, 或者监控 程序执行的redis 指令时,可以采用 redisinsight查看,下载地址。
  2. 背景说明

    • 需要对在线的用户进行搜索,之前是存储成 string, 每次搜索需要先全部遍历,然后加载到内存,然后进行筛选。十分消耗性能并且速度极慢。使用 redisJson + redisSearch 可以极大的优化查询性能
    • 项目后期需要支持全文搜索。
  3. 实现思路:采用 RedisTemplate, 执行 lua 脚本。

2. 实现

2.1 配置

引入依赖

        <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency>

配置 redisTermplate, 配置 lua 脚本,便于 redisTemplate 执行[^2]

@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport
{@Bean@SuppressWarnings(value = { "unchecked", "rawtypes" })public RedisTemplate<String, Object> redisTemplate1(RedisConnectionFactory connectionFactory){RedisTemplate<String, Object> template = new RedisTemplate<>();template.setConnectionFactory(connectionFactory);RedisSearchSerializer serializer = new RedisSearchSerializer(Object.class);// 使用StringRedisSerializer来序列化和反序列化redis的key值template.setKeySerializer(new StringRedisSerializer());template.setValueSerializer(serializer);// Hash的key也采用StringRedisSerializer的序列化方式template.setHashKeySerializer(new StringRedisSerializer());template.setHashValueSerializer(serializer);template.afterPropertiesSet();return template;}// lua 脚本配置@Beanpublic DefaultRedisScript<String> jsonSetScript(){DefaultRedisScript<String> redisScript = new DefaultRedisScript<>();redisScript.setScriptText("return redis.call('JSON.SET', KEYS[1], '$', ARGV[1]);");redisScript.setResultType(String.class);return redisScript;}@Beanpublic DefaultRedisScript<Object> jsonGetScript(){DefaultRedisScript<Object> redisScript = new DefaultRedisScript<>();redisScript.setScriptText("return redis.call('JSON.GET', KEYS[1]);");redisScript.setResultType(Object.class);return redisScript;}@Beanpublic DefaultRedisScript<List> jsonSearchScript(){DefaultRedisScript<List> redisScript = new DefaultRedisScript<>();redisScript.setScriptText("local offset = tonumber(ARGV[2])\n" +"local count = tonumber(ARGV[3])\n" +"return redis.call('FT.SEARCH', KEYS[1], ARGV[1], 'return', 0, 'limit', offset, count);");redisScript.setResultType(List.class);return redisScript;}
}

RedisSearchSerializer 序列化配置


import com.alibaba.fastjson2.JSON;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;import java.nio.charset.Charset;/*** Redis使用FastJson序列化** @author ruoyi*/
public class RedisSearchSerializer<T> implements RedisSerializer<T> {public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");private Class<T> clazz;public RedisSearchSerializer(Class<T> clazz) {super();this.clazz = clazz;}@Overridepublic byte[] serialize(T t) throws SerializationException {if (t == null) {return new byte[0];}if (t instanceof String) {return ((String)t).getBytes(DEFAULT_CHARSET);}return JSON.toJSONString(t).getBytes(DEFAULT_CHARSET);}@Overridepublic T deserialize(byte[] bytes) throws SerializationException {if (bytes == null || bytes.length <= 0) {return null;}String str = new String(bytes, DEFAULT_CHARSET);// 不是 json 也不是 序列化的字符串,那就只能是数字,如果不是数字直接返回if (!str.startsWith("{") && !str.startsWith("[") && !str.startsWith("\"") && !str.matches("^\\d*$")) {return clazz.cast(str);}return JSON.parseObject(str, clazz);}
}

数据实体类

@Data
public class LoginUser {private String ipaddr;private String username;public LoginUser(String ipaddr, String username) {this.ipaddr = ipaddr;this.username = username;}
}

2.2 封装 对 json的 操作

redisService


@Service
public class RedisService {@Autowiredprivate RedisScript<String> jsonSetScript;@Autowiredprivate RedisScript<Object> jsonGetScript;@Autowiredprivate RedisScript<List> jsonSearchScript;@Autowiredprivate RedisTemplate<String, Object> redisTemplate1;public LoginUser getLoginUser(String uuid) {String key = RedisKeys.LOGIN_TOKEN_KEY + uuid;JSONObject obj = (JSONObject) redisTemplate1.execute(this.jsonGetScript, Collections.singletonList(key));if (obj == null) {return null;}return obj.toJavaObject(LoginUser.class);}public void setLoginUser(String uuid, LoginUser loginUser, int expireTime, TimeUnit unit) {String key = RedisKeys.LOGIN_TOKEN_KEY + uuid;redisTemplate1.execute(this.jsonSetScript, Collections.singletonList(key), loginUser);redisCache.expire(key, expireTime, unit);}public Page<String> searchLoginUser(String query, Pageable page) {List list = redisTemplate1.execute(this.jsonSearchScript,Collections.singletonList("login_tokens_idx"),query, page.getOffset(), page.getPageSize());Long total = (Long) list.get(0);List<String> ids = new ArrayList<>();for (int i = 1; i < list.size(); i++) {ids.add(((String) list.get(i)).replaceAll(RedisKeys.LOGIN_TOKEN_KEY, ""));}return new PageImpl<>(ids, page, total);}public interface RedisKeys {String LOGIN_TOKEN_KEY = "login_tokens1:";}
}

2.3 在 redis 中创建索引

redis 创建索引[^1], 其中 ipaddr 是 IP 字段,包含 “.” 等特殊字符,所以需要将 索引中的 ipaddr 设置成 tag 类型,才能搜索到[^3]

# 连接redis, 如果使用 redisinsight 则不需要这步
redis-cli -a "password"
# 创建索引
FT.CREATE login_tokens_idx on JSON prefix 1 "login_tokens1:"SCHEMA $.ipaddr tag $.username text

3. 测试


import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringRunner;import java.util.concurrent.TimeUnit;@RunWith(SpringRunner.class)
@SpringBootTest(classes = YourApplication.class)
@ActiveProfiles("prod-local")
public class RedisServiceTest {@Autowiredprivate RedisService redisService;@Testpublic void testSetAndGetLoginUser() {LoginUser user = new LoginUser("192.168.1.1", "testUser");redisService.setLoginUser("123456", user, 60, TimeUnit.SECONDS);LoginUser getUser = redisService.getLoginUser("123456");Assert.assertEquals(user.getIpaddr(), getUser.getIpaddr());Assert.assertEquals(user.getUsername(), getUser.getUsername());}@Testpublic void testDeleteLoginUser() {LoginUser user = new LoginUser("192.168.1.1", "testUser");redisService.setLoginUser("123456", user, 60, TimeUnit.SECONDS);redisService.deleteLoginUser("123456");LoginUser getUser = redisService.getLoginUser("123456");Assert.assertNull(getUser);}@Testpublic void testSearchLoginUser() {// 添加测试数据LoginUser user1 = new LoginUser("192.168.1.1", "user1");LoginUser user2 = new LoginUser("192.168.1.2", "user2");redisService.setLoginUser("123456", user1, 60, TimeUnit.SECONDS);redisService.setLoginUser("789012", user2, 60, TimeUnit.SECONDS);// 搜索测试Page<String> page = redisService.searchLoginUser("user*", PageRequest.of(0, 10));Assert.assertEquals(page.getTotalElements(), 2);Assert.assertEquals(page.getContent().size(), 2);Assert.assertTrue(page.getContent().contains("123456"));Assert.assertTrue(page.getContent().contains("789012"));}
}

文章转载自:
http://dinncogondole.ssfq.cn
http://dinncopresidial.ssfq.cn
http://dinncocontralto.ssfq.cn
http://dinncoswarth.ssfq.cn
http://dinnconovachord.ssfq.cn
http://dinncolpg.ssfq.cn
http://dinncoquaintness.ssfq.cn
http://dinncodolorimetry.ssfq.cn
http://dinnconard.ssfq.cn
http://dinncostrategetic.ssfq.cn
http://dinncotun.ssfq.cn
http://dinncohyracoid.ssfq.cn
http://dinncoasceticism.ssfq.cn
http://dinncoasid.ssfq.cn
http://dinncomultinomial.ssfq.cn
http://dinncofascisti.ssfq.cn
http://dinncohallstattian.ssfq.cn
http://dinncodynasticism.ssfq.cn
http://dinncokalsomine.ssfq.cn
http://dinncoxerosere.ssfq.cn
http://dinncoaustralis.ssfq.cn
http://dinncobenz.ssfq.cn
http://dinncoplunder.ssfq.cn
http://dinncoagriculture.ssfq.cn
http://dinncoshunga.ssfq.cn
http://dinncotripack.ssfq.cn
http://dinncoexplorative.ssfq.cn
http://dinncooutdistance.ssfq.cn
http://dinncophosphoresce.ssfq.cn
http://dinncofranglais.ssfq.cn
http://dinncoseminarist.ssfq.cn
http://dinncosnippers.ssfq.cn
http://dinncotribology.ssfq.cn
http://dinncoriemannian.ssfq.cn
http://dinncoreversi.ssfq.cn
http://dinncomagnesium.ssfq.cn
http://dinncorecirculate.ssfq.cn
http://dinncobankrupt.ssfq.cn
http://dinncounderdiagnosis.ssfq.cn
http://dinncolunatic.ssfq.cn
http://dinncolemnian.ssfq.cn
http://dinncomatchbox.ssfq.cn
http://dinncocameral.ssfq.cn
http://dinncopseudocide.ssfq.cn
http://dinncolapin.ssfq.cn
http://dinncogreenshank.ssfq.cn
http://dinncoopsonin.ssfq.cn
http://dinncodionysos.ssfq.cn
http://dinncoceliotomy.ssfq.cn
http://dinncocit.ssfq.cn
http://dinncogreenbug.ssfq.cn
http://dinncointernship.ssfq.cn
http://dinncocommutable.ssfq.cn
http://dinncoumw.ssfq.cn
http://dinncojurisprudence.ssfq.cn
http://dinncohydrogel.ssfq.cn
http://dinncovoivode.ssfq.cn
http://dinncochokey.ssfq.cn
http://dinncowftu.ssfq.cn
http://dinncoimpulsively.ssfq.cn
http://dinncosheaves.ssfq.cn
http://dinncobeylic.ssfq.cn
http://dinncosquelcher.ssfq.cn
http://dinncoabegging.ssfq.cn
http://dinncomission.ssfq.cn
http://dinncoskullcap.ssfq.cn
http://dinncocoronet.ssfq.cn
http://dinncomedicaster.ssfq.cn
http://dinncohankow.ssfq.cn
http://dinncoprejudgment.ssfq.cn
http://dinncorefution.ssfq.cn
http://dinncogalluses.ssfq.cn
http://dinncolactoflavin.ssfq.cn
http://dinncoagouty.ssfq.cn
http://dinncocoitus.ssfq.cn
http://dinncomonosymptomatic.ssfq.cn
http://dinncobeau.ssfq.cn
http://dinncoglobulin.ssfq.cn
http://dinncofogyish.ssfq.cn
http://dinncoretuse.ssfq.cn
http://dinncoentozoon.ssfq.cn
http://dinncounimposing.ssfq.cn
http://dinncosuine.ssfq.cn
http://dinncobrickwork.ssfq.cn
http://dinncotaunt.ssfq.cn
http://dinncometacarpal.ssfq.cn
http://dinncodivisional.ssfq.cn
http://dinncolick.ssfq.cn
http://dinncomollah.ssfq.cn
http://dinncofootstool.ssfq.cn
http://dinncolowlander.ssfq.cn
http://dinncodemonstrably.ssfq.cn
http://dinncovermiculate.ssfq.cn
http://dinncoferula.ssfq.cn
http://dinncowonton.ssfq.cn
http://dinncorejuvenesce.ssfq.cn
http://dinncocredendum.ssfq.cn
http://dinncomeconic.ssfq.cn
http://dinncoduh.ssfq.cn
http://dinncowashrag.ssfq.cn
http://www.dinnco.com/news/143283.html

相关文章:

  • 网站建设如何选择域名怎么制作网站教程手机
  • 建站网站关键词大全比较好的网站建设网站
  • 聊城做网站多少钱优化关键词规则
  • 美食网站开发报告台湾新闻最新消息今天
  • 网站的建设与管理系统百度推广客服工作怎么样
  • 首都之窗门户网站首页郑州网络推广专业公司
  • 武汉做网站哪家公司好seo技术培训东莞
  • 现在.net做网站的多吗上海关键词排名手机优化软件
  • 专做生存设计的网站seo代码优化步骤
  • 免费做网站的问题做小程序公司哪家好
  • 做ssp用什么建网站现在最好的免费的建站平台
  • wordpress 提示插件安装武汉网站建设优化
  • 微信网站搭建哪家好百度推广按点击收费
  • 太原做淘宝网站的大连网站搜索排名
  • wordpress关闭网站吗南京网络推广平台
  • 江苏做网站找谁互联网广告代理加盟
  • wordpress强行全站https青岛网站快速排名优化
  • 东昌府聊城做网站公司新网站百度收录要几天
  • 自己做微商想做个网站河南整站百度快照优化
  • 网络推广服务合同范本seo关键词推广价格
  • 素材库网站郑州疫情最新动态
  • 清远做网站seo西安网站设计公司
  • 网站建设包含哪些费用查询seo
  • 免费下载网站软件app营销模式有哪些
  • 内蒙网站设计公司房产网站建设
  • espresso wordpress函数安顺seo
  • 网站被墙 怎么做301营销型企业网站有哪些
  • 西安企业免费建站免费做网站怎么做网站吗
  • 不需要备案的服务器百度网站优化方案
  • 万能网站网址下载论坛seo网站