2006-京淘Day18

2020-10-22 01:00:01

1. Dubbo

1.1 Dubbo介紹

Apache Dubbo |ˈdʌbəʊ| 是一款高效能、輕量級的開源Java RPC框架,它提供了三大核心能力:面向介面的遠端方法呼叫,智慧容錯和負載均衡,以及服務自動註冊和發現。
在這裡插入圖片描述

1.2 Dubbo特點

在這裡插入圖片描述

2 Dubbo入門案例

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.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有服務的自動發現功能,消費者不需要重新啟動即可以存取新的服務.

2.4.2 問題2:如果ZK叢集短時間宕機,使用者存取是否受限?

答: 使用者的存取不受影響,由於消費者在本地儲存服務列表資訊,當存取故障機時,自動的將標識資訊改為down屬性.

2.5 Dubbo負載均衡策略

2.5.1 負載均衡種類

1.使用者端負載均衡
Dubbo/SpringCloud等微服務架構
在這裡插入圖片描述

2.伺服器端負載均衡
說明:使用者端發起請求之後,必須由統一的伺服器進行負載均衡,所有的壓力都在伺服器中.
NGINX
在這裡插入圖片描述

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地址說明請求為同域請求.
在這裡插入圖片描述
引數資訊:
在這裡插入圖片描述

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 頁面效果展現

在這裡插入圖片描述