第三阶段 Day18 Dubbo 完成用户注册/单点登陆

  1. Dubbo

=========java

1.1 Dubbo介绍

Apache Dubbo |ˈdʌbəʊ| 是一款高性能、轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。
在这里插入图片描述mysql

1.2 Dubbo特色

在这里插入图片描述

2 Dubbo入门案例

2.1 定义公共接口项目

说明:接口项目通常定义公共的部分,而且被第三方依赖.
在这里插入图片描述nginx

2.2 服务提供者介绍

2.2.1 提供者代码结构

在这里插入图片描述

2.2.2 编辑实现类

`package com.jt.dubbo.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;

import com.alibaba.dubbo.config.annotation.Service;
import com.jt.dubbo.mapper.UserMapper;
import com.jt.dubbo.pojo.User;
@Service(timeout=3000)    //3秒超时 内部实现了rpc
//@org.springframework.stereotype.Service//将对象交给spring容器管理
public class UserServiceImpl implements UserService {
    
    @Autowired
    private UserMapper userMapper;
    
    @Override
    public List<User> findAll() {
        
        System.out.println("我是第一个服务的提供者");
        return userMapper.selectList(null);
    }
    
    @Override
    public void saveUser(User user) {
        
        userMapper.insert(user);
    }
}`

2.2.3 编辑提供者配置文件

`server:
  port: 9000   #定义端口

spring:
  datasource:
    #引入druid数据源
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/jtdb?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
    username: root
    password: root

#关于Dubbo配置   
dubbo:
  scan:
    basePackages: com.jt    #指定dubbo的包路径 扫描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  #每个服务都有本身特定的端口 不能重复.

      
mybatis-plus:
  type-aliases-package: com.jt.dubbo.pojo       #配置别名包路径
  mapper-locations: classpath:/mybatis/mappers/*.xml  #添加mapper映射文件
  configuration:
    map-underscore-to-camel-case: true                #开启驼峰映射规则`

2.3 服务消费者介绍

2.3.1 编辑Controller

`package com.jt.dubbo.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.dubbo.config.annotation.Reference;
import com.jt.dubbo.pojo.User;
import com.jt.dubbo.service.UserService;

@RestController
public class UserController {
    
    //利用dubbo的方式为接口建立代理对象 利用rpc调用
    @Reference
    private UserService userService; 
    
    /**
     * Dubbo框架调用特色:远程RPC调用就像调用本身本地服务同样简单
     * @return
     */
    @RequestMapping("/findAll")
    public List<User> findAll(){
        
        //远程调用时传递的对象数据必须序列化.
        return userService.findAll();
    }
    
    @RequestMapping("/saveUser/{name}/{age}/{sex}")
    public String saveUser(User user) {
        
        userService.saveUser(user);
        return "用户入库成功!!!";
    }
}`

2.3.2 编辑YML配置文件

`server:
  port: 9001
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`

2.3.3 Dubbo入门案例测试

在这里插入图片描述

2.4 关于Dubbo框架知识点

2.4.1 问题1:若是其中一个服务器宕机 用户访问是否受限?

答:因为zk的帮助,使得程序永远能够访问正确的服务器.而且当服务重启时,duboo有服务的自动发现功能,消费者不须要重启便可以访问新的服务.web

2.4.2 问题2:若是ZK集群短期宕机,用户访问是否受限?

答: 用户的访问不受影响,因为消费者在本地存储服务列表信息,当访问故障机时,自动的将标识信息改成down属性.redis

2.5 Dubbo负载均衡策略

2.5.1 负载均衡种类

1.客户端负载均衡
Dubbo/SpringCloud等微服务框架
在这里插入图片描述spring

2.服务端负载均衡
说明:客户端发起请求以后,必须由统一的服务器进行负载均衡,全部的压力都在服务器中.
NGINX
在这里插入图片描述sql

2.5.2 Dubbo负载均衡方式

