SpringBoot part4 day17

电脑启动顺序:
1 检查linux中防火前状态 firewall-cmd --state;
2 启动电脑,在dos中键入services.msc,将vmware所有相关类容打开,将数据库打开;
3 启动虚拟机,将虚拟机中Zookeeper文件都打开;启动redis集群;
4 运行idea,测试程序访问是否成功。
zookeeper 程序结构
rpc调用速度特别快,但有时候后台服务器繁忙,导致返回错误信息,所以在生产者的service实现类注解上加上超时时间
提供者:service实现类 以及mapper文件 启动项 yml(有tomcat端口号和dubbo端口号)
在这里插入图片描述

消费者:controller 启动项 yml(没有数据库连接)
在这里插入图片描述

接口: service接口 pojo

其中provider和interface是继承关系

1 Dubbo框架优势

1.1问题说明

问题1 服务的生产者有一个宕机,问程序是否正常运行???
说明:由于dubbo框架的机制,依然可以保证正常运行(心跳检测机制,标识为down)

问题2 如果整个zk集群宕机,问程序是否正常运行???
在这里插入图片描述
说明1:如果只是主机宕机,程序有高可用机制(myid优先 ),程序访问不受影响
说明2:如果整合zk集群宕机,用户依然可以正常访问,消费者本地同步了数据,但是现在的程序处于危险状态
说明3:如果在上述的情况下,再次宕机一台生产者,程序依然可以正常运行, 因为维护了本地的服务列表信息.

2 Dubbo负载均衡机制

2.1负载均衡种类

说明:dubbo框架中负载均衡机制是客户端负载均衡机制,该配置需要在客户端(消费者)中配置即可
2.1.1 负载均衡的配置
在这里插入图片描述
在这里插入图片描述

1.随机策略

在这里插入图片描述
在这里插入图片描述

2 .轮询机制

在这里插入图片描述

在这里插入图片描述

3 一致性hash

在这里插入图片描述
实现了客户端与服务器的绑定
在这里插入图片描述

4 最近最少使用

在这里插入图片描述
在这里插入图片描述
数据在ZK中的存储结构
进入zk的客户端
在这里插入图片描述
检索 ls /
在这里插入图片描述
在这里插入图片描述理解:
在这里插入图片描述
在这里插入图片描述
以树形结构存储,根目录下有dubbo和zookeeper自身配置,dubbo中存多个接口,每个接口一个目录,每个接口中有自己的生产者和消费者以及配置

3 jt项目重构

说明:
将jt-common当成接口项目,jt-sso为生产者,jt-web为消费者

3.1导入jar包

<!--引入dubbo配置 -->
       <dependency>
            <groupId>com.alibaba.boot</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>0.2.0</version>
        </dependency>

3.2在jt-common中准备接口

在这里插入图片描述
准备四个接口
在这里插入图片描述

3.3 定义服务生产者

在这里插入图片描述
在这里插入图片描述

#关于Dubbo配置
dubbo:
  scan:
    basePackages: com.jt    #指定dubbo的包路径
  application:              #应用名称
    name: provider-user     #一个接口对应一个服务名称
  registry:
    address: zookeeper://192.168.126.129:2181?backup=192.168.126.129:2182,192.168.126.129:2183
  protocol:  #指定协议
    name: dubbo  #使用dubbo协议(tcp-ip)  web-controller直接调用sso-Service
    port: 20880  #每一个服务都有自己特定的端口 不能重复.


3.4服务消费者

在这里插入图片描述
修改配置文件

dubbo:
  scan:
    basePackages: com.jt
  application:
    name: consumer-user   #定义消费者名称
  registry:               #注册中心地址
    address: zookeeper://192.168.126.129:2181?backup=192.168.126.129:2182,192.168.126.129:2183

在这里插入图片描述

4 完成jt单点登陆业务实现

4.1 用户注册实现

4.1.1业务需求说明

在这里插入图片描述
4.1.2页面的分析
ctrl+h
在这里插入图片描述

