1 |基于大数据技术的电子商务平台(老师指导下完成) 2 Ø 开发时间:2017/12 – 至今 3 Ø 软件架构:Spring + SpringMVC + Mybatis +EasyUI + Solr + Redis + Maven 4 Ø 项目描述: 5 该项目采用SSM框架,采用Redis缓存,采用Solr搜索实现多维度检索,缓解访问数据库压力。采用Nginx进行地址映射、负载均衡、反向代理。并从数据存储、服务器架设、性能方面进行优化设计,对项目功能模块和系统架构进行进一步优化。采用大数据分析技术,经过对业务数据进行采集、提取、分类、分流、分析等处理,进行业务指导和决策支持。 6 项目分为:后台管理系统,前台显示系统,用户系统,订单系统等。后台管理能够实现商品分类,商品管理,广告管理等。前台系统实现显示商品分类、商品、广告等。用户系统实现注册登录功能,订单系统实现添加购物车、商品结算功能。 7 8 描述一下这个系统: 9 [ 10 从3个方面来回答这个问题: 11 |--系统背景及系统概述 12 |--系统包括的业务模块及主业务流程 13 |--责任模块 14 ] 15 16 总体介绍: 17 1.背景及系统的概述: 18 商城是一个B2C(Business-to-Customer 商对客)电商项目,集零售与批发于一体。 19 整个项目技术用Spring,SpringMVC,Mybatis框架进行开发。 20 采用了分布式架构,使用Maven进行项目依赖和jar包的管理, 21 使用中间切分的方式将web,service,mapper,pojo分层开发,这样的好处也就是让代码的重用性更高. 22 采用Redis缓存, 23 采用Solr搜索实现多维度检索,缓解访问数据库压力, 24 采用Nginx进行地址映射、负载均衡、反向代理。 25 26 2.系统包括的业务模块及主业务流程: 27 咱们的这个项目为后台商品管理模块、会员模块、订单模块、购物车模块、支付模块、搜索模块、评论模块等。 28 29 3.责任模块: 30 我在这个项目中主要负责后台商品的管理模块:主要是实现商品的录入、上下架、以及商品类目详情展现,包括 商品规格参数模板设计以及商品实际参数录入功能。其中在商品查询中没有使用传统的mybatis分页查询而是会用一个分页插件PageHelper来实现。对于商品图片的上传,在后台页面使用了富文本编辑器KindEditor进行批量上传。后台使用fileupload组件来接收图片,在后台代码里面实现图片校验功能,图片验证包括:图片大小、格式、文件内容的校验。防止危险脚本经过图片上传到服务器;文件内容的校验是经过ImageIO读取上传的文件构建BufferedImage对象,经过断定BufferedImage的宽高属性来辨别上传的文件是否为图片。关于数据库优化方面,商品表中价格字段使用long型存储,避免了开发中处理小数的问题,商品描述做为表格单独设计,由于数量比较大,并且描述通常不轻易改动,单独做为一个表在查询商品的时候不须要查询,提升了查询性能,用户须要的时候让其查询而对于商品规格参数的设计考虑一个商品对应一张表,存放该商品的规格参数数据,数据表太庞大,因而组内商讨设计了一张商品规格参数模板表,该表中有事个字段,分别是id,建立时间,更新时间、商品类目id、商品类目名称、规格参数模板数据。每一个类目对应模板表的一条记录,规格参数模板数据存放的是商品类目的规格参数。新增添商品时模拟模板生成一个规格参数的表单。填写规格参数数据,保存到数据库中. 31 32 前台系统中我实现了商品分类的展现,实现商品分类展现我們当时有两种思路,第一种就是当前台系统的页面须要商品分类信息的时候,前台页面向前台系统发送ajax请求,由前台系统经过HttpClient请问后台系统获取分类信息,而后前台系统将商品分类信息数据给前台页面. 33 第二种实现方案是前台页面直接发送ajax请求访问后台系统,因为后台系统向前台页岩发送的是json格式的数据,而json数据没法进行跨域传送数据,我們当时使用了jsonp来包装json数据,实现路霸数据的传输.这种实现方案性能稍高于第一种,最后我采用了这种设计思路。 34 35 36 因为商品首页分类展现的操做很频繁,为了减轻数据库的压力,我們使用了redis做为缓存数据库。后台系统在查询mysql数据库以前,先查看redis里面是否有商品分类信息,若是有则直接返回结果,若是没有则查询mysql数据库,将查询结果保存在redis中并返回该结果。 37 38 我們的项目中关于用户登陆的这块采用的是单点登陆系统(什么是单点登陆),考虑到通常用户登陆的时候,当用户登陆成功之后,我們将用户信息保存在session中,由于这个我們采用的是分布式架构,当用户登陆要访问其余功能模块的时候,因为session是基于web服务器的,每个功能模块都有本身的web服务器,各个功能模块不能共享session数据,因此用户须要从新登陆.我們采用了单点登陆系统.当用户登陆成功后,我們根据时间戳和用户id生成惟一的令牌ticket,将ticket和用户令牌做为键值对放在redis中,并把ticket写入cookie中,当用户访问其余功能模块时,首先从cookie中拿到ticket,根据ticket在redis里面查找用户信息,若是找到则登陆成功。 39 40 在首页的搜索模块中我們使用了solr实现,提供服务从数据库中查询的数据生成索引库。为了实现各模块数据之間的同步,我們在搜索模块让娃不服务接口。只要后台系统数据有增删改就调用搜索模块的服务进行索引库的维护。(搜索这一块是其余人作的,他们提供了一个接口,经过这个接口调用搜索模块的服务进行维护。) 41 42 我們使用ActivityMQ实现商品数据的同步.为了减轻数据库的压力,提升系统性能我們引入了redis缓存数据库和solr索引库,这样就会涉及一个数据同步的问题。我們要保证mysql数据库、redis缓存数据库以及索引库中商品的数据是一致的,原先我們是这么作的:当后台系统商品的数据进行增删改操做后,经过httpClient调用前台系统和搜索系统对redia和索引库进行维护.这样虽然能解决数据同步问题,可是各个模块之間的耦合性过高.当新增长某个系统之后,要对后台系统进行维护,这显然不合理的,因此我們引入了activityMQ。后台管理系统做为消息的生产者,须要发送消息,在后台系统声明交换机,肯定交换机的类型topic。前端系统和搜索系统都是消息的消费者,在前端系统和搜索系统端声明队列,并监听消息,根据消息内容作出相应的操做。 43 44 购物车的实现有多种方式,能够直接使用数据库存储购买的商品信息,可使用session来做为购物车存储商品.用数据为存储商品对数据库形成的负担特别大,并且对于购物车这种须要实时操做的东西,数据库的访问量一旦太大,数据库容易出现并发错误,或者直接崩溃.用session来存储商品信息效率确实很高,并且会話针对各个链接的,因此便于管理,可是用session也不是完美的,由于session是有有效期的,根据服务器设置不一样而不一样,若是你在购物的过程当中session超时了,那么购物车中的东西就空了,session是保存在服务器内存中的,占用了服务器资源.session没法进行水平扩展,使用集群..基于这些我們使用cookie+Mysql,来实现购物车功能.当用户牌登陆状态的时候,我們将购物车信息存放在Mysql数据库中,当用户处于离线状态,我們将购物车信息存放在cookie中,用户进行登陆操做的时候,判断cookie中是否有购物车信息,若是有,则把购物车信息与数据库中的合并,由于我們使用了数据库做为购物车来存放商品数据,考虑到数据库的压力大,我們采用了数据库的集群,搭建实现数据库的读写分离.我們设计了一个主库负责写入数据,三个从库读取数据,这样就大大减轻了数据库的压力。 45 46 订单系统,购物车系统。 47 在首页的商品搜索模块我們使用了solr实现,我們提供服务从数据库中查询的数据生成索引库。为了实现与数据库之間的同步,我們在搜索快提供了服务接口。只要数据有增删改就调用对应的服务,再以后我就实现了商品详情页的展现,首先根据商品的id到redis缓存中命中,若是缓存中没有才会查询数据库,而且保存到redis中,考虑到redis是内存中的稀有资源,因此我們在设计的时候为不须要常常显示的提供了在redis中的有效时间。我們设计的是一天的时间,在商品详情页中首先将关键字段查询展现,在使用延迟的方法加载商品描述,提升了相应的速度。而且商品规格我們使用按需加载,只有点击加载商品描述,提升了生意人速度。而且商品规格我們使用按需加载,只有点击才会加载,减轻了数据库的压力。 48 49 因为顾客要建立订单须要登陆,可是我們采用的是分布式架构,为了提升顾客的体验性,因此我們采用了单点登陆系统。
1,电子商务常见模式前端
B2B:商家到商家。阿里巴巴。
B2C:商家到用户。京东。
C2C:用户到用户。淘宝。
B2B2C:商家到商家到用户。天猫。
O2O:线上到线下。美团、饿了么。java
2,电子商务行业技术特色 mysql
①技术新:(NoSql推广首在社区网站和电商项目),发展快,需求推进技术的革新。
②技术范围广:除了java,像淘宝前端还使用了PHP,数据库MySQL或者oracle,nosql,服务器端使用Linux,服务器安全、系统安全
③分布式:之前是在一台机器上作运算,如今是分散到不少机器上,最后汇总起来。(集中式向分布式进行考虑)由需求来推进
④高并发、集群、负载均衡、高可用:由并发问题采用集群处理,集群会涉及服务器的主从以及分布问题,使用负载均衡。(权重高低)高可用对用户而言,用户服务不中断(系统升级,服务不中断)。
⑤海量数据:双11,570亿的背后,订单有多少?浏览次数有多少?商品会有多少?活动相关数据?
⑥业务复杂:不要简单的认为是:商品展现出来后,加入购物车后购买就完成了。后台特别复杂,好比优惠(包邮、满减)
⑦系统安全:系统上线必须经过系统安所有门审核经过。前年CSDN数据泄露。快捷酒店数据泄露(经过身份证就能够查看你的开房记录)。近几年,安全意识逐步在提升。nginx
3,Maven是什么?为何要进行项目依赖与Jar包管理web
Maven是一个采用纯Java编写的开 源项目管理工具。采用了一种被称之为project object model (POM)概念来管理项目,全部的项目配置信息都被定义在一个叫作POM.xml的文件中,经过该文件,Maven能够管理项目的整个声明周期,包括编 译,构建,测试,发布,报告等等。Maven自己还支持多种插件,能够方便更灵活的控制项目。ajax
Maven经常使用于项目构建,依赖管理,热部署等。方便Jar包管理,工程之间的依赖管理,自动打包,热部署,方便svn版本控制。redis
4,什么是分布式架构,为何使用分布式架构,分布式架构的优势?spring
分布式结构就是将一个完整的系统,按照业务功能,拆分红一个个独立的子系统,在分布式结构中,每一个子系统就被称为“服务”。这些子系统可以独立运行在web容器中,它们之间经过RPC方式通讯。sql
注:集群是多台设备干同一件事情,而分布式是不一样的设备干不一样的事情。数据库
就商城项目而言。按照微服务的思想,咱们须要按照功能模块拆分红多个独立的服务,如:用户服务、产品服务、订单服务、后台管理服务、数据分析服务等等。这一个个服务都是一个个独立的项目,能够独立运行。若是服务之间有依赖关系,能够经过RPC方式相互调用。
这样的好处有不少:
5,项目的架构,分层架构?
技术架构:本项目使用市场上较为主流的框架spring+springmvc+mybatis进行开发,采用分布式的系统架构,前台系统和单点登陆系统采用了集群的方式部署,后台管理系统中采用了Maven的多模块化的管理,其中采用了水平切分的方式,将pojo、dao、service、web分层开发,这样作的好处就是能够重用性更高。系统内部接口调用采用Dubbo,在后台接口中扩展了spirng提供的jackson数据转化器实现;搜索系统使用了solr实现,在保证系统高性能的前提下,尽量为公司节约成本,咱们使用MySQL数据库进行集群(oracle收费)。在部署方面,采用了Nginx+tomcat的模式,其中nginx的做用一方面是作反向代理、负载均衡、另外一方面是作图片等静态资源的服务器。
功能架构:分布式系统架构,如问题四
6,涉及的技术
Spring、SpringMVC、MybatisJSP、JSTL、jQuery、jQuery plugin、EasyUI、KindEditor(富文本编辑器)、CSS+DIV
Redis(缓存服务器)
Lucene、Solr(搜索)
httpclient(调用系统服务)
Mysql
Nginx(web服务器)
Quartz(定时任务)
RabbitMQ(消息队列)
7,功能介绍,项目实现了哪些功能?
本项目包含:前台、后台、会员、订单、搜索、单点登录等系统模块。
1)搜索系统包括提供商品的搜索功能。
2)订单系统包括提供下单、查询订单、修改订单状态、定时处理订单。
3)后台管理系统包括管理商品、订单、类目、商品规格属性、用户管理以及内容发布等功能。
4)前台系统包括用户能够在前台系统中进行注册、登陆、浏览商品、首页、下单等操做。
5)会员系统包括用户能够在该系统中查询已下的订单、收藏的商品、个人优惠券、团购等信息。
6)单点登陆系统为多个系统之间提供用户登陆凭证以及查询登陆用户的信息。
8,为何使用Redis缓存?使用缓存的优势?
9,使用Solr干什么?Solr怎么进行搜索的?怎么实现多维度检索?
Solr是一个高性能,采用Java5开发,基于Lucene的全文搜索服务器。同时对其进行了扩展,提供了比Lucene更为丰富的查询语言,同时实现了可配置、可扩展并对查询性能进行了优化,而且提供了一个完善的功能管理界面,是一款很是优秀的全文搜索引擎。咱们把搜索单独作成一个服务,能够针对该服务作扩展,作成服务集群等,其它模块均可以调用Solr服务。
10,Nginx是怎么进行地址映射,负载均衡,反向代理等工做的?
反向代理:
11,项目中数据库压力的解决方案都有哪些?还有其余的数据库压力缓解的方法吗?
1,数据库语句优化
2,数据库存储优化(双数据库切换数据分流,使用Mycat进行分表分库,Mysql进行读写分离,主备复用,主从复制)
3,数据库访问性能优化(Redis缓存数据,FastDFS数据库)
12,数据存储,服务器架设,性能方面怎么进行优化的?
数据存储:如问题11
服务器:
使用Zookeeper进行服务管理,Dubbo进行服务的发布等。
使用Spring Cloud进行服务发布,配置管理,智能路由等。
使用Nginx进行负载均衡,反向代理,区域分流。
使用FastDFS对大文件进行存储、同步、上传和下载等。
使用NoSql(Redis)作数据缓存,用空间换时间,用内存换速度。
使用Solr搜索与HBase结合实现多维度检索。
性能:
使用FreeMark进行网页静态化。
系统拆分为分布式系统,提升系统扩展性。
13,项目中遇到的问题?解决方案?
1,后台管理模块(商品录入,上架下架,商品详情展现【规格参数模板设计,实际参数录入】)
技术亮点:分页插件pagehelper,富文本编辑器,图片校验,EasyUI
数据存储优化:【商品表价格字段为long,避免小数】,【商品描述单独做为表设计】,【商品规格参数模板】
分页:
商品查询中没有使用传统的mybatis分页查询而是会用一个分页插件PageHelper来实现。
富文本编辑器:
对于商品图片的上传,在后台页面使用了富文本编辑器KindEditor进行批量上传。
图片校验:
使用fileupload组件来接收图片,在代码里面实现图片校验功能,图片验证包括:图片大小、格式、文件内容的校验。防止危险脚本上传到服务器;
文件内容的校验是经过ImageIO读取上传的文件构建BufferedImage对象,经过断定BufferedImage的宽高属性来辨别上传的文件是否为图片。
数据存储优化:
商品表中价格字段使用long型存储,避免了开发中处理小数的问题;
商品描述做为表格单独设计,由于数量比较大,并且描述通常不轻易改动,单独做为一个表在查询商品的时候不须要查询,提升了查询性能;
商品规格参数的设计考虑一个商品对应一张表,存放该商品的规格参数数据,数据表太庞大,设计了一张商品规格参数模板表;
该表中有事个字段,分别是id,建立时间,更新时间、商品类目id、商品类目名称、规格参数模板数据;
每一个类目对应模板表的一条记录,规格参数模板数据存放的是商品类目的规格参数,
新增添商品时模拟模板生成一个规格参数的表单。填写规格参数数据,保存到数据库中。
2,前台技术:
技术亮点:Bootstarp,Jsonp包装json数据,页面静态化
数据库优化:Redis缓存数据库
实现商品分类展现:
第一种实现方案是:
当前台系统的页面须要商品分类信息的时候,前台页面向前台系统发送ajax请求,由前台系统经过HttpClient请问后台系统获取分类信息,
而后前台系统将商品分类信息数据给前台页面。 第二种实现方案是:
前台页面直接发送ajax请求访问后台系统,因为后台系统向前台页岩发送的是json格式的数据,而json数据没法进行跨域传送数据,
当时使用了jsonp来包装json数据,实现路霸数据的传输。
这种实现方案性能稍高于第一种,最后我采用了第二种设计思路。
3,单点登录页面:
技术亮点:共享Session(先从Session中拿到ticket【时间戳和用户id生成的惟一令牌】,根据ticket再redis中查找用户信息)
Redis:
因为商品首页分类展现的操做很频繁,为了减轻数据库的压力,我們使用了redis做为缓存数据库。
后台系统在查询mysql数据库以前,先查看redis里面是否有商品分类信息
若是有则直接返回结果,若是没有则查询mysql数据库,将查询结果保存在redis中并返回该结果。
单点登陆:
通常用户登陆的时候,当用户登陆成功之后,用户信息保存在session中,由于这个我們采用的是分布式架构,当用户登陆要访问其余功能模块的时候,
因为session是基于web服务器的,每个功能模块都有本身的web服务器,各个功能模块不能共享session数据,因此用户须要从新登陆
我們采用了单点登陆系统.当用户登陆成功后,就不用在其余系统中登录,也就是一次登录能够得到其余全部系统的信任,
我們根据时间戳和用户id生成惟一的令牌ticket(String ticket= user.getUserId() + "" + System.currentTimeMillis();
),将ticket和用户令牌做为键值对放在redis中,并把
ticket写入cookie中,当用户访问其余功能模块时,首先从首先从cookie中拿到ticket, 根据ticket在redis里面查找用户信息,若是找到则登陆成功。
4,搜索页面:
技术亮点:Solr搜索(索引库),ActivityMQ消息队列(实现数据同步【索引库,缓存与信息】),延迟加载
Solr:
在首页的搜索模块中我們使用了solr实现,提供服务从数据库中查询的数据生成索引库。为了实现各模块数据之間的同步,在搜索模块提供服务接口。
只要后台系统数据有增删改就调用搜索模块的服务进行索引库的维护。(提供了搜索服务接口,经过接口调用搜索模块的服务进行维护。)
ActivityMQ:
使用ActivityMQ实现商品数据的同步,为了减轻数据库压力,提升系统性能,引入了redis缓存数据库和solr索引库,这样就会涉及数据同步问题。
我們要保证mysql数据库、redis缓存数据库以及索引库中商品的数据是一致,
原先我們是这么作的:
当后台系统商品的数据进行增删改操做后,经过httpClient调用前台系统和搜索系统对redia和索引库进行维护.这样虽然能解决数据同步问题,
可是各个模块之間的耦合性过高.当新增长某个系统之后,要对后台系统进行维护。
这显然不合理的,因此我們引入了activityMQ。
后台管理系统做为消息的生产者,须要发送消息,在后台系统声明交换机,肯定交换机的类型topic。前端系统和搜索系统都是消息的消费者,
在前端系统和搜索系统端声明队列,并监听消息,根据消息内容作出相应的操做。
5,购物车:
技术亮点:Mysql+Session存储商品信息,数据库集群(读写分离,主备复用,负载均衡)
购物车:
能够直接使用数据库存储购买的商品信息,可使用session来做为购物车存储商品。
这样用存储商品对数据库形成的负担特别大,并且购物车这种须要实时操做的东西,数据库的访问量一旦太大,数据库容易出现并发错误,或者直接崩溃。
使用session来存储商品信息效率确实很高,并且会話针对各个链接的,因此便于管理。
可是用session也不是完美的,由于session是有有效期的,根据服务器设置不一样而不一样
若是你在购物的过程当中session超时了,那么购物车中的东西就空了,session是保存在服务器内存中的,占用了服务器资源。
我們使用cookie+Mysql来实现。
当用户牌登陆状态的时候,我們将购物车信息存放在Mysql数据库中,当用户处于离线状态,我們将购物车信息存放在cookie中,
用户进行登陆操做的时候,判断cookie中是否有购物车信息,若是有,则把购物车信息与数据库中的合并,
由于我們使用了数据库做为购物车来存放商品数据,考虑到数据库的压力大,我們采用了数据库的集群,搭建实现数据库的读写分离。
我們设计了一个主库负责写入数据,三个从库读取数据,这样就大大减轻了数据库的压力。
未登陆(先写到cookie和Redis缓存中,登陆后写到数据库表中);
已登陆(直接写到数据库,而后写到Redis缓存中)
订单系统,购物车系统。
在首页的商品搜索模块我們使用了solr实现,我們提供服务从数据库中查询的数据生成索引库。
为了实现与数据库之間的同步,我們在搜索快提供了服务接口,只要数据有增删改就调用对应的服务。
再以后我就实现了商品详情页的展现,首先根据商品的id到redis缓存中命中,若是缓存中没有才会查询数据库,而且保存到redis中,
考虑到redis是内存中的稀有资源,因此我們在设计的时候为不须要常常显示的提供了在redi中的有效时间。我們设计的是一天的时间,
在商品详情页中首先将关键字段查询展现,在使用延迟的方法加载商品描述,提升了相应的速度。而且商品规格我們使用按需加载,只有点击加载商品描述,减轻了数据库压力