第三階段 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 頁面效果展示

在這裏插入圖片描述

相關文章
相關標籤/搜索