网上商城是一个综合性的B2B2C平台,类似京东商城。商家可以申请入驻到平台进行商品的销售,会员可以在商城浏览商品、搜索商品、使用购物车、购买商品下订单,以及参加秒杀团购等各种活动。网站前台共分为门户、搜索、商品详情页、购物车、秒杀、用户中心、单点登陆系统等7个模块。
系统有两个管理后台:商家管理后台和运营商管理后台。 商家申请入驻后,即可获得商家管理后台的使用权限,在商家管理后台可以提交商品信息、品牌申请、规格申请等。商家提交的商品信息必须经过管理员在运营商管理后台进行审核方可正式销售 。管理员、运营人员可以在运营商后台管理系统中审核商家入驻申请、审核商品提交申请、管理订单、会员、商家结算、统计分析等,客服可以在运营商后台管理系统中处理用户的询问以及投诉。
网上商城采用当前最流行的SSM(springmvc+spring+mybatis)框架开发,是当前电商网站首选的技术架构。系统是基于SOA架构设计,采用当当的dubbox作为服务中间件,前端采用angularJS + Bootstrap,操作简便用户体验好。商品详细页使用freemarker做静态化页面来提高系统的性能,使用nginx做负载均衡服务器以应对大规模的用户量的并发。电商搜索系统采用当前最流行的全文检索技术solr集群实现。系统中使用redis集群做缓存,使用Activemq做消息中间件。后台数据库使用mysql数据库,使用mycat做读写分离。
Dubbox是一个分布式服务框架,提供了统一的高性能的远程服务调用平台。所有的业务逻辑都使用dubbox发布供表现层工程调用。发布dubbox服务需要使用spring容器的支持来发布服务,调用服务同样使用spring容器来应用服务。其中服务的发布和服务的发现都是通过注册中心来实现,我们使用zookeeper作为注册中心。
互联网项目追求的是高性能,尤其是数据库查询的时候,在并发量高的情况下需要对sql语句进行调优。Mybatis就是面向sql语句的,所以操作起来笔记容易入手。所以一般互联网项目中大多采用mybatis作为持久层框架。
在电商项目中需要保存大量的图片,需要一个独立的图片服务器来保存,而且存储的容量需要可扩展。并且还需要解决在高并发及高可用的问题。所以我们采用一个FastDFS一个分布式文件系统来保存图片。FastDFS可以搭建服务器集群,解决了存储空间的水平扩展、负载均衡以及服务器的高可用问题。
经过我们对系统的调优,保证压力测试时每个tomcat的并发量达到400。现在我们有5台web服务器提供服务,基本上也就是2000左右的并发,如果将来并发量进一步提高是可以再增加服务器来提供并发能力。
解决高并发问题首先要提高本系统的吞吐能力,例如在系统中添加缓存、实现网页静态化等方式。如果在系统优化之后还不能满足业务的需要就需要增加服务器,做服务器集群。前端使用nginx做负载均衡服务器,并实现nginx的高可用。目前可以满足当前的业务需要,如果将来业务量增加的话可以考虑添加服务器及F5硬负载等设备。
我们做过seo处理,也就是配合seo人员做一些工作。在页面中添加一个关键词、做网页的伪静态化或者是纯静态化等处理。还有就是在页面的关键词中中添加一些链接等。
创建一个独立的工程,此功能的功能就是生成静态化页面的,例如商品详情页面静态化。将此工程独立部署到一个服务上,页面就生成到当前服务的磁盘上,并且此工程监听MQ的消息,一旦后台工程添加商品,此工程将接收到消息并且生成静态页面。在此服务器上安装一个nginx做为访问静态资源的http服务器。
Redis提供的存储形式比较丰富。为了便于对缓存数据进行管理,我们多数是采用hash(键值对)格式来存储的。
在商城系统中当并发量比较高,频繁的对数据库进行读操作的时候都需要添加缓存。例如页面中广告数据、搜索面板数据、购物车等。
做数据的缓存时,因为数据量很大,而且缓存是把数据保存到内存中,此时不可能把所有的数据都放到缓存中。所以需要设置数据缓存的有效期,当用户访问到非热点数据后,此数据放到缓存中,当缓存到期后就从缓存中删除,而且长时间不会添加到缓存。而热点数据一旦从缓存中删除会马上又添加到缓存。这样可以提高缓存的利用率,同时也减轻了数据库的压力。
只要使用了缓存就涉及到缓存同步的问题。缓存同步其实就是当缓存的信息发生变化,也就是对后台对缓存的数据进行增、删、改操作后,数据库中的数据发生了变化同时要把缓存中的数据对应删除即可。当页面再次请求数据时,缓存中不能命中就会从数据库中查询并且添加到缓存中,即实现了缓存同步。
Redis是nosql数据库,但是redis是key-value形式的nosql数据库,数据是存储到内存中的,适合于快速存取一般作为缓存使用。所以不适合于大数据的存储。并且redis是单线程的如果某个操作进行大数据的存储的话其他的进程都处于等待状态,这样就降低了性能。所以在redis中不适合于大数据的存储。如果是类似商品评论这样的价值不高的大批量数据,我们的做法是采用mongodb。
电商搜索一般也是使用全文检索实现,我们使用的是solr作为全文检索服务器,实现搜索功能。我们在solr中配置跟业务相关的业务域,从数据库中把相关的数据导入到索引库中。例如商品搜索功能就把商品表中的数据导入到索引库中。然后使用solr实现商品搜索,然后在页面中把搜索结果展示出来。
我们把SKU商品名称、商家名称、价格、规格等信息设置为业务域。规格的存储采用了动态域来实现。
我们使用的是SpringDataSolr框架来实现对solr的操作。
如果要搜索的内容数据量很大并且并发量很高的情况下,一个solr服务是不能满足要求的,所以此时需要SolrCloud来解决。SolrCloud也就是solr的分布式解决方案。是zookeeper+solr实现的。
在项目中搜索功能使用solr实现,在solr中配置中文分析器,我们使用IKAnalyzer来实现中文分词。如果是新上市的商品可能会出现一些新的关键词,为了查询的准确性,我们会把新的关键词添加到IKAnalyzer的扩展词典中。
我们项目主体部分采用的是Dubbox分布式框架,利用Zookeeper实现各系统之间的调用。另外就是使用ActiveMQ实现系统之间异步调用。前端跨域调用使用CORS技术。
项目中使用到了Activemq,可以实现系统之间的异步通信,从而实现业务的解耦和执行效率的提升。
使用MQ中间件可以有两种通信方式queue和topic。Queue可以实现点到点之间的通信,可以有多个Producer也可以有多个Consumer,但是消息只能被一个Consumer接收,一旦消息被消费后就没有了。
Topic可以实现类似广播的通信方式,可以有多个Producer和多个Consumer,一旦有Producer发送消息后,此消息可以被所有Consumer接收。
应用场景1:当后台系统对商品数据进行添加、删除、修改后,将会发送一个消息变化的消息,此消息通过topic进行通信,有多个消费端,:商品详情页面的静态页面会重新生成。
应用场景2:用户注册时,向用户注册发送短信验证码,采用queue方式通信。消费端调用阿里大于短信接口进行短信的发送。
在我们的项目中,我们使用一个SSO(单点登录)系统来解决集群环境下的登录问题,只需要在单点登录系统中登录一次就可以访问其他的互信,网站。我们采用的耶鲁大学的开源项目CAS,并与SpringSecurity进行集成 。
我们的项目中是用户不登陆的时候也可以使用购物车,通过读写cookie实现的。当用户登陆后,将本地的购物车同步到服务端,采用Redis进行存储。同步后将本地的购物车数据清除。
1、把商品的数量放到redis中。
2、秒杀时使用decr命令对商品数量减一。如果不是负数说明抢到。
3、一旦返回数值变为0说明商品已售完。
我们系统采用微信扫码支付。首先需要到微信平台申请微信公众账号(服务号),然后再申请开通微信支付。开通后会得到appid、秘钥等数据,用于调用微信支付接口。
微信支付接口是通过httpClient方式向微信支付平台发送数据并获取结果。
(1)调用统一下单接口获取url
(2)根据获取的url在页面上通过qrcode.js生成二维码
(3)生成二维码后,实时轮询查询订单状态,当返回成功时,跳转至成功页面
ng-app 指定应用模块
ng-controller 指定控制器
ng-init 指定控制器调用的初始化方法
ng-model 绑定变量
ng-if 条件判断
ng-repeat 循环数据
我们使用redis作为数据缓存,并搭建redis集群(6个点,3主3备),使用Spring Data Redis框架操作redis缓存。
可以使用nginx做反向代理服务器,经过配置nginx.conf 配置反向代理,将请求转发给后端的tomcat集群 ,实现负载均衡。
数据库可以实现垂直切分和水平节分。垂直切分就是将不同业务模块的表存入到不同的数据库中。水平切分就是将一个表的数据按照一定分片规则存储在不同的数据库中。
我们可以使用mycat数据库中间件。Mycat可以很方便地管理数据的集群。通过设置数据节点、分片规则、逻辑库、逻辑表来实现数据的水平切分。
对于大部分应用,数据库读的多,写的少。数据库所承担是主要是读的压力。我们可以通过mysql的主从复制实现数据库的读写分离。即一个主库(用于写入数据),多个从属库(用于读取数据)。当用户发送查询语句,就访问从属库,如果用户发送增删改语句,就访问主库。
主库与从属库之间建立心跳,实现实时同步数据。
Docker是一个开源的引擎,可以轻松的为任何应用创建一个轻量级的、可移植的、自给自足的容器。开发者在笔记本上编译测试通过的容器可以批量地在生产环境中部署。