注册
一般来说,注册模块并没有什么难点,但我在注册模块中写了两种验证码(普通验证码,短信验证码),普通验证码没有难度,但手机验证码需要在twilio网获取免费手机号,通过这个手机号给注册用户发短信验证码。
作用:
注册验证逻辑 短信+邮件+验证码 防止机器人重复注册




登录
我的登陆模块写了第三方登录,因为大多数网站都有第三方登陆,并且第三方登录可以省许多时间,比较方便。
关于三方登录的授权机制
在授权过程中大致有三个对象。一个是服务提供方(第三方网站)、一个是用户(将资源放在服务提供方存放的对象)、还有一个就是客户端(向服务提供放请求用户资源的对象)。首先,客户端向服务提供方发起请求,请求服务提供方的一个临时令牌,这个临时令牌是进行下一步的基础,服务提供方先要验证一下客户端的身份,验证成功后会给客户端所要的临时令牌。接下来客户端会引导用户进行授权操作,用户进入服务提供方提供的页面,完成授权以后服务提供方会给客户端一个访问令牌并调转回客户端的网页。通过访问令牌,客户端就可以获得用户在服务提供方上的若干权限

绑定逻辑:
判断user_social表中是否存在该openid的数据。
若存在,直接进行登录。
若不存在,将数据,存储到user_social 表,引导用户绑定本站账号。
若本站已存在账号,直接关联账号即可。
若本站不存在账号,引导用户注册,成功后与当前openid关联即可。



商品详情页


功能:
1.加入购物车
2,收藏
3。评论

加入购物车
需求分析:

购物车首先标识要唯一,因为每个账号要对应一个购物车,在登录状态下,我们可以直接将数据保存到数据库中,使用用户的id表示自己购买的商品,但是如果在未登录状态下呢,或者对购车访问量大的时候,这个就存在弊端,因为这样高速的读写数据库,会对数据库的压力比较大。
所以,我采用存入cookie和redis这两种数据库中。
方案一 :客户端 cookie 弊端:客户端不可控,可能禁用cookie。
方案二 : 服务端 redis 推荐使用。

redis:

利用redis key的唯一性来实现。并且采用分表的形式。
为什么分表?
随着公司业务增长,如果每天1000多万笔订单的话,3个月将有约10亿的订单量,之前数据库采用单表的形式已经不满足于业务需求,数据库改造迫在眉睫。

解决思路:

按月分表,将原订单表拆分为 order_201901 order_201902 由此类推

这样就可以缓解数据库压力 根据业务场景 可以细分按周,按日分表


购物车存到cookie
为什么不存session?

首先,session存在时间限制,会定期清空的,而cookie如果不主动清或者设置定期则不会清楚;

session存放在服务器端,cookie存放在客户端浏览器。

购物车存放的都是临时的物品,购买之后才产生真正的交易记录,所以这部分数据一般不会放到session中。session还有一个问题就是容易失效,默认20分钟左右会自动销毁。所以存放到cookie中是比较合理的选择。

Cookie方式:

优点:购物车信息存储在客户端,不占用服务器资源,基本可以到达持久化存储。
缺点:Cookie有大小的限制,不能超过4K,而且不够安全。如果是个人PC机,Cookie能很好的保存购物车信息,但如果是公共办公环境,Cookie保存的信息基本就失效了(会被其他人购物车信息覆盖)。对一个大型的电子商务网站,我们需要对用户的购买行为进行分析,需要对用户推荐用户感兴趣的商品,如果把购物车信息保存在Cookie中,则不能对用户购买行为分析统计。


为什么要用两种购物车?
防止其中一个购物车发生异常,两种购物车可以进行无缝切换。


收藏
为什么写收藏功能?
1,我对这一件商品感兴趣,但我不买。
2.我没钱,等着打折。
3,我喜欢这个风格的衣服,我还不确定我买那一件。
4.收藏功能由于没有任何的限制及使用成本。我们经常会把看到的喜欢的、想特意关注的、等以后有钱再买的等各种产品放置收藏夹,等待下一次时机成熟时进行购买。

所以,收藏功能诞生了。



评论:

评价这个功能是非常重要的一个功能,他有利于顾客更好的了解这个商品的优缺点,并且可以让商家及时看到这个商品需要在那个地方进行改正。

评论存在的目的:

1.将用户在购买后对商品、服务、物流等相关信息的真实感官表现出来,为其他用户提供购买决策,减少购物成本。

2.对于平台来说提高复购率;构建商家信用评价体系,帮助商家分层,合理分配平台资源。

