1、功能需求
- 一个人可以follow很多人
- 一个用户如果发了新weibo会自动推送所有关注他的人
- 可以搜索、关注其它用户
- 可以分类关注
- 用户可以发weibo, 转发、收藏、@其它人
- 发微博时可选择公开、隐私、只能好友看等
- 可私信聊天
- 热门微博无需关注
- 我的微博列表
- 可以评论、点赞微博
- 发微博时可以上传图片、视频、可以发表情
2.1 设计架构前需要考虑的问题
- weibo目前的架构经历了多次演变才做到目前支持大并发的成熟产品, 我们在设计架构时要考虑以下问题
- 亿级用户数据的存储如何高效实现?
- 用户发一条微博,后台要进行入库、分发、推送等多个动作才能完成,如何让用户感觉发微博速度快?
- 用户发weibo要推送给关注他的人,如何提高推送效率?
- 如何降低不同产品、模块、服务之前的耦合,使产品、功能的水平扩展等?
- “Break large complex systems down into many services… google.com search touches 100s of service(ads, web search, books, news, spelling correction…”
- 如何做到去中心化,避免单点及瓶颈
- 如何实现接口安全
2.2 架构实现
所需服务组件:
- django: 用户页面呈现
- nginx: 前端高并发必备
- cdn:异地高并发、静态内容速度快必备
- redis: 热点weibo话题数据高效存储
- rabbitMQ: 用户weibo推送
- SOA:服务解耦,服务接口化
- zabbix,nagios: 系统监控
- google analysis: 用户访问质量、行为分析监控
用户发微博流程图
3.表结构设计
from django.db import models from django.contrib.auth.models import User # Create your models here. class Weibo(models.Model): '''所有微博''' wb_type_choices = ( (0,'new'), (1,'forward'), (2,'collect'), ) wb_type = models.IntegerField(choices=wb_type_choices,default=0) forward_or_collect_from = models.ForeignKey('self',related_name="forward_or_collects",blank=True,null=True) user = models.ForeignKey('UserProfile') text = models.CharField(max_length=140) pictures_link_id = models.CharField(max_length=128,blank=True,null=True) video_link_id = models.CharField(max_length=128,blank=True,null=True) perm_choice = ((0,'public'), (1,'private'), (2,'friends')) perm = models.IntegerField(choices=perm_choice,default=0) date = models.DateTimeField(auto_now_add=True) def __str__(self): return self.text class Topic(models.Model): '''话题''' name = models.CharField(max_length=140) date = models.DateTimeField() def __str__(self): return self.name class Category(models.Model): '''微博分类''' name = models.CharField(max_length=32) def __str__(self): return self.name class Comment(models.Model): '''评论''' to_weibo = models.ForeignKey(Weibo) p_comment = models.ForeignKey('self',related_name="child_comments") user = models.ForeignKey('UserProfile') comment_type_choices = ((0,'comment'),(1,'thumb_up')) comment_type = models.IntegerField(choices=comment_type_choices,default=0) comment = models.CharField(max_length=140) date = models.DateTimeField(auto_created=True) def __str__(self): return self.comment class Tags(models.Model): '''标签''' name = models.CharField(max_length=64) def __str__(self): return self.name class UserProfile(models.Model): '''用户信息''' user = models.OneToOneField(User) name = models.CharField(max_length=64) brief = models.CharField(max_length=140,blank=True,null=True) sex_type = ((1,'Male'),(0,'Female')) sex = models.IntegerField(choices=sex_type,default=1) age = models.PositiveSmallIntegerField(blank=True,null=True) email = models.EmailField() tags = models.ManyToManyField(Tags) head_img = models.ImageField() follow_list = models.ManyToManyField('self',blank=True,related_name="my_followers",symmetrical=False) #registration_date = models.DateTimeField(auto_created=True) def __str__(self): return self.name
4.上传图片本地预览功能
如下图,发微博时,可以同时发图片,图片我们肯定是通过ajax异步上传到后台,但是我只是从电脑里选择了图片后,我还想实现一个在本地小图预览的功能, 这个需求如何实现呢?
本地预览实现
function handleFileSelect(evt) { var files = evt.target.files; // Loop through the FileList and render image files as thumbnails. for (var i = 0, f; f = files[i]; i++) { // Only process image files. if (!f.type.match('image.*')) { continue; } var reader = new FileReader(); // Closure to capture the file information. reader.onload = (function(theFile) { return function(e) { // Render thumbnail. var span = document.createElement('span'); span.innerHTML = [ '<img style="height: 75px; border: 1px solid #000; margin: 5px" src="', e.target.result, '" title="', escape(theFile.name), '"/>' ].join(''); document.getElementById('list').insertBefore(span, null); }; })(f); // Read in the image file as a data URL. reader.readAsDataURL(f); } } document.getElementById('files').addEventListener('change', handleFileSelect, false);
<input type="file" id="files" multiple /> <output id="list"></output>
参考 http://stackoverflow.com/questions/14069421/show-an-image-preview-before-upload