乐趣区

关于java:京淘Day18

1.Dubbo

1.1Dubbo 介绍

Apache Dubbo 是一款高性能, 轻量级的开源 java RPC 框架, 它提供三大外围能力: 面向接口的近程办法调用, 智能容错和负载平衡, 以及服务主动注册和发现.

1.2Dubbo 的特点

2Dubbo 入门案例

2.1 定义公共接口我的项目

阐明: 接口我的项目个别定义公共局部, 并且被第三方依赖.

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.2 服务消费者介绍

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 入门案例测试

2.4 对于 Dubbo 框架知识点

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

因为 ZK 的帮忙, 使得程序能够永远拜访正确的服务器, 并且当服务重启时,dubbo 有服务的主动发现性能, 消费者不须要重启既能够拜访新的服务.

2.4.2 问题 2: 如果 ZK 集群短时间宕机, 用户拜访是否受限?

用户拜访不受影响, 因为消费者在本地贮存服务列表信息, 当拜访故障机, 主动将标识信息改为 down 属性.

2.5Dubbo 负载平衡策略

2.5.1 负载平衡品种

1. 客户端负载平衡
Dobbo/SpringCloud 等微服务框架

2. 服务端负载平衡
阐明: 客户端发动申请后, 必须由对立的服务器进行负载平衡, 所有的压力都在服务器之中.
NGINX

2.5.2Dubbo 负载平衡形式

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

}

京淘我的项目 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.1URL 剖析

阐明: 依据 url 地址阐明申请为同域申请

参数信息

4.1.2 页面 JS 剖析

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.2SSO

单点登录 (SingleSignOn,SSO),就是通过用户的一次性甄别登录。当用户在身份认证服务器上登录一次当前,即可取得拜访单点登录零碎中其余关联系统和应用软件的权限,同时这种实现是不须要管理员对用户的登录状态或其余信息进行批改的,这意味着在多个利用零碎中, 用户只需一次登录就能够拜访所有相互信任的利用零碎。这种形式缩小了由登录产生的工夫耗费,辅助了用户治理,是目前比拟风行的 .

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 页面成果展示

退出移动版