`@RestController
public class UserController {
    
    //利用dubbo的方式为接口建立代理对象 利用rpc调用
    //@Reference(loadbalance = "random")            //默认策略  负载均衡随机策略
    //@Reference(loadbalance = "roundrobin")        //轮询方式
    //@Reference(loadbalance = "consistenthash")    //一致性hash  消费者绑定服务器提供者
    @Reference(loadbalance = "leastactive")            //挑选当前负载小的服务器进行访问
    private UserService userService; 

}`

3 京淘项目Dubbo改造

3.1 改造JT-SSO

3.1.1 添加jar包文件

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

3.1.2 建立DubboUserService接口

在这里插入图片描述

3.1.3 建立提供者实现类

在这里插入图片描述

3.1.3 编辑提供者YML配置文件

`server:
  port: 8093
  servlet:
    context-path: /
spring:
  datasource:
    #引入druid数据源
    #type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/jtdb?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
    username: root
    password: root

  mvc:
    view:
      prefix: /WEB-INF/views/
      suffix: .jsp
#mybatis-plush配置
mybatis-plus:
  type-aliases-package: com.jt.pojo
  mapper-locations: classpath:/mybatis/mappers/*.xml
  configuration:
    map-underscore-to-camel-case: true

logging:
  level: 
    com.jt.mapper: debug

#关于Dubbo配置
dubbo:
  scan:
    basePackages: com.jt    #指定dubbo的包路径 扫描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.1.4 启动服务提供者

测试Dubbo服务器启动是否正常.
在这里插入图片描述数据库

3.2 改造服务消费者JT-WEB

3.2.1 注入Service接口

在这里插入图片描述

3.2.2 编辑消费者配置文件

`server:
  port: 8092    
spring:     #定义springmvc视图解析器
  mvc:
    view:
      prefix: /WEB-INF/views/
      suffix: .jsp

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

3.2.3 启动效果测试

在这里插入图片描述

4.用户模块实现

4.1 用戶注册

4.1.1 URL分析

根据url地址说明请求为同域请求.
在这里插入图片描述
参数信息:
在这里插入图片描述json

4.1.2 页面JS分析

说明:根据分析获取返回值数据信息应该为SysResult对象
在这里插入图片描述服务器

4.1.3 编辑UserController

`/**
     * 需求: 实现用户信息注册
     * 1.url请求地址:  http://www.jt.com/user/doRegister
     * 2.请求参数:     {password:_password,username:_username,phone:_phone},
     * 3.返回值结果:   SysResult对象
     */
    @RequestMapping("/doRegister")
    @ResponseBody   //将数据转化为JSON
    public SysResult saveUser(User user){
        //消费者给予dubbo协议将user对象进行远程网络数据传输.
        userService.saveUser(user);
        return SysResult.success();
    }`

4.1.4 编辑UserService

`/**
     * 注意事项:
     *  1.暂时使用电话号码代替邮箱
     *  2.密码进行md5加密.
     *  3.入库操做注意事务控制
     * @param user
     */
    @Override
    public void saveUser(User user) {
        String md5Pass =
                DigestUtils.md5DigestAsHex(user.getPassword().getBytes());
        user.setEmail(user.getPhone())
            .setPassword(md5Pass);
        userMapper.insert(user);
    }`

4.1.5 页面效果展示

在这里插入图片描述

4.2 关于ZK数据存储结构

说明:在zk中数据的存储采用树形结构的方式保存
命令: [root@localhost bin]# sh zkCli.sh
查询命令: ls /…在这里插入图片描述

4.3 用户单点登陆原理介绍

4.3.1 传统方式登陆存在的问题

说明: 若是采用SESSION的方式实现用户的登陆操做,因为nginx负载均衡的策略,用户能够访问不一样的服务器.可是Session不能共享,因此致使用户频繁的登陆. 用户的体验很差.
在这里插入图片描述

4.3.2 SSO

