`
xpenxpen
  • 浏览: 731439 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

用spring-data-redis实现类似twitter的网站

阅读更多
1. spring-data-redis简介
封装了一下redis的客户端,使得使用起来更方便。
优点是把客户端连接放到一个连接池里,从而提高性能。还有就是可以不同的客户端之间实现切换,而不用改一行代码(Spring惯用的一个手法)。
本文写作时最新版是1.3,
目前支持下面4种java客户端,可以自由切换而不用改代码。


2. twitter简介
twitter如果没用过的话,可以理解成类似于国内的新浪微博。因为微博的访问量和使用人数极大,用传统的关系型数据库支撑不了,所以有了用redis这种非关系型数据库的架构设计。
本文我们将用spring-data-redis来实现一个类似twitter的网站。

3. 环境
本人亲测通过环境
jdk 1.6.0_45 64bit
gradle 1.7
tomcat 7.0.35
redis 2.8.11 win64
jedis 2.5.1
spring 3.2.9
spring-data-redis 1.3.0

4. 先动手操作
4.1 首先git clone以下项目
https://github.com/spring-projects/spring-data-keyvalue-examples/tree/master/retwisj

4.2 本人做了一些修改,一些3pp改成本文写作时最新的版本
build.gradle
compile "redis.clients:jedis:2.5.1"


gradle.properties
springVersion = 3.2.9.RELEASE
springRedisVersion = 1.3.0.RELEASE


4.3 编译
gradle build


4.4 将retwisj.war放入tomcat的webapp目录下,启动tomcat

4.5 访问http://localhost:8080/retwisj
花几分钟上去玩一下,熟悉一下功能。
好了,我们已经做好了一个微博网站了。玩好了我们简单分析一下代码实现。

5. 实现分析

5.1 表结构设计

5.1.1 用户(User)

用以前的关系型数据库设计是这样的
KeyUsernamePassword
1springrodinterface21
2costinlthis is fun


而用redis的则变成了这样
KeyTypeValue
uid:1hash{name: springrod, pass: interface21}
uid:2hash{name: costinl, pass: secret}


将用户的名字和密码作为一个hash存入
对应的redis原生命令是
HMSET user:1 name springrod pass interface21


uid是自增长的,可以用redis的INCR来实现,这是一个原子操作
INCR global:uid


KeyTypeValue
global:uidstring2


我们要保存username和uid的对应关系,比如一个user登录时,我们要得到他的uid。可以创建一个倒转的key来实现此功能。user:[name]:uid
还创建了一个users用来保存所有uid的list
KeyTypeValue
user:springrod:uidstring1
user:costinl:uidstring2
userslist{1, 2}


5.1.2 微博(Post)

同样的,用global:pid来记录自增长的post id
KeyTypeValue
global:pidstring2


将微博的内容、时间和作者作为一个hash存入
KeyTypeValue
pid:1hash{content: Hello World, time: 1301931414757, uid: 1}
pid:2hash{content: Working on some cool stuff, time: 1301931414897, uid: 1}
pid:3hash{content: Checking out RetwisJ, time: 1301931454897, uid: 2}


某个用户的所有微博
KeyTypeValue
uid:1:postslist{1, 2}
uid:2:postslist{3}


所有微博列表(Timeline)
KeyTypeValue
timelinelist{1, 2, 3}


5.1.3 关系(粉丝(Follower),关注(Following))

比如user2关注了user1,则user2是user1的粉丝,
user3也关注了user1,
则user1被user2,user3所关注

KeyTypeValue
uid:1:followersset{2,3}
uid:2:followingset{1}
uid:3:followingset{1}


新浪微博上姚晨的粉丝有7000万,光记录她一个人的粉丝就要7000万条记录。
如果用传统的关系型数据库实现,压力很大。

5.2 安全验证
我们不用session来跟踪用户,而用cookie。
每当用户登录后,为他生成一个随机数(令牌),发给该用户,让他作为cookie保存,这个cookie用来验证用户的身份。
同样的存储一个倒转的key,可以根据cookie来得到uid

KeyTypeValue
uid:2:authstring{fea5e81ac8ca77622bed1c2132a021f9}
auth:fea5e81ac8ca77622bed1c2132a021f9string{2}


5.3 包的结构
org.springframework.data.redis.sample.retwisj.webweb层
org.springframework.data.redis.sample.retwisj.redis持久层
org.springframework.data.redis.sample.retwisj领域层


5.4 使用redisTemplate
applicationContext-redis.xml
<beans>
  <context:property-placeholder location="classpath:redis.properties"/>

  <!-- Redis client 这里就是不改代码实现不同客户端切换的地方了,我们用jedis-->
  <bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
    p:host-name="${redis.host}" p:port="${redis.port}" p:password="${redis.pass}"/>

    <bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate" 
        p:connection-factory-ref="connectionFactory"/>

    <context:annotation-config />
    <context:component-scan base-package="org.springframework.data.redis.samples"/>

</beans>


5.5 web层
采用spring MVC和JSP

5.5.1 Controller层
RetwisController

5.5.2 CookieInterceptor
对于用户验证,采用cookie的方式,写了一个Spring MVC的拦截器
public class CookieInterceptor extends HandlerInterceptorAdapter


并在retwisj-servlet.xml里配置
<mvc:interceptors>
    <bean class="org.springframework.data.redis.samples.retwisj.web.CookieInterceptor" />
</mvc:interceptors>

执行效果就是在客户端保存了一个叫"retwisauth"的cookie,保存了用户的令牌。

5.5.3 i18

CookieLocaleResolver把语言作为cookie存在客户端
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver"/>


执行效果就是在客户端保存了一个叫"org.springframework.web.servlet.i18n.CookieLocaleResolver.LOCALE"的cookie,保存了语言。

LocaleChangeInterceptor可以用来变更语言
<mvc:interceptors>
    <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" p:paramName="lang"/>
</mvc:interceptors>


这样就可以通过http://localhost:8080/retwisj/?lang=cn来变更语言

5.6 持久层
RetwisRepository

如下代码示例了如何用intersect来找出2个用户相同的粉丝

private RedisSet<String> following(String uid) {
    return new DefaultRedisSet<String>(KeyUtils.following(uid), template);
}

public List<String> commonFollowers(String uid, String targetUid) {
    RedisSet<String> tempSet = following(uid).intersectAndStore(following(targetUid),
    KeyUtils.commonFollowers(uid, targetUid));

    tempSet.expire(5, TimeUnit.SECONDS);

    return covertUidsToNames(tempSet.getKey());
}


如下代码示例了用RedisAtomicLong实现自增长的id,BoundHashOperations来存储用户的用户名和密码

public String addUser(String name, String password) {
    String uid = String.valueOf(userIdCounter.incrementAndGet());

    // save user as hash
    // uid -> user
    BoundHashOperations<String, String, String> userOps = template.boundHashOps(KeyUtils.uid(uid));
    userOps.put("name", name);
    userOps.put("pass", password);
    valueOps.set(KeyUtils.user(name), uid);

    users.addFirst(name);
    return addAuth(name);
}

分享到:
评论

相关推荐

    springboot学习思维笔记.xmind

    spring-boot-starter-redis spring-boot-starter-security spring-boot-starter-social-facebook spring-boot-starter-social-linkedin spring-boot-starter-social-twitter spring-...

    spring+mybatis+redis+bootstrap 简单框架

    Spring框架提供了对Redis的支持,通过Spring Data Redis模块可以轻松地进行集成。 **Bootstrap**是Twitter开源的一个前端开发框架,它提供了丰富的预定义样式、组件和JavaScript插件,帮助开发者快速创建响应式和...

    spring官方资料集合

    Spring Data Redis是Spring Data项目的一部分,它提供了对Redis内存数据存储的集成。文档中会详细讲解如何配置、操作Redis数据结构,以及利用Spring Data的便捷API进行持久化操作。 5. **spring-data-jpa-...

    spring clond

    - **与 Spring Cloud Config 的配合**:可以与 Spring Cloud Config 配合使用,实现配置的热更新。 #### 3. Spring Cloud Netflix - **简介**:提供了一系列基于 Netflix OSS 组件的工具包,这些组件广泛应用于...

    基于Spring Boot和Spring Cloud实现微服务架构学习(一).docx

    Spring Data简化了对各种数据存储的访问,包括关系型数据库(如JDBC)和NoSQL数据库(如MongoDB、Redis)。Spring Batch则提供了批量处理任务的框架,包括任务调度和日志跟踪。 Spring Security提供了声明式的安全...

    java品优购项目实战视频教程

    7.使用SpringDataRedis框架操作Redis、 8.使用Spring Data Solr框架操作solr 9.Solr新增动态域(Dynamic)知识点 10.掌握SPU和SKU的概念 11.搭建SpringBoot框架 12.实现阿里大于短信发送功能 13.使用CAS实现单点登录...

    基于Spring Boot和Spring Cloud实现微服务架构学习(一).pdf

    Spring Data则进一步简化了数据访问,支持多种数据库类型,包括关系型数据库如JDBC,以及NoSQL数据库如MongoDB和Redis。Spring Batch是一个强大的批处理框架,适用于大规模数据处理任务。 Spring Security是安全...

    基于SpringBoot和SpringCloud实现微服务架构学习(一).pdf

    Spring Data是一个强大的数据访问框架,支持多种数据存储,如关系型数据库JDBC、NoSQL数据库Redis、MongoDB等。Spring Batch则是一个批处理框架,用于大规模数据处理任务,包括调度、日志记录等功能。 Spring ...

    基于SpringBoot和SpringCloud实现微服务架构学习(一).docx

    Spring Data简化了数据访问,支持多种数据库和NoSQL存储,如JDBC、Redis、MongoDB等。Spring Batch则专为批量处理任务设计,提供了调度、跟踪等功能。Spring Security则提供了安全框架,用于声明式地管理应用的安全...

    基于Springboot+Thymeleaf实现的旅游景点酒店的预订网站+源代码+文档说明+数据库

    后台:SpringBoot、SpringDataJpa等 4.架构模式:半前后分离架构模式 5.模板引擎:thymeleaf 6.项目管理:Maven 7、JDK版本:1.8 8、额外功能:阿里云短信服务SMS、阿里云图片存储OSS、QQ邮箱验证服务 9、主要算法:...

    Java微服务

    Spring Data简化了对各种数据存储(如关系数据库、NoSQL数据库)的访问,包括JDBC、Redis、MongoDB等。Spring Batch是处理批量任务的框架,支持任务调度和日志记录。Spring Security提供了安全访问控制,用于保护...

    基于SpringBoot和SpringCloud实现微服务架构学习

    Spring Data是一个广泛的数据访问框架,支持多种数据库和NoSQL存储,如JDBC、Redis、MongoDB等。Spring Batch是批处理任务的框架,适用于大规模数据处理场景。 Spring Security提供了一套全面的安全访问控制解决...

    最新整理Java面试题

    - **Spring Boot**:快速开发特性,如自动配置、Actuator监控、Spring Data JPA等。 - **Spring Cloud**:服务治理、配置中心、熔断机制等,如Eureka、Config、Hystrix等组件的运用。 5. **分布式**: - **CAP...

    详解如何使用MongoDB+Springboot实现分布式ID的方法

    在实现分布式ID时,通常有几种方案:使用数据库自增ID、使用Redis的incr命令、使用UUID、Twitter的snowflake算法、利用Zookeeper生成唯一ID、MongoDB的ObjectId等。每种方案都有其优缺,需要根据实际情况选择合适的...

    个人毕设项目-基于Springboot+Thymeleaf旅游景点酒店预订源码含sql数据库.zip

    基础能力强的可以在此基础上修改调整,以实现类似其他功能。 ## 旅游网是一个基于SpringBoot框架设计的一个毕业设计,主要类似于一个电商系统 ## 主要功能介绍 有用户登录注册,景点列表,相册墙,购买景点,评论,...

    基于SpringBoot+MySQL的旅游网站设计与实现.zip

    3.后台:SpringBoot、SpringDataJpa 等 4.架构模式:半前后分离架构模式 5.模板引擎:thymeleaf 6.项目管理:Maven 7、JDK 版本:1.8 8、额外功能:阿里云短信服务 SMS、阿里云图片存储 OSS、QQ 邮箱验证服务 9、...

    基于Springboot+Thymeleaf旅游景点酒店预订网站设计

    3.后台:SpringBoot、SpringDataJpa等 4.架构模式:半前后分离架构模式 5.模板引擎:thymeleaf 6.项目管理:Maven 7、JDK版本:1.8 8、额外功能:阿里云短信服务SMS、阿里云图片存储OSS、QQ邮箱验证服务 9、主要算法...

    基于Springboot+Thymeleaf旅游景点酒店预订网站

    3.后台:SpringBoot、SpringDataJpa等 4.架构模式:半前后分离架构模式 5.模板引擎:thymeleaf 6.项目管理:Maven 7、JDK版本:1.8 8、额外功能:阿里云短信服务SMS、阿里云图片存储OSS、QQ邮箱验证服务 9、主要算法...

    java开源包3

    WebSocket4J 是一个用 Java 实现的 WebSocket 协议的类库,可使用 Java 来构建交互式 Web 应用。WebSocket4J 并未实现客户端通讯协议,所以不能用它来连接 WebSocket 服务器。 Struts验证码插件 JCaptcha4Struts2 ...

    java开源包4

    WebSocket4J 是一个用 Java 实现的 WebSocket 协议的类库,可使用 Java 来构建交互式 Web 应用。WebSocket4J 并未实现客户端通讯协议,所以不能用它来连接 WebSocket 服务器。 Struts验证码插件 JCaptcha4Struts2 ...

Global site tag (gtag.js) - Google Analytics