3.对于想买的顾客来说,有购买意愿的买家需要了解商品的真是情况,获得高质量的评价帮助自己购物决策,是评价产品的高频使用者,此类买家由于厌倦海量的评价、对真实评价有迫切的需求,往往会更加注重评价的筛选,有图评价和追加评价更容易被关注。

4.对于以及购买的客户来说,已经购买的买家可以分为两类,一类是对商品、服务、物流有超预期的体验或者发表不满的情绪,这类买家的评价重要性权值要高很多,要让这类买家在产品使用过程中尽可能多的机会来发表建议(包括评价问答);另一类就是商品和预期差不多的买家,这部分买家占据大多数,通常不会将自己的感受表现出来,这时需要平台介入提高评价率,简化评价流程,降低成本。

5.评价对卖家来说一种特别好的收集用户反馈流程,通过评价可以帮助优化购物体验、商品品质。但卖家反而是评价系统的风险用户,由于评价会直接影响客流转化,所以卖家会更有意愿去破坏评价初衷和规则。

逻辑:

(1)单篇文章的评论数量和信息展示;

(2)从时间维度,按照时间倒叙的方式展示动态的用户评论信息;

(3)不同栏目,不同模块,不同时间维度的评论排行展示;

(4)精华评论的单独推荐和聚合展示;

(5)评论后直接分享到绑定的第三方平台;

(6)点赞数、回复数等维度的排行等。

在评价的时候,其他顾客也可以进行提问或者发表其他意见。


数据表设计:
一问一答模式
(1)需求分析

大部分APP采用简单的评论设计即可,即是一问一答模式,比如微信朋友圈的评论功能的设计。如:

A:今天天气真好!
B @ A :今天天气确实不错!
1
2
这种设计简单、直接,也满足了用户评论、回复的基本要求,对于没有大量用户评论的APP需求足够。

(2)数据库设计
这种场景下一般评论较少,评论不活跃,可以不区分评论和回复,统一看成评论。区别是,有些评论是直接评论主题,而有些是@其他用户,使用一张表就可以达到效果,评论表设计如下:

表字段 字段说明
id  主键
topic_id    主题id
topic_type  主题类型
content 评论内容
from_uid    评论用户id
to_uid  评论目标用户id
topic_type:为了能复用评论模块,我们引入这个字段来区分主题的类别。

from_uid:表示评论人的id,通过该id我们可以检索到评论人的相关信息。

to_uid 是评论目标人的id,如果没有目标人,则该字段为空

出于性能的考虑,往往我们会冗余评人的相关信息到评论表中,比如评论人的nick、头像,目标用户也是如此。 这样一来我们就只用查询单表就可以达到显示的效果

有时,目标用户有多个,那么可以将to_uid字段修改为to_uids,保存时用分隔符来分割用户id,而目标用户的信息再去查询缓存或者数据库。也可以简单的将多个目标用户的信息一起存成json格式,可以应付简单的展现需求。

2.2 评论为主模式
(1)需求分析
论分为评论和回复,所有评论均挂在评论下面,类似于树状结构。

(2)数据库设计
在以评论为主的树形显示情况下,数据库的设计十分灵活,可以使用单表,添加一个parent_id字段来指向父评论,需要嵌套查询。

同时也可以将评论拆分为评论表和回复表,评论挂在各种主题下面,而回复挂在评论下面。

评论表设计如下:

表字段 字段说明
id  主键
topic_id    主题id
topic_type  主题类型
content 评论内容
from_uid    评论用户id
回复表设计:

表字段 字段说明
id  主键
comment_id  评论id
reply_id    回复目标id
reply_type  回复类型
content 回复内容
from_uid    回复用户id
to_uid  目标用户id
由于我们拆分了评论和回复,那么评论表就不再需要目标用户字段了,因为评论均是用户对主题的评论,评论表的设计更佳简洁了。

回复表添加了一个comment_id字段来表示该回复挂在的根评论id,这样设计也是出于性能方面的考虑,我们可以直接通过评论id一次性的找出该评论下的所有回复,然后通过程序来编排回复的显示结构。 通过适当的冗余来提高性能也是常用的优化手段之一。

reply_type:表示回复的类型,因为回复可以是针对评论的回复(comment),也可以是针对回复的回复(reply), 通过这个字段来区分两种情景。

reply_id:表示回复目标的id,如果reply_type是comment的话,那么reply_id=commit_id,如果reply_type是reply的话,这表示这条回复的父回复。

2.3 网易新闻盖楼模式
(1)需求分析

