linux 安装MQ 需要安装 java JDK 先把Open jdk卸载掉 安装java 的jdk 在可以 java -version 查看 是否是java jdk
www.cnblogs.com/CuteNet/p/3947139.html 访问网址卸载Open JDK rpm -qa | grep java :查看虚拟机的jdk
索引库的同步,
商品维护,和添加商品是索引库维护,两个不同的功能
添加一条商品怎么把这一条商品同步到索引库中,和其他的数据没有任何关系?
同步索引库分析:MQ消息的队列
谁发消息就是消息的生产者,谁接收消息就是消息的消费者MQ是一个消息的中间件,可以实现系统的解耦合的作用
安装MQ,配置jdk
linux命令 用户切换的命令是 su - (切换root用户) 输入密码OK su - "普通的用户名" 就可以了
工具成功连接安装好的虚拟机之后可通过 rpm -qa | grep java 或 rpm -qa | grep jdk 命令来查询出系统自带的jdk
然后通过 rpm -e --nodeps 后面跟系统自带的jdk名 这个命令来删除系统自带的jdk,
例如:rpm -e --nodeps java-1.8.0-openjdk-1.8.0.102-4.b14.el7.x86_64
]
创建一个文件存放jdk
移动jdk和tomcat的压缩包文件 使用移动命令 mv 是移动 cp 是复制过去
解压压缩包 tar(是指令) -vxzf
解压成功,配置JDK的环境变量,配置linux上的环境变量需要修改linux系统中的一个配置文件,把我们要配置的环境变量写在里面,就可以了,是在根路径的etc 文件夹中,进入etc文件中 然后在找到profile 文档我们要把环境变量写在这里面 我们编辑profile文档
x先重命名一下 mv jdk1.8.0_162/ jdk1.8 mv 重命名的意思 mv 旧的 新的
vim profile 配置环境变量的网址 www.linuxidc.com/Linux/2016-09/134941.html
环境变量配置完成后加载一下 命令 source /etc/profile
JAVA_HOME=/usr/local/java/jdk1.8
JAR_HOME=$JAVA_HOME/jre
PATH=$PATH:$JAVA_HONE/bin:$JRE_HOME/bin
CLASS_PATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib
export JAVA_HOME JRE_HOME CLASS_PATH PATH
我们还可以启动一下linux上的tomcat8:启动
关闭: shutdown.sh 启动 :startup.sh
要先进入先进入tomcat8文件中的bin,里面有脚本文件,启动脚本 startup.sh 启动成功查看日志文件 tomcat的日志文件是在logs文件中存放 查看日志 命令(tail -f -n 500 /usr/soft/tomcat8/logs/catalina.out)
部署项目:进入tomcat的webapps文件中把打成 项目名.war 放进webapps文件中, 然后启动tomcat就可以运行项目了
我们还可以给IP地址绑定域名,就可以直接访问域名就可以啦
还可以省略端口号不用写,只需要改一下端口号改成 80 即可
1. ActiveMQ
1.1. 什么是ActiveMQ
ActiveMQ 是Apache出品,最流行的,能力强劲的开源消息总线。ActiveMQ 是一个完全支持JMS1.1(java消息服务)和J2EE 1.4规范的 JMS Provider实现,尽管JMS规范出台已经是很久的事情了,但是JMS在当今的J2EE应用中间仍然扮演着特殊的地位。
主要特点:
1. 多种语言和协议编写客户端。语言: Java, C, C++, C#, Ruby, Perl, Python, PHP。应用协议: OpenWire,Stomp REST,WS Notification,XMPP,AMQP
2. 完全支持JMS1.1和J2EE 1.4规范 (持久化,XA消息,事务)
3. 对Spring的支持,ActiveMQ可以很容易内嵌到使用Spring的系统里面去,而且也支持Spring2.0的特性
4. 通过了常见J2EE服务器(如 Geronimo,JBoss 4, GlassFish,WebLogic)的测试,其中通过JCA 1.5 resource adaptors的配置,可以让ActiveMQ可以自动的部署到任何兼容J2EE 1.4 商业服务器上
5. 支持多种传送协议:in-VM,TCP,SSL,NIO,UDP,JGroups,JXTA
6. 支持通过JDBC和journal提供高速的消息持久化
7. 从设计上保证了高性能的集群,客户端-服务器,点对点
8. 支持Ajax
9. 支持与Axis的整合
10. 可以很容易得调用内嵌JMS provider,进行测试
1.0.安装ActiveMQ在把ActiveMQ的压缩包添加到activemq文件中然后解压压缩包
./activemq start 执行命令 ./activemq status 查看状态 关闭时 stop
启动成功就可以查看ActiveMQ的官方页面
在启动之前要关闭防火墙
1.1. ActiveMQ的消息形式的两种形式
对于消息的传递有两种类型:
一种是点对点的,即一个生产者和一个消费者一一对应;发送一个消息,只能有一个接收者,
另一种是发布/订阅模式,即一个生产者产生消息并进行发送后,可以由多个消费者进行接收。发送一个消息,有多个接收消息者
在linux系统上配置java开发的ActiveMQ客户端启动配置文件
<dependency> <!- 导入ActiveMQ的依赖的包 ->
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-all</artifactId>
</dependency>
Queues:点对点的形式是,如果一个消息你不接收你们它会默认在服务端持久化.一直保存着,没有保存期限,是永久保存,除非是你把这个消息给消费了,然后就没有了
Topics:广播模式,是不支持持久化的,能接收到就接收到,接收不到数据就会丢掉
弹框缓存和取出缓存的数据
1.1. 向业务逻辑中添加缓存
1.1.1. 缓存添加分析
使用redis做缓存。
业务逻辑:
1、根据商品id到缓存中命中
2、查到缓存,直接返回。
3、差不到,查询数据库
4、把数据放到缓存中
5、返回数据
缓存中缓存热点数据,提供缓存的使用率。需要设置缓存的有效期。一般是一天的时间,可以根据实际情况跳转
需要使用String类型来保存商品数据。
可以加前缀方法对象redis中的key进行归类。
查看商品详情使用缓存技术,可以在Redis缓存中获取商品详情页面,数据,使用Freemaker页面静态化,展示页面数据,
1. 服务接口实现
1.1. 检查数据是否可用
1.1.1. 功能分析
请求的url:/user/check/{param}/{type}
参数:从url中取参数1、String param(要校验的数据)2、Integer type(校验的数据类型)
响应的数据:json数据。e3Result,封装的数据校验的结果true:成功false:失败。
业务逻辑:
1、从tb_user表中查询数据
2、查询条件根据参数动态生成。
3、判断查询结果,如果查询到数据返回false。
4、如果没有返回true。
5、使用e3Result包装,并返回。
操作判断查询的结果数据是否合格
//注入Mapper层,执行查询条件 @Autowired private TbUserMapper userMapper; /** * 注册方法 */ public E3Result checkData(String param, int type) { //创建User的查询条件,还要根据不同的type生成不同的查询条件 TbUserExample example = new TbUserExample(); Criteria criteria = example.createCriteria(); //操作返回查询的条件 //判断返回的状态码,1表示:用户名,2表示:手机号,3表示:邮箱 if (type==1) { criteria.andUsernameEqualTo(param); } else if (type==2) { criteria.andPhoneEqualTo(param); } else if (type==3) { criteria.andEmailEqualTo(param); } else { //返回错误提示信息 return E3Result.build(666, "数据类型错误!"); } //执行查询条件 List<TbUser> list = userMapper.selectByExample(example); //判断结果是否带有数据 if (list != null && list.size()>0) { //判断查询的集合数据是否为空,长度是否为空 return E3Result.ok(false); } //发回正确答案 return E3Result.ok(true); } |
操作完成发布服务
<!-- 声明需要暴露的服务接口 -->
<dubbo:service interface="cn.e3mall.sso.service.RegisterService" ref="registerServiceImpl" timeout="600000"/>
编写Controller层,接收表单的数据,进行操作,把参数传递给Service层进行处理结果
,用户唯一验证,密码验证,和手机号验证,都同过,进行注册添加用户操作
用户注册操作添加用户名.
用户登录模块:
登录模块的处理的业务逻辑
1.什么是sso系统
SSO英文全称Single Sign On,单点登录。SSO是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。它包括可以将这次主要的登录映射到其他应用中用于同一个用户的登录的机制。它是目前比较流行的企业业务整合的解决方案
2.登录的处理流程:
1、登录页面提交用户名密码。
2、登录成功后生成Token。Token相当于原来的jsessionid,字符串,可以使用uuid。
3、把用户信息保存到redis。Key就是token,value就是TbUser对象转换成json。
4、使用String类型保存Session信息。可以使用“前缀:token”为key
5、设置key的过期时间。模拟Session的过期时间。一般半个小时。
6、把token写入cookie中。
7、Cookie需要跨域。例如www.e3.com\sso.e3.com\order.e3.com,可以使用工具类。
8、Cookie的有效期。关闭浏览器失效。
9、登录成功。
单点登录,我们需要登录的数据放到session中,单点登录我们需要一个session服务器来管理session ,session使用key.value的形式,我们把session放进redis里面去 ,我们在不同的电脑上登录就是不同的session,那我们是怎么区分他是不同的session那,是用sessionid来区分的,我们使用不同的sessionid来区分你是当前的那个会话,我们把sessionid放进cookie中,每次发送请求都会把cookie带入服务端,那我们需要自己生产一个sessionID
我们要保证sessionid不可以重复,这样才能区分各个session才是相互独立的,生成的sessionid要保证不同,可以使用uuid,
一个token对应一个session,一个session就对应一个用户信息,我们可以使用sessionid来区分,生成的token本身节点sessionID 那我们就把sessionid 保存到redis 中也需要设置一些redis的过期时间,否则session就会永久保存,session是有过期时间的但是我们也需要设置一下j
我们还需要把token写入Cookie中
还需要判断登录的状态,先从Cookie中获取token,判断你当前是否在登录的状态,获取到token以后,还要判断token有没有过期,这时候我们需要调用sso的服务,sso就会根据token来获取redis,把key取出来,那么我们判断一下有没有取到,如果取到啦,那么你是登录状态,进行其他的操作,如果你没有登录去判断你的token,取出来是空,就代表你的key就已经过期了,key一旦过期了,就会从缓存中移除,那么我们就判断你没有登录,然后就跳转到登录页面,让你去登录
1.1.1. Dao层
查询tb_user表。单表查询。可以使用逆向工程。
1.1.2. Service层
参数:
1、用户名:String username
2、密码:String password
返回值:e3Result,包装token。
业务逻辑:
1、判断用户名密码是否正确。
2、登录成功后生成token。Token相当于原来的jsessionid,字符串,可以使用uuid。
3、把用户信息保存到redis。Key就是token,value就是TbUser对象转换成json。
4、使用String类型保存Session信息。可以使用“前缀:token”为key
5、设置key的过期时间。模拟Session的过期时间。一般半个小时。
6、返回e3Result包装token。
1.1. 通过token查询用户信息
1.1.1. 功能分析
请求的url:/user/token/{token}
参数:String token需要从url中取。
返回值:json数据。使用e3Result包装Tbuser对象。
业务逻辑:
1、从url中取参数。
2、根据token查询redis。
3、如果查询不到数据。返回用户已经过期。
4、如果查询到数据,说明用户已经登录。
5、需要重置key的过期时间。
6、把json数据转换成TbUser对象,然后使用e3Result包装并返回。
判断用户是否登录
查看订单,如果你没有登录,还能查看订单吗?答案是不能,是必须需要你登录, 那如何判断你的登录状态呢,就是从cookie中获取token,这个才是判断你当前是不是登录的标准,从cookie中获取token,还要判断token有没有过期,我们需要调用sso的服务,我们就根据token来获取redis,其实key就是token,那就是根据key来获取value,那我们去判断有没有取到如果取到啦那么你是登录状态,你是登录状态的话,哪我还有重置你的过期时间,你刷新一次也就是相当于重置了一下时间,session过期时间
如果你没有登录判断token,获取token里面的用户信息,如果取出来是空,空说明你的key已经过期啦key一旦过期了,就会从缓存中移除,那么我们就判断你没有登录,然后就跳转到登录页面,让你去登录
用户请求跨域的报错问题的解决
js 跨域问题,应该是处于安全考虑 就是说8082下面的js不能访问8088下面的数据,就出现啦跨域问题
什么是跨域呢?域名不同,或者是IP地址不同,还有一种情况,IP地址相同,域名也相同,端口不同也叫跨域
什么的错误是,IP地址相同,端口号不同, js是有限制的,是不可以跨域请用数据的
什么情况下跨域呢? 怎么解决跨域的问题呢?相应的时候使用jsonp的格式
js可以跨域加载js文件
先定义一个方法,方法中有一个参数,定义完成,接下来做一个Ajax请求,跨域加载就是文件
方案一:在Controller中取cookie中的token数据,调用sso服务查询用户信息。
方案二:当页面加载完成后使用js取token的数据,使用ajax请求查询用户信息。
问题:服务接口在sso系统中。Sso.e3.com(localhost:8088),在首页显示用户名称,首页的域名是www.e3.com(localhost:8082),使用ajax请求跨域了。
Js不可以跨域请求数据。
什么是跨域:
1、域名不同
2、域名相同端口不同。
解决js的跨域问题可以使用jsonp。
Jsonp不是新技术,跨域的解决方案。使用js的特性绕过跨域请求。Js可以跨域加载js文件。
先定义一个方法,把这个方法名传递给服务端,更具方法名,拼接一个方法调用的语句,相应给浏览器,这个语句会调用这个方法,把我们相应的数据取出来
单点登录父回顾
1.单点登录主要解决的是一个session共享的问题,除了session共享的问题,还有一个注册,登录的页面的实现,和数据的提交,你一但登录的话都会调用单点登录的这个系统,才能进行登录注册,那么我们是怎么解决session共享的问题呢,我们是把session统一管理,如果你要把session统一管理的话,就不能使用tomcat自带的session啦 ,得要自己模拟session ,模拟session就要使用Redis模拟session,如果你要使用Redis模拟session,就设计到一个问题,我们把session放到Redis中,Redis中的key可以是什么?value是什么?,都要考虑清楚,那么这时候我们就应该考虑,key就应该是sessionid,就应该区分每一个session,每一个连接,的session信息都是不一样的,我们应该自己生成一个sessionID,sessionID呢我们管它叫token,那么我们使用UUID来生成不同的sessionID,有啦sessionID以后我们把用户信息就可以放到session中,key就是token,value就是用户信息,绑定以后,我们还要操作session的过期时间,把session对应的过期时在Redis中设置一下,设置完成以后,返回到成功页面,还有一个问题,我们客户端如何识别你到底是哪个session呢,那么我们还要把sessionid返回回去,返回到Cookie中,将来我们需要判断用户是否登录,还要在Cookir中获取这个token,获取完之后,还要去单点登录的系统中判断你当前的状态是否在登录的状态
购物车的分析 :
购物车要涉及到登录的业务处理,判断你登录或不登录的情况,登录情况下跟我学然后处理,不登录的情况下购物车然后处理?
1.添加购物车
2.删除购物车
3.修改购物车中的数量
4.展示购物车列表数据
* 添加购物车商品详情
* @author kwb
/*我们要对Cookie进行读写的操作 ,处理Cookie的读写我们只能在表现层操作,
* 服务层是操作不了的Cookie,表现层拿不到作用域的参数(request,response)
加入购物车的流程:
1.先进入商品详情展示 <a οnclick="cartAdd(${item.id}, 0, 1, 0, 1, this);"><b></b>加入购物车</a>
<!-- 点击加入购物车按钮,把商品的id传过去 还有商品的数量 -->
function cartAdd(product_id,cart_type,opencity_id, flag,bs, obj, cfrom){
//取购物车商品数量 product_id商品id
var num = $("#number_" + product_id).val();获取文本框value的属性值
拼装url参数,做跳转 添加购物车 把商品id传过去 num商品数量参数也传过去
location.href="http://localhost:8090/cart/add/"+product_id+".html?num=" + num;
业务,我们把商品加入购物车,首先要从Cookie中把商品的列表取出来,然后判断购物车是否有商品,如果有就把之前的商品添加到购物车中,
还需要判断之前的商品和添加新的商品是否有重复的商品,如果有则让数量增加
如果存在,商品数量相加。如果有重复的吧商品数量取出来,然后再加添加后的商品数量
tbItem.setNum(tbItem.getNum() + num);//商品数量加一
1.1.1. 解决请求*.html后缀无法返回json数据的问题
在springmvc中请求*.html不可以返回json数据。
修改web.xml,添加url拦截格式。
1.1. 修改购物车商品数量,需要传过去两个值,一个是你要修改的商品id,一个是你增加或者减少的商品的数量,两个值
1.1.1. 功能分析
1、在页面中可以修改商品数量
2、重新计算小计和总计。
3、修改需要写入cookie。
4、每次修改都需要向服务端发送一个ajax请求,在服务端修改cookie中的商品数量。
请求的url:/cart/update/num/{itemId}/{num}
参数:long itemId、int num
业务逻辑:
1、接收两个参数
2、从cookie中取商品列表
3、遍历商品列表找到对应商品
4、更新商品数量
5、把商品列表写入cookie。
6、响应e3Result。Json数据。
返回值:
e3Result。Json数据
1.1. 删除购物车商品
1.1.1. 功能分析
请求的url:/cart/delete/{itemId}
参数:商品id
返回值:展示购物车列表页面。Url需要做redirect跳转。
业务逻辑:
1、从url中取商品id
2、从cookie中取购物车商品列表
3、遍历列表找到对应的商品
4、删除商品。
5、把商品列表写入cookie。
6、返回逻辑视图:在逻辑视图中做redirect跳转。
1.1. 小结
使用cookie实现购物车:
优点:
1、实现简单
2、不需要占用服务端存储空间。
缺点:
1、存储容量有限
2、更换设备购车信息不能同步。
实现购车商品数据同步:
1、要求用户登录。
2、把购物车商品列表保存到数据库中。推荐使用redis。
3、Key:用户id,value:购车商品列表。推荐使用hash,hash的field:商品id,value:商品信息。
4、在用户未登录情况下写cookie。当用户登录后,访问购物车列表时,
a) 把cookie中的数据同步到redis。
b) 把cookie中的数据删除
c) 展示购物车列表时以redis为准。
d) 如果redis中有数据cookie中也有数据,需要做数据合并。相同商品数量相加,不同商品添加一个新商品。
5、如果用户登录状态,展示购物车列表以redis为准。如果未登录,以cookie为准。
Redis:是单线程的,如果请求过来多的话,它只能一个一个的处理,处理起来很慢,在Redis中尽量操作比较小的数据,这样的话就会很快的完成,
我们可以使用 hash 的类型来存储购物车中的数据 ,那么hash的key就是用户的id, 一个用户对应一个hash
用户在登录的情况下,我们就把加入的商品添加的到Redis中,没有登录的情况下,就保存到Cookie中
但是我们还需要判断用户到底有没有登录,那么就需要去单点登录的系统中去判断用户有没有登录,需要调用单点登录系统中的服务,我们要先获取一个token,就是sessiopID,先获取sessionID,拿到这个token之后我们需要把token拿到服务端去验证,有没有登录如果token都没有取到那就你没有登录,如果取到啦,还需要判断这个session 有没有过期,没有返回就代表session过期啦
1.1. 用户身份认证
在展示订单确认页面之前,需要对用户身份进行认证,要求用户必须登录。
1.1.1. 功能分析
1、使用springmvc的拦截器实现。需要实现一个接口HandlerInterceptor接口。
2、业务逻辑
a) 从cookie中取token。
b) 没有token,需要跳转到登录页面。
c) 有token。调用sso系统的服务,根据token查询用户信息。
d) 如果查不到用户信息。用户登录已经过期。需要跳转到登录页面。
e) 查询到用户信息。放行。
3、在springmvc.xml中配置拦截器。
1.1.2. 拦截器实现
1、在springmvc.xml中配置拦截器。
更换设备,同步购物车,怎么实现?
* 创建一个拦截器,用户登录处理
* @author kwb
* 用于判断你是否登录没有登录.不需要拦截,只需要判断就OK
* 你如果是登录我就把用户信息取到,然后放进request中
* 你可以在Controller层看看有没有用户信息,判断是不是登录的状态,
* 如果不登录情况下也可以使用购物车,不管你登不登陆,都要让用户使用购物车,所以不管你在什么情况下你都要放行,
* 你要在添加Redis之前判断他是不是登录状态,如果你不判断,所有的购物车都会存放进Cookie中,
* 只有你提交订单的时候,才会判断你到底有没有登录,到那个时候购物车就不能同步啦
* 所以要在加入购物车之前,去判断它当前的登录状态 ,如果是登录,我们需要把它放到服务端,如果没有登录需要放进Cookie中,
* 所以我们要在添加购物车之前进行拦截操作,不管你是添加,删除,修改,我们都需要对他进行拦截,如果是登录我们就进行另外的处理,不登录时另外一种处理,
* 那么都需要进行来判断你有没有登录,那么我们就使用拦截器来实现,单独的把这个处理提出来,拦截器就是判断你有没有登录
package cn.e3mall.cart.interceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import cn.e3mall.common.utils.CookieUtils; import cn.e3mall.common.utils.E3Result; import cn.e3mall.pojo.TbUser; import cn.e3mall.sso.service.TokenService; /** * 创建一个拦截器,用户登录处理 * @author kwb * 用于判断你是否登录没有登录.不需要拦截,只需要判断就OK * 你如果是登录我就把用户信息取到,然后放进request中 * 你可以在Controller层看看有没有用户信息,判断是不是登录的状态, * 如果不登录情况下也可以使用购物车,不管你登不登陆,都要让用户使用购物车,所以不管你在什么情况下你都要放行, * 你要在添加Redis之前判断他是不是登录状态,如果你不判断,所有的购物车都会存放进Cookie中, * 只有你提交订单的时候,才会判断你到底有没有登录,到那个时候购物车就不能同步啦 * 所以要在加入购物车之前,去判断它当前的登录状态 ,如果是登录,我们需要把它放到服务端,如果没有登录需要放进Cookie中, * 所以我们要在添加购物车之前进行拦截操作,不管你是添加,删除,修改,我们都需要对他进行拦截,如果是登录我们就进行另外的处理,不登录时另外一种处理, * 那么都需要进行来判断你有没有登录,那么我们就使用拦截器来实现,单独的把这个处理提出来,拦截器就是判断你有没有登录 * */ public class LoginInterceptor implements HandlerInterceptor { //注入单点登录的接口,来测试用户是否登录 @Autowired private TokenService tokenService; @Override //前处理,是在执行Hander之前执行此方法 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //是在执行Hander之前执行此方法 //返回true 放行 false 拦截 // 1.从Cookie中获取token信息 String token = CookieUtils.getCookieValue(request, "token");//直接取token信息 // 2.如果没有token,未登录状态,直接返回 if (StringUtils.isBlank(token)) {//判断token是否存在 //如果没有直接返回 return true; } // 3.取到token,需要调用sso系统的服务,根据token来获取用户信息 //调用单点登录的方法,把token传过去,去Redis的查取用户信息,返回一个用户信息 E3Result e3Result = tokenService.getUserByToken(token); // 4.没有取到用户信息,token过期,直接返回 if (e3Result.getStatus() != 200) { return true; } // 5.取到用户信息,登录状态 TbUser tbuser = (TbUser) e3Result.getData(); // 6.把用户信息放进request中,只需要在Controller层,判断request中是否包含用户信息 ,放形 request.setAttribute("tbuser", tbuser); return true; } @Override //处理后 public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { //Handler执行之后,返回ModelAndView之前 } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { //完成处理,返回ModelAndView之后 } } |
购物车分为两种情况,一种是登录的情况下怎么使用购物车,如果你不登录我们没有办法,把你添加购物车的商品添加到服务端,我们只能放进Cookie里面,我们把购物车放进Cookie里面我们实现起来就比较简单,不用占用我们服务端的资源,只需要对Cookie进行读写就可以啦,但是存储Cookie里面,它的存储上限是有限的,不能存的太多,如果你跟换一个设备,购物车里面的数据不能同步,Cookie是存在本地的数据,但是它是一种最简单的实现购物车方法,可以在以后的版本中逐步的完善
我们还在登录情况下的购物车的实现,可以使用之前的单点登录系统,实现登录,一但登录成功之后,我们会在Cookie里面会有一个token信息,那么我们是如何判断你是登录还是没有登录,是从Cookie中的token信息来判断的,判断用户是不是登录,我们是先从Cookie中取token,取完token之后,在调用单点登录中的服务来判断你的session是否过期,如果没有过期,就是登录的状态,其他的状态就是未 登录,如果你是登录还是不登录都可以使用购物车,我们写的拦截器,只是判断用户是登录还是不登录,拦截器里面并没有对用户进行拦截的操作,不管什么情况我们都放行,只不过用户没有登录的话,会走Cookie
在Controller 中我们是如何来判断它是否登录了呢?
就是在request对象中看看有没有user对象,在拦截器里面我们会把用户对象取出来之后会放在request作用域中,我们只需要在方法里面判断有没有用户信息判断它是不是登录啦,登录之后呢我们会把购物车信息放进Redis中 ,你要把购物车放进Redis 中哪key是什么,key就是用户id,谁登录啦,我就使用是谁当做key,key就是用户id,在保存value的时候,我们知道它里面是商品的列表数据 ,我们使用的是hash类型存储购物车的数据,存取更方便, hash里面的field就是商品的id ,value就是对象,转成json串
合并购物车:
还有一种情况,当用户没有等登录的时候,加入购物车商品,但是等一会他有登录,又往购物车添加商品数据,这个时候,就要实现购物车合并,合并啦之后,我们都是以服务端为准,以后再存取购物车的时候 就从服务端取就可以啦
支付平台:可以参考支付文档,调用第三方接口实现支付功能
要申请一个能够实现在线支付的平台,必须申请的是一个服务号,不能是订阅号,订阅号不能做支付功能,必须是服务号,还要拿公司的资质去申请,是根据自己的权限来调用接口
Mycat
1 海量数据的存储问题
如今随着互联网的发展,数据的量级也是撑指数的增长,从GB到TB到PB。对数据的各种操作也是愈加的困难,传统的关系性数据库已经无法满足快速查询与插入数据的需求。这个时候NoSQL的出现暂时解决了这一危机。它通过降低数据的安全性,减少对事务的支持,减少对复杂查询的支持,来获取性能上的提升。
但是,在有些场合NoSQL一些折衷是无法满足使用场景的,就比如有些使用场景是绝对要有事务与安全指标的。这个时候NoSQL肯定是无法满足的,所以还是需要使用关系性数据库。如果使用关系型数据库解决海量存储的问题呢?此时就需要做数据库集群,为了提高查询性能将一个数据库的数据分散到不同的数据库中存储。
一百万条的数据,一个Mysql数据库就可以搞定,查询的效率,但是数据量更多的话,mysql数据库的压力就会变大,上亿条的数据,是承载不住的
Mycat 是基于 cobar 演变而来,对 cobar 的代码进行了彻底的重构,使用 NIO 重构了网络模块,并且优化了 Buffer 内核,增强了聚合,Join 等基本特性,同时兼容绝大多数数据库成为通用的数据库中间件。
简单的说,MyCAT就是:
·一个新颖的数据库中间件产品支持mysql集群,或者mariadb cluster,提供高可用性数据分片集群。你可以像使用mysql一样使用mycat。对于开发人员来说根本感觉不到mycat的存在。
实现数据库分片,把一个表的内容,分别存放在不同的数据库中,设置配置文件,设置分片规则,根据id的值,来判断数据的存储位置,根据一定的规则来存储数据库的,在我们重查询数据的时候,也会根据这个规则来查询是哪个数据库
1 Mycat读写分离
数据库读写分离对于大型系统或者访问量很高的互联网应用来说,是必不可少的一个重要功能。对于MySQL来说,标准的读写分离是主从模式,一个写节点Master后面跟着多个读节点,读节点的数量取决于系统的压力,通常是1-3个读节点的配置
Mycat读写分离和自动切换机制,需要mysql的主从复制机制配合。
一个库做写的操作,一个库做读的操作,读写分离