$.ajax({
			type : "POST",
			url : "/user/doRegister",
			contentType : "application/x-www-form-urlencoded; charset=utf-8",
			data : {password:_password,username:_username,phone:_phone},
			dataType : 'json',
			success : function(result) {
				if(result.status == "200"){
					// 注册成功,去登录页
					showMessage('注册成功,请登录!');
					verc();
					$("#registsubmit").removeAttr("disabled").removeClass()
							.addClass("btn-img btn-regist");
					isSubmit = false;
					return;
				}else{
					showMessage('注册失败,请联系管理员!');
					//alert('注册失败,请重新注册!   ' + result.data );
				}

编辑消费者的userController
在这里插入图片描述
生产者DubboUserServiceImpl

package com.jt.service;

import com.alibaba.dubbo.config.annotation.Service;
import com.jt.mapper.UserMapper;
import com.jt.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;

@Service(timeout = 3000)
@Transactional
public class DubboUserServiceImpl implements DubboUserService{
    @Autowired
    private UserMapper userMapper;

     /**
      * 业务:
      * 1.将密码进行加密处理
      * 2.邮箱暂时用电话代替
      * */
    @Override
    public void saveUser(User user) {
        byte[] bytes=user.getPassword().getBytes();
       String md5Pass= DigestUtils.md5DigestAsHex(bytes);
       user.setPassword(md5Pass).setEmail(user.getPhone());
       userMapper.insert(user);

    }
}

热部署原因:
热部署太快导致注册了两个一模一样的信息
在这里插入图片描述
解决方案:重启服务器

4.2 单点登陆系统

4.2.1业务需求
要求: 用户只需要登录一次,则可以在任意的服务器享受免密登录.有效期为30天.

sso介绍:
单点登录(SingleSignOn,SSO),就是通过用户的一次性鉴别登录。当用户在身份认证服务器上登录一次以后,即可获得访问单点登录系统中其他关联系统和应用软件的权限,同时这种实现是不需要管理员对用户的登录状态或其他信息进行修改的,这意味着在**多个应用系统中,用户只需一次登录就可以访问所有相互信任的应用系统。**这种方式减少了由登录产生的时间消耗,辅助了用户管理,是目前比较流行的 [1]
4.2.2 单点登录实现原理
在这里插入图片描述
单点登录实现步骤:
1.用户通过用户名和密码访问jt-web服务器.
2.JT-WEB服务器通过JT-SSO校验用户名和密码是否正确.
3.如果用户名和密码正确,则将数据保存到redis中. TICKET密钥:USERJSON,之后将密钥返回给用户即可.
4.JT-WEB服务器将密钥信息保存到用户的Cookie中 并且设定Cookie的共享/有效时间.
4.2.3 登录页面分析
1).url分析
在这里插入图片描述
2).参数分析
在这里插入图片描述
3).页面JS
在这里插入图片描述
4.2.4编辑UserController

/**
     *  业务需求:
     *       实现用户单点登录操作
     *       1.url地址:http://www.jt.com/user/doLogin?r=0.43530970885614617
     *       2.请求参数:  username: asdasdfas
     *                    password: asdfasdfa
     *       3.返回值结果: SysResult对象
     *
     *  实现Cookie数据的存储
     * 1.获取用户名和密码进行数据校验
     * 2.获取后端的密钥信息   是否非空
     * 3.如果一切正常,则将数据存储到Cookie中   路径/有效期/共享问题
     *
     *   关于Cookie说明:
     *       1 cookie只能看到自己域名下的cookie   cookie是私有的
     *       2 setPath  说明:
     *                 setPath("/")  读取cookie权限的设定,根目录中的请求,读取cookie
     *                 setPath("/user") ur地址路径/user下时才能读取cookie信息
     *         url1: http://www.jt.com/findAll
     *
     *         url2: http://www.jt.com/user/findAll
     * */
    @RequestMapping("/doLogin")
    public SysResult doLogin(User user, HttpServletResponse response){
        String ticket="123";//userService.findUserByUP(user);
        if(!StringUtils.hasLength(ticket)){
            //如果数据为null则表示用户名和密码错误
          return SysResult .fail();
        }
        //需要将数据存储到cookie
        Cookie cookie=new Cookie("JT_TICKET", ticket);
        cookie.setPath("/");
        //cookie单位是秒
        cookie.setMaxAge(7*24*60*60);//设置有效期  7天有效
        cookie.setDomain("jt.com");//设置共享   只要域名中有jt.com则可以数据共享
        response.addCookie(cookie);//将数据写入到客户端
        return SysResult.success();

    }