这种场景中评论和回复是同级显示的,回复不在显示结构上不用挂在一个评论下面。 双表的设计在这里就不太合适了,因为涉及到评论和回复的混排,使用双表则会导致查询的逻辑过于复杂。 所以建议还是采用单表的设计,不区分评论和回复会简化应用层的逻辑。 我们统一都看成评论,而有些评论是可以引用其他评论的。


秒杀功能

双十一刚过不久,大家都知道在天猫、京东、苏宁等等电商网站上有很多秒杀活动,例如在某一个时刻抢购一个原价1999现在秒杀价只要999的手机时,会迎来一个用户请求的高峰期,可能会有几十万几百万的并发量,来抢这个手机,在高并发的情形下会对数据库服务器或者是文件服务器应用服务器造成巨大的压力,严重时说不定就宕机了,另一个问题是,秒杀的东西都是有量的,例如一款手机只有10台的量秒杀,那么,在高并发的情况下,成千上万条数据更新数据库(例如10台的量被人抢一台就会在数据集某些记录下 减1),那次这个时候的先后顺序是很乱的,很容易出现10台的量,抢到的人就不止10个这种严重的问题。那么,以后所说的问题我们该如何去解决呢? 接下来我所分享的技术就可以拿来处理以上的问题: 分布式锁

在购物平台中,秒杀通过对一些商品经过折扣优惠来吸引一些客户流量。

秒杀功能的逻辑:

1 请求量大,请求高并发; 2 用户瞬间活跃量高,要求系统响应快;
3 秒杀商品少,只有少数用户能够买到。

4.秒杀频道首页列出秒杀商品(进行中的)点击秒杀商品图片跳转到秒杀商品详细页。
5.商品详细页显示秒杀商品信息,点击立即抢购实现秒杀下单,下单时扣减库存。当库存为 0 或不在活动期范围内时无法秒杀。
6.秒杀下单成功,直接跳转到支付页面(支付宝),支付成功,跳转到成功页,填写收货地址、电话、收件人等信息,完成订单。

7.当用户秒杀下单 5 分钟内未支付,取消预订单,调用支付宝支付的关闭订单接口,恢复库存。
利用redis的setnx锁来实现不能超卖
利用 apache bench 进行压力测试

服务器负载太大而影响程序效率也是很常见的,Apache服务器自带有一个叫AB(ApacheBench)的工具,可以对服务器进行负载测试
同时美多商城的秒杀功能也会被高负载影响,从而导致超卖现象
基本用法:

ab -n 全部请求数 -c 并发数测试url

注:可以将ab.exe 加入系统环境变量;或直接切换置 ab 目录执行。如: C:\Windows\System32> cd C:\xampp\apache\bin
引申出redis缓存和mysql数据库数据同步问题

解决方案 redis设置超时时间,一旦超时,数据就会同步



 








我的订单:

我实在购物车中点击结算后添加到我的订单中,并进行购买。
我为什么要加入订单而不是立即购买,因为我在购物车中点击结算后添加到我的订单时,会生成订单号,通过这个生成的订单号进行购买。

第三方支付:
我使用的是支付包支付。

神魔是第三方支付:

第三方支付是指具有一定实力和信誉保障的第三方独立机构。通过与各大银行签订合同,建立连接用户和银行支付结算系统的平台,从而实现电子支付模式。从另一个角度来看,第三方支付就是非金融机构提供的网络支付、预售卡发行与受理、银行卡收单等零售支付服务。

作为一种创新的支付方式,第三方支付极大地方便了人们的生活。但与此同时,第三方支付机构由于自身的运营机制,容易出现支付欺诈、信息泄露、信用违约等问题,这引起了公众和相关监管机构的关注。


第三方支付的优势:

第三方支付作为当代支付方式发展的核心驱动力,具有以下优点。

一是扮演信用中介的角色。第三方支付大大改善了商品交易中买卖双方信息不对称造成的犹豫销售或购买的问题,促进了商品经济的数量和质量,同时保证了双方的财产安全。

二是扩展支付。它允许消费者随时随地购物、生活缴费,如支付水费、电话费甚至会员费,结束了过往使用手机卡、游戏卡和其他充值卡的时代。

三是加快建立全民信用信息系统。同时,信用评分已成功应用于消费者的日常生活。以太原市图书馆为例。只要读者的芝麻信用达到600分或以上,您就可以申请图书馆借阅卡而无需押金,可以借4本书。此外,支付宝依靠天猫商城推出“信用尝鲜”服务,这意味着信用合格的客户可以先享受试用天猫服饰,先享后付天猫电子产品等权益,为信用信息系统的发展注入强大的力量。

 
第三方支付通俗来讲就是微信支付,支付宝支付,财付通等;
 