单点登陆(SingleSignOn,SSO),就是经过用户的一次性鉴别登陆。当用户在身份认证服务器上登陆一次之后,便可得到访问单点登陆系统中其余关联系统和应用软件的权限,同时这种实现是不须要管理员对用户的登陆状态或其余信息进行修改的,这意味着在多个应用系统中,用户只需一次登陆就能够访问全部相互信任的应用系统。这种方式减小了由登陆产生的时间消耗,辅助了用户管理,是目前比较流行的 [1]

4.3.3 京淘项目单点登陆设计

在这里插入图片描述
实现步骤:
1.当用户输入用户名和密码点击登陆时,将请求发送给JT-WEB消费者服务器.
2.JT-WEB服务器将用户信息传递给JT-SSO单点登陆系统完成数据校验.
3.若是登陆成功,则动态生成密钥信息,将user数据转化为json.保存到redis中. 注意超时时间的设定.
4.JT-SSO将登陆的凭证 传给JT-WEB服务器.
5.JT-WEB服务器将用户密钥TICKET信息保存到用户的cookie中 注意超时时间设定.
6.若是登陆不成功,则直接返回错误信息便可.

4.4 用户单点登陆实现

4.4.1 页面url分析

在这里插入图片描述

4.4.2 页面参数分析

在这里插入图片描述

4.4.3 页面JS分析

在这里插入图片描述

4.4.4 编辑UserController

`/**
     * 完成用户登陆操做
     * 1.url地址: http://www.jt.com/user/doLogin?r=0.9309436837648131
     * 2.参数:    {username:_username,password:_password},
     * 3.返回值结果:  SysResult对象
     *
     * 4.Cookie:
     *   4.1 setPath("/")  path表示若是须要获取cookie中的数据,则url地址所在路径设定.
     *       url:http://www.jt.com/person/findAll
     *       cookie.setPath("/");   通常都是/
     *       cookie.setPath("/person");
     *   4.2 setDomain("xxxxx")  设定cookie共享的域名地址.
     */
    @RequestMapping("/doLogin")
    @ResponseBody
    public SysResult doLogin(User user, HttpServletResponse response){
        String ticket = userService.doLogin(user);
        if(StringUtils.isEmpty(ticket)){
            //说明用户名或者密码错误
            return SysResult.fail();
        }else{
            //1.建立Cookie
            Cookie cookie = new Cookie("JT_TICKET",ticket);
            cookie.setMaxAge(7*24*60*60);   //设定cookie存活有效期
            cookie.setPath("/");            //设定cookie有效范围
            cookie.setDomain("jt.com");     //设定cookie共享的域名 是实现单点登陆必备要素
            response.addCookie(cookie);
            return SysResult.success();     //表示用户登陆成功!!
        }
    }`

4.4.5 编辑UserService

`/**
     * 1.获取用户信息校验数据库中是否有记录
     * 2.有  开始执行单点登陆流程
     * 3.没有 直接返回null便可
     * @param user
     * @return
     */
    @Override
    public String doLogin(User user) {  //username/password
        //1.将明文加密
        String md5Pass =
                DigestUtils.md5DigestAsHex(user.getPassword().getBytes());
        user.setPassword(md5Pass);
        QueryWrapper<User> queryWrapper = new QueryWrapper<>(user);
        //根据对象中不为null的属性当作where条件.
        User userDB = userMapper.selectOne(queryWrapper);
        if(userDB == null){
            //用户名或密码错误
            return null;
        }else{ //用户名和密码正确  实现单点登陆操做
            String ticket = UUID.randomUUID().toString();
            //若是将数据保存到第三方 通常须要脱敏处理
            userDB.setPassword("123456你信不??");
            String userJSON = ObjectMapperUtil.toJSON(userDB);
            jedisCluster.setex(ticket, 7*24*60*60, userJSON);
            return ticket;
        }
    }`

4.4.5 页面效果展示

在这里插入图片描述

相关文章
相关标签/搜索