查看cookie的方法,只能看到当前页面的cookie
在这里插入图片描述
实现cookie数据的共享
在这里插入图片描述

 //restFul风格只能在get请求中使用,post提交的方式不能使用

    /**
     *  业务需求:
     *       实现用户单点登录操作
     *       1.url地址:http://www.jt.com/user/doLogin?r=0.43530970885614617
     *       2.请求参数:  username: asdasdfas
     *                    password: asdfasdfa
     *       3.返回值结果: SysResult对象
     *
     *  实现Cookie数据的存储
     * 1.获取用户名和密码进行数据校验
     * 2.获取后端的密钥信息   是否非空
     * 3.如果一切正常,则将数据存储到Cookie中   路径/有效期/共享问题
     *
     *   关于Cookie说明:
     *       1 cookie只能看到自己域名下的cookie   cookie是私有的
     *       2 setPath  说明:
     *                 setPath("/")  读取cookie权限的设定,根目录中的请求,读取cookie
     *                 setPath("/user") ur地址路径/user下时才能读取cookie信息
     *         url1: http://www.jt.com/findAll
     *
     *         url2: http://www.jt.com/user/findAll
     * */
    @RequestMapping("/doLogin")
    @ResponseBody
    public SysResult userLogin(User user, HttpServletResponse response){
        String ticket = userService.findUserByUP(user);
        if(!StringUtils.hasLength(ticket)){
            //如果数据为null则表示用户名和密码错误...
            return SysResult.fail();
        }

        //需要将数据保存到cookie中
        Cookie cookie = new Cookie("JT_TICKET", ticket);
        cookie.setPath("/");
        cookie.setMaxAge(7*24*60*60); //设定有效期 7天有效 单位秒
        cookie.setDomain("jt.com");   //主要域名中由jt.com则可以共享数据
        response.addCookie(cookie);   //将数据写入客户端
        return SysResult.success();
    }
package com.jt.service;

import com.alibaba.dubbo.config.annotation.Service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jt.mapper.UserMapper;
import com.jt.pojo.User;
import com.jt.util.ObjectMapperUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;
import redis.clients.jedis.JedisCluster;
import sun.security.provider.MD5;

import java.util.UUID;

@Service
public class DubboUserServiceImpl implements DubboUserService{

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private JedisCluster jedisCluster;

    /**
     * 业务:
     *  1.将密码进行加密处理
     *  2. 邮箱暂时用电话代替
     * @param user
     */
    @Override
    public void saveUser(User user) {

        byte[] bytes = user.getPassword().getBytes();
        //利用Spring工具API进行加密操作
        String md5Pass = DigestUtils.md5DigestAsHex(bytes);
        user.setPassword(md5Pass).setEmail(user.getPhone());
        userMapper.insert(user);
    }

    /**
     * 1.校验用户名和密码是否正确  不存在直接返回null
     * 2.动态生成密钥   将用户信息转化为JSON
     * 3.将数据保存到redis中 7天有效.
     * 4.返回密钥ticket信息.
     * @param user
     * @return
     */
    @Override
    public String findUserByUP(User user) {
        String md5Pass =
                DigestUtils.md5DigestAsHex(user.getPassword().getBytes());
        user.setPassword(md5Pass);
        //1.根据对象中不为null的属性当做where条件
        QueryWrapper<User> queryWrapper = new QueryWrapper<>(user);
        User userDB = userMapper.selectOne(queryWrapper);

        //2.判断对象是否有值
        if(userDB==null){
            return null;
        }

        //3.表示用户名和密码正确 开启单点登录操作
        String ticket = UUID.randomUUID()
                .toString().replace("-", "");
        //转化之前应该将数据进行脱敏处理
        userDB.setPassword("123456");
        String userJSON = ObjectMapperUtil.toJSON(userDB);

        //4.将数据保存到redis中
        jedisCluster.setex(ticket, 7*24*60*60, userJSON);
        return ticket;
    }
}

4.3用户数据回显

4.3.1业务分析
如果用户登录成功之后,则通过cookie数据利用JSONP跨域方式,实现数据的动态获取
4.3.2页面URL分析
1).页面URL分析
在这里插入图片描述
2)检查页面JS
在这里插入图片描述

数据格式的转化:
json格式转过去有斜杠:
在这里插入图片描述
处理方法1:

在这里插入图片描述
处理方法2:在后端传的时候传对象
4.3.3 编辑JT_SSO UserController

/**
     * 跨域请求:完成用户信息获取
     * URL网址:  http://sso.jt.com/user/query/dca70b16a1c54aea9ebb0b27621250de?callback=jsonp1608021961735&_=1608021961777
     * 参数:    参数1: ticket信息    参数2:callback
     * 返回值:   SysResult对象(用户数据......)
     */
    @RequestMapping("/query/{ticket}")
    public JSONPObject findUserByTicket(@PathVariable String ticket,
                                        String callback){
        //如何获取用户信息?  从redis中获取数据
        if(jedisCluster.exists(ticket)){
            String userJSON = jedisCluster.get(ticket);
            SysResult sysResult = SysResult.success(userJSON);
            return new JSONPObject(callback, sysResult);
        }else{
            return new JSONPObject(callback, SysResult.fail());
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值