第三方支付的逻辑:
1.使用沙箱提供的商家环境
2.生成密钥对
3.将公钥加到商品环境中
4.将Alipay提供的公钥加入项目中
5.支付功能
6.根据order_id查询订单对象
7.创建alipay对象
8.调用方法,生成url
9.返回url
10.保存支付状态
11.根据返回的url请求支付宝
12.支付成功后返回商家回调页面--------->会传回很多Alipay传回来的参数,很多明文,防止别人攻击
13.返回商家的同时请求后台服务器------>发送这些参数给后台
14.接收参数并且验证,成功则创建订单支付对象返回订单号,否则提示支付失败


配置秘钥
1.注册成为蚂蚁金服开放平台用户 https://openhome.alipay.com

2.点击登陆,二维码登陆或者密码登陆.

3.登陆成功后,点击开发中心里面的研发服务。

4。进入研发服务后在沙箱应用中,点级设置应用密钥(在网上查找RSA签名验签工具windows_V1.4)中复制 RSA签名验签工具.bat 生成密钥 密钥格式选择非java适用 长度选2048(私钥比公钥安全,因为私钥相当于一把只有你自己有的钥匙,防止密码泄露等)



 

5。复制公钥到SA2(SHA256)密钥(推荐)中的查看应用公钥。并保存

6.设置成功后点击查看应用公钥或者支付公钥,是否设置成功。

7.在公钥.text中,需要把text中的自己生成的公钥修改成https://openhome.alipay.com/platform/appDaily.htm?tab=info页面中RSA(SHA1)密钥的查看支付宝公钥。

 

浏览历史(我的足迹)

一般看浏览历史是因为我在没有加入购物车或者收藏时,我很想买那一件商品,所以看浏览历史。

对于商城项目中的历史浏览记录我们将它储存在redis缓存中,便于存储和拿取数据,
而我们首先要明确历史记录什么时候添加,什么时候获取。
添加  访问商品详情页面的时候,需要添加历史浏览记录
获取  访问用户中心个人信息页的时候,需要获取历史记录



便于用户查看浏览的页面。


消息推送:
python websocket Django 实时消息推送
概述:
WebSocket 是什么?
WebSocket 是 HTML5 提供的一种浏览器与服务器间进行全双工通讯的协议。依靠这种协议可以实现客户端和服务器端 ,一次握手,双向实时通信。

WebSocket是一种在单个TCP连接上进行全双工通信的协议
WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输
现在,很多网站为了实现推送技术,所用的技术都是轮询。轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP请求,然后由服务器返回最新的数据给客户端的浏览器。这种传统的模式带来很明显的缺点,即浏览器需要不断的向服务器发出请求,然而HTTP请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,显然这样会浪费很多的带宽等资源。
而比较新的技术去做轮询的效果是Comet。这种技术虽然可以双向通信,但依然需要反复发出请求。而且在Comet中,普遍采用的长链接,也会消耗服务器资源。
在这种情况下,HTML5定义了WebSocket协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯


1. http协议是用在应用层的协议,他是基于tcp协议的,http协议建立链接也必须要有三次握手才能发送信息。
  http链接分为短链接,长链接,短链接是每次请求都要三次握手才能发送自己的信息。即每一个request对应一个response。长链接是在一定的期限内保持链接。保持TCP连接不断开。客户端与服务器通信,必须要有客户端发起然后服务器返回结果。客户端是主动的,服务器是被动的。
2. WebSocket 
  WebSocket他是为了解决客户端发起多个http请求到服务器资源浏览器必须要经过长时间的轮训问题而生的,他实现了多路复用,他是全双工通信。在webSocket协议下客服端和浏览器可以同时发送信息。
建立了WenSocket之后服务器不必在浏览器发送request请求之后才能发送信息到浏览器。这时的服务器已有主动权想什么时候发就可以发送信息到服务器。而且信息当中不必在带有head的部分信息了与http的长链接通信来说,这种方式,不仅能降低服务器的压力。而且信息当中也减少了部分多余的信息。

WebSocket 服务端:
用的是 dwebsocket,安装命令pip install dwebsocket.

这是客户端的一些说明,在客户端,websocket的两个属性:readyState和bufferedAmount,区别和说明如下:

