晚上 9.32前
10.1.6是内部通信ip
今天任务
Dubbo框架的介绍
Dubbo通讯方式
不能用9000访问提供者的服务 是因为用的是http协议 再dubbo里面 的用dubbo(tcp-ip协议)
zk的数据存储结构(一致性服务的调度性)
扩展:一主多从,读写分离,负载均衡,集群,分布式是一个概念吗?
分布式是一个概念,指的是多个服务器一起协作的方式,分布式系统是通过将硬件资源在物理层面进行分散化,然后通过计算机网络来实现信息交换。对于业务系统的用户来说,系统是统一完整的,一般不会感受到数据或者逻辑资源是分散的
集群是更多来解决高可用的,而分布式是解决高性能、高并发的
而一主多从,读写分离都是分布式的实际应用模式
负载均衡一般是集群的具体应用
一主多从
指的是服务之间的关系
读写分离
指的是读写不在一台机器上
负载均衡
指的是各个机器之间的工作强度一样,环节压力,比如某台机器流量太大扛不住。nginx会将部分流量转移到另外一台机器上去执行这个任务。集群指的是将几台服务器集中在一起,实现同一业务。分布式是指将不同的业务分布在不同的地方,比如读写分离中读的任务和写得任务不在一台机器上。一主多从也是主机负责主任务,从机负责次要任务
集中式的负载均衡说明
客户端的负载均衡
原始的都不知道目的地 优化后的不受限于服务列表
dubbo的负载均衡
去消费者(controller)里面调
负责rpc的一种负载均衡模式
ctrl+h去搜 LoadBalance
1.随机的负载均衡
2.轮询的负载均衡
3.一致性hash算法
4.挑选负载压力小的服务器访问算法
自我测试 轮询
@Reference(check = false,timeout = 3000, loadbalance = "roundrobinloadbalance")
京淘Dubbo项目改造
改造计划
1.
2.
3.
导包修改
额外的点
导入后 @Service 和 对应@Autowired的注解会有所不同 DI依赖如下对应 @Autowired的注解 依赖注入
<!--引入dubbo配置 -->
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>0.2.0</version>
</dependency>
修改jt-common
修改提供者jt-sso
待修正的错误 User应在common里面
修改jt-web 消费者 前台
修改配置文件
实现效果
测试 nginx本机 redis集群 哨兵 和zookeeper开启
web消费者报错 并修正 原先没有加
还是运行不了页面
应该是pojo里面得User在sso里面得原因
无法解决 直接导包8
用户模块实现
用户注册
页面分析
实现注册操作
页面JS分析
说明:根据页面url地址 查找页面JS的位置
jt-web
改动
可以直接入库 不返回信息
代码直接入库就可
关于POJO转化异常说明
报错说明: 由于SpringBoot配置了热部署的工具,当代码进行修改之后,程序就会重新启动. 在重启的过程中程序又会再次链接zookeeper注册中心.由于zk的心跳检测机制存在超时时间,可能在zk中会出现2条一模一样的服务的提供者的信息.
解决方案: 需要手动的重启服务器即可.
自我实现
重新导入了项目
脚手架
jt-web消费者 前台 controller层
service层
jt-common接口
service实现类
jt-sso 提供者
如上图 不返回了 直接入库 然后保持事务的一致性
提供者对应dao层
页面实现
前提 把nginx本机 redis集群 哨兵 和zookeeper开启
如上图 插入数据库成功
作业:
复习:关于Cookie操作 设定有效时间 设定cookie的域名共享 设定cookie的权限…
cookie是如何操作的…
下午
SSO介绍
用户登录具体实现
3.3.1 用户登录页面分析
1.url分析
分析
如上 或者jwt
分析js
页面js分析
$.ajax({
type: "POST",
url: "/user/doLogin?r=" + Math.random(),
contentType: "application/x-www-form-urlencoded; charset=utf-8",
data: {username:_username,password:_password},
dataType : "json",
error: function () {
$("#nloginpwd").attr({ "class": "text highlight2" });
$("#loginpwd_error").html("网络超时,请稍后再试").show().attr({ "class": "error" });
$("#loginsubmit").removeAttr("disabled");
$this.removeAttr("disabled");
},
success: function (result) {
//如果数据不为null时执行
if (result) {
var obj = eval(result);
if (obj.status == 200) {
obj.success = "http://www.jt.com";
var isIE = !-[1,];
if (isIE) {
var link = document.createElement("a");
link.href = obj.success;
link.style.display = 'none';
document.body.appendChild(link);
link.click();
} else {
window.location = obj.success;
}
return;
}else{
$("#loginsubmit").removeAttr("disabled");
verc();
$("#nloginpwd").attr({ "class": "text highlight2" });
$("#loginpwd_error").html("账号或密码错误!").show().attr({ "class": "error" });
}
}
编辑消费者的controller -----------jt-web
返回ticket
得把cookie返回 传回去
实现cookie共享
自我实现
controller消费者层
/**
* 完成用户的登录操作
* url地址:http://www.jt.com/user/doLogin?r=0.8989367429030823
* 参数: username/password
* 返回值: SysResult对象 的JSON的数据.
*
* cookie.setMaxAge(-1); 关闭浏览器会话时删除
* cookie.setMaxAge(0); 立即删除cookie
* cookie.setMaxAge(100); cookie可以存储的时间单位是秒
*
* http://www.jt.com/saveUser/xxx
* cookie.setPath("/");
* cookie.setPath("/add");
*/
@RequestMapping("/doLogin")
@ResponseBody
public SysResult doLogin(User user, HttpServletResponse response){
//1.实现用户的登录操作!!!
String ticket = "uuid"; //dubboUserService.doLogin(user);
//2.校验ticket是否有值.
if(StringUtils.isEmpty(ticket)){
//用户名或者密码错误
return SysResult.fail();
}
//3.如果用户的ticket不为null,则表示登录正确,需要将数据保存到cookie中
//Cookie要求 1.7天有效 2.要求cookie可以在jt.com的域名中共享 3.cookie权限 /
Cookie cookie = new Cookie("JT_TICKET",ticket);
cookie.setMaxAge(7*24*3600);
cookie.setDomain("jt.com"); //在jt.com中实现页面共享.
cookie.setPath("/"); //定于cookie的权限根目录有效
response.addCookie(cookie); //利用response将cookie保存到客户端中.
return SysResult.success();
}
继续
如上图 之前是左边那一块
对应查询不正确的话 ticket为null
if(StringUtils.isEmpty(ticket)){
//用户名或者密码错误
return SysResult.fail();
}
如上图 晚上去复习mybatisPlus 遗忘了 去回看
改的是内存数据的代码(密码) 没有入库没关系 只是为了脱敏处理
自我实现
如上图 原本随便输入都可以进行跳转
现在开始写业务逻辑层
脚手架
impl实现类 业务逻辑 查数据库及操作
@Autowired
private JedisCluster jedisCluster;
/**
* 1.根据用户名和密码查询数据库
* 2.校验用户数据的有效性.
* 3.如果用户的数据是正确的 则开始进行单点登录操作.
* 4.如果用户数据不正确 则ticket数据为null即可.
* @param user
* @return
*/
@Override
public String doLogin(User user) {
//1.将密码进行加密处理
String password = DigestUtils.md5DigestAsHex(user.getPassword().getBytes());
user.setPassword(password);
//如果传递的是对象,则根据对象中不为null的属性充当where条件
QueryWrapper<User> queryWrapper = new QueryWrapper<>(user);
User userDB = userMapper.selectOne(queryWrapper);
//2.校验数据是否有效
if(userDB == null){
return null;
}
//userDB数据不为null,用户的输入信息正确.开启单点登录操作.
//3.1动态生成uuid
String ticket = UUID.randomUUID().toString().replace("-", "");
//3.2脱敏处理
userDB.setPassword("123456你信不??");
String userJSON = ObjectMapperUtil.toJSON(userDB);
//3.3 将数据保存到redis中
jedisCluster.setex(ticket, 7*24*60*60, userJSON);
return ticket;
}
页面实现效果
第二次 UUID不一样的
UUID不懂 扩展 晚上
用户登陆回显
如下 有写死才会有报错
用户信息回显说明
根据ticket获得json字符串 然后转换回对象 进行页面回显
用户登录回显
当用户登录成功之后会生成COOKIE信息.
根据cookie获取TICKET信息,之后根据ticket获取user信息,.之后在首页展现用户名称即可.
页面分析
Request URL: http://sso.jt.com/user/query/2798d08a3ee24c46a1b7e3b1b8a0635e?callback=jsonp1600333080718&_=1600333080787
jt-sso 提供者去加业务
/**
* 根据ticket信息查询用户的json信息 jsonp请求 返回值使用特定的对象封装.
* url地址:http://sso.jt.com/user/query/ca620491866a42e596b29ee52fc27aff?callback=jsonp1600333068471&_=1600333068521
*/
@RequestMapping("/query/{ticket}")
public JSONPObject findUserByTicket(@PathVariable String ticket, HttpServletResponse response,
String callback){
if(jedisCluster.exists(ticket)){
//可以正确返回
String userJSON = jedisCluster.get(ticket);
return new JSONPObject(callback, SysResult.success(userJSON));
}else{
//如果根据ticket查询有误,则应该删除Cookie信息.
Cookie cookie = new Cookie("JT_TICKET","");
cookie.setDomain("jt.com");
cookie.setPath("/");
cookie.setMaxAge(0);
response.addCookie(cookie);
return new JSONPObject(callback, SysResult.fail());
}
}
正确数据带回去就行
返回的对象如下 晚上17.17
自我实现
@Autowired
private JedisCluster jedisCluster;
/**
* 根据ticket信息查询用户的json信息 jsonp请求 返回值使用特定的对象封装.
* url地址:http://sso.jt.com/user/query/ca620491866a42e596b29ee52fc27aff?callback=jsonp1600333068471&_=1600333068521
*/
@RequestMapping("/query/{ticket}")
public JSONPObject findUserByTicket(@PathVariable String ticket, HttpServletResponse response,
String callback){
if(jedisCluster.exists(ticket)){
//可以正确返回
String userJSON = jedisCluster.get(ticket);
return new JSONPObject(callback, SysResult.success(userJSON));
}else{
//如果根据ticket查询有误,则应该删除Cookie信息.
Cookie cookie = new Cookie("JT_TICKET","");
cookie.setDomain("jt.com");
cookie.setPath("/");
cookie.setMaxAge(0);
response.addCookie(cookie);
return new JSONPObject(callback, SysResult.fail());
}
}
回显成功错误的点
如果没写
正常登入无回显
解决办法 加上注解就好作业 登出 重定向到页面首页
问题:
江哥 请问我们写页面回显怎么又回到jt-sso(提供者)里面写了呢? 不应该按微服务架构,写在消费者jt-web里面么? 我有点混淆了,应该怎么去区分好一点呢.
答:其实这样你可以在这个web里边儿写,只不过呢,这个页面的js他发的一个请求,他是一个跨域的请求,所以呢只能去sso里边儿去找对应的请求路径。
如上两图 js涉及到跨域 jt-web---->jt-sso
复习跨域之间的知识 先从江哥文档 再到自己的