根据readyState属性可以判断webSocket的连接状态,该属性的值可以是下面几种:
0 :对应常量CONNECTING (numeric value 0),
正在建立连接连接,还没有完成。The connection has not yet been established.
1 :对应常量OPEN (numeric value 1),
连接成功建立,可以进行通信。The WebSocket connection is established and communication is possible.
2 :对应常量CLOSING (numeric value 2)
连接正在进行关闭握手,即将关闭。The connection is going through the closing handshake.
3 : 对应常量CLOSED (numeric value 3)
连接已经关闭或者根本没有建立。The connection has been closed or could not be opened.

根据bufferedAmount可以知道有多少字节的数据等待发送,若websocket已经调用了close方法则该属性将一直增长。

WebSocket 和HTTP的区别:
HTTP:每发一次广告,就请求一次。
webSocket: 请求一次,可以多次发送。




项目部署:

我的项目是部署到docker(容器)上面。

Docker 简介

Docker 是一个开源项目,诞生于 2013 年初,最初是 dotCloud 公司内部的一个业余项目。它基于 Google 公司推出的 Go 语言实现。 项目后来加入了 Linux 基金会,遵从了 Apache 2.0 协议,项目代码在 GitHub 上进行维护。
Docker 自开源后受到广泛的关注和讨论,以至于 dotCloud 公司后来都改名为 Docker Inc。Redhat 已经在其 RHEL6.5 中集中支持 Docker;Google 也在其 PaaS 产品中广泛应用。
Docker 项目的目标是实现轻量级的操作系统虚拟化解决方案。 Docker 的基础是 Linux 容器(LXC)等技术。在 LXC 的基础上 Docker 进行了进一步的封装,让用户不需要去关心容器的管理,使得操作更为简便。用户操作 Docker 的容器就像操作一个快速轻量级的虚拟机一样简单。

为什么用docker?

作为一种新兴的虚拟化方式,Docker 跟传统的虚拟化方式相比具有众多的优势。
Docker 在如下几个方面具有较大的优势:
更快速的交付和部署
Docker在整个开发周期都可以完美的辅助你实现快速交付。Docker允许开发者在装有应用和服务本地容器做开发。可以直接集成到可持续开发流程中。
例如:开发者可以使用一个标准的镜像来构建一套开发容器,开发完成之后,运维人员可以直接使用这个容器来部署代码。 Docker 可以快速创建容器,快速迭代应用程序,并让整个过程全程可见,使团队中的其他成员更容易理解应用程序是如何创建和工作的。 Docker 容器很轻很快!容器的启动时间是秒级的,大量地节约开发、测试、部署的时间。
高效的部署和扩容
Docker 容器几乎可以在任意的平台上运行,包括物理机、虚拟机、公有云、私有云、个人电脑、服务器等。 这种兼容性可以让用户把一个应用程序从一个平台直接迁移到另外一个。
Docker的兼容性和轻量特性可以很轻松的实现负载的动态管理。你可以快速扩容或方便的下线的你的应用和服务,这种速度趋近实时。
更高的资源利用率
Docker 对系统资源的利用率很高,一台主机上可以同时运行数千个 Docker 容器。容器除了运行其中应用外,基本不消耗额外的系统资源,使得应用的性能很高,同时系统的开销尽量小。传统虚拟机方式运行 10 个不同的应用就要起 10 个虚拟机,而Docker 只需要启动 10 个隔离的应用即可。
更简单的管理
使用 Docker,只需要小小的修改,就可以替代以往大量的更新工作。所有的修改都以增量的方式被分发和更新,从而实现自动化并且高效的管理。


虚拟机(VM(VMware))与docker的区别 :
VM(VMware)在宿主机器、宿主机器操作系统的基础上创建虚拟层、虚拟化的操作系统、虚拟化的仓库,然后再安装应用;
Docker容器,在宿主机器、宿主机器操作系统上创建Docker引擎,在引擎的基础上再安装应用。

docker设计小巧,部署迁移快速,运行高效,应用之间相互独立,管理人员可以看到所有容器的内容,虚拟化技术比较臃肿,不论什么应用都需要先创建新的系统,并且并非按照应用隔离,而是按照系统隔离,管理员无法看到系统内部信息 举个例子,Docker就是手机中的各种APP,只需要一个系统就可以下载自己所需的应用,但是虚拟化技术相当于你的苹果手机安装一个庞大软件,这个软件上安装安卓系统、魅族系统等,每个系统上还要安装各类应用,比较麻烦。 但两者没有绝对的好坏,主要还是看应用场景,根据不同的需求选择不同的解决方案即可。