1.Dubbo框架介紹
1.1 Dubbo框架通訊的方式
說明:只要使用Dubbo框架 ,在內部使用了dubbo協議進行通訊,其中的IP地址是動態生成的.并且埠號是訪問服務的唯一標識資訊.

1.2 ZK存盤資料的結構
說明:zk中的資料的存盤的方式是樹形結構的.一般三級.

1.3 關于負載均衡的說明
1.3.1 集中式的負載均衡
說明:由于nginx處于負載均衡的中心,所以什么樣的服務都會經過nginx之后轉向到不同的服務器中. 所以會造成nginx的負載壓力很大.
nginx的主要的作用是反向代理.

1.3.2 客戶端的負載均衡
說明:在微服務呼叫程序中每個服務的消費者都可以在客戶端實作負載均衡的操作,在每次請求之前通過服務串列獲取將要訪問的服務資訊.實作了壓力私有化.

1.3.3 Dubbo負載均衡的方式
名稱都是類名的前半部分都小寫即可.
1.RandomLoadBalance 隨機負載均衡 語法: random 默認的
2.RoundRobinLoadBalance 輪詢策略 語法: roundrobin
3.ConsistentHashLoadBalance 一致性hash演算法 將消費者與服務提供者系結 語法: consistenthash
4.LeastActiveLoadBalance 挑選負載壓力小的服務器進行訪問 語法: leastactive

2 京淘專案Dubbo改造
2.1 改造計劃
1.jt-common充當介面專案
2.jt-sso 充當用戶的提供者 服務埠號20880 服務名稱 provider-sso 介面DubboUserService
3.jt-web 充當用戶的消費者
2.2 匯入Dobbu jar包
<!--引入dubbo配置 -->
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>0.2.0</version>
</dependency>
2.3 編輯Dubbo介面
說明:在jt-common中添加Dubbo的業務介面

2.4 編輯jt-sso的服務提供者
2.4.1 編輯Service實作類

2.4.2 編輯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的支持
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的包路徑
application: #應用名稱
name: provider-sso #一個介面對應一個服務名稱
registry: #zk集群 主機中的資訊與從機中的資訊一致的 從zk中獲取資料的時候鏈接的從機 主機的作用就是監控集群
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 #每一個服務都有自己特定的埠 不能重復.
2.5 編輯服務消費者
2.5.1 編輯UserController
注入UserService注解

2.5.2 編輯YML組態檔
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 用戶模塊實作
3.1 用戶注冊
3.1.1 頁面分析


3.1.2 頁面JS分析
說明:根據頁面url地址 查找頁面JS的位置

3.1.3 編輯UserController
/**
* 完成用戶注冊操作.
* url地址: http://www.jt.com/user/doRegister
* 引數: {password:_password,username:_username,phone:_phone}
* 回傳值: SysResult物件 回傳的是JSON串
* 業務說明:通過dubbo框架將user資訊RPC傳入jt-sso實作資料的入庫操作.
* */
@RequestMapping("/doRegister")
@ResponseBody
public SysResult saveUser(User user){
dubboUserService.saveUser(user);
return SysResult.success();
}
3.1.4 編輯UserService
package com.jt.service;
import com.alibaba.dubbo.config.annotation.Service;
import com.jt.mapper.UserMapper;
import com.jt.pojo.User;
import com.jt.vo.SysResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;
@Service //dubbo的注解
public class DubboUserServiceImpl implements DubboUserService{
@Autowired
private UserMapper userMapper;
/**
* 1.郵箱暫時使用電話號碼代替
* 2.需要將密碼進行加密處理 md5/md5-hash
* @param user
* @return
*/
@Override
@Transactional
public void saveUser(User user) {
//1.獲取明文
String password = user.getPassword();
//2.利用Spring的工具API進行加密操作
password = DigestUtils.md5DigestAsHex(password.getBytes());
user.setPassword(password).setEmail(user.getPhone());
userMapper.insert(user);
}
}
3.1.4 關于POJO轉化例外說明
報錯說明: 由于SpringBoot配置了熱部署的工具,當代碼進行修改之后,程式就會重新啟動. 在重啟的程序中程式又會再次鏈接zookeeper注冊中心.由于zk的心跳檢測機制存在超時時間,可能在zk中會出現2條一模一樣的服務的提供者的資訊.
解決方案: 需要手動的重啟服務器即可.

3.2 單點登錄實作策略
3.2.1 需求說明
要求用戶只需要登錄一次,那么就可以訪問其他的認證系統,無需用戶再次登錄.
如果采用如下的配置,則必然會出現用戶頻繁登錄的現象.

3.2.2 SSO介紹
單點登錄(SingleSignOn,SSO),就是通過用戶的一次性鑒別登錄,當用戶在身份認證服務器上登錄一次以后,即可獲得訪問單點登錄系統中其他關聯系統和應用軟體的權限,同時這種實作是不需要管理員對用戶的登錄狀態或其他資訊進行修改的,這意味著在多個應用系統中,用戶只需一次登錄就可以訪問所有相互信任的應用系統,這種方式減少了由登錄產生的時間消耗,輔助了用戶管理,是目前比較流行的 一種登錄方式
3.2.3 單點登錄實作策略

步驟:
1.當用戶輸入用戶名和密碼時需要將資料傳遞給jt-web服務器進行登錄操作.
2.jt-web服務器需要將資料傳到jt-sso服務器中進行資料的校驗.
3.jt-sso根據username/password查詢資料庫校驗資料是否有效.
4.如果用戶名和密碼正確則將資料經過處理之后保存到redis中 KEY=UUID(每次生成的都不一樣) VALUE=“userJSON”
5.如果用戶寫入redis成功,之后需要將用戶的登錄的憑證回傳給客戶端.
6.JT-WEB服務器將獲取的TICKET資訊保存到客戶端的Cookie中,方便下次使用. 并且要求cookie共享的.
3.3 用戶登錄具體實作
3.3.1 用戶登錄頁面分析
1.url分析

2.引數分析

3.頁面JS分析
$.ajax({
type: "POST",
url: "/user/doLogin?r=" + Math.random(),
contentType: "application/x-www-form-urlencoded; charset=utf-8",
data: {username:_username,password:_password},
dataType : "json",
error: function () {
$("#nloginpwd").attr({ "class": "text highlight2" });
$("#loginpwd_error").html("網路超時,請稍后再試").show().attr({ "class": "error" });
$("#loginsubmit").removeAttr("disabled");
$this.removeAttr("disabled");
},
success: function (result) {
//如果資料不為null時執行
if (result) {
var obj = eval(result);
if (obj.status == 200) {
obj.success = "http://www.jt.com";
.....
3.3.2 編輯UserController
/**
* 完成用戶的登錄操作
* url地址:http://www.jt.com/user/doLogin?r=0.8989367429030823
* 引數: username/password
* 回傳值: SysResult物件 的JSON的資料.
*
* cookie.setMaxAge(-1); 關閉瀏覽器會話時洗掉
* cookie.setMaxAge(0); 立即洗掉cookie
* cookie.setMaxAge(100); cookie可以存盤的時間單位是秒
*
* http://www.jt.com/saveUser/xxx
* cookie.setPath("/");
* cookie.setPath("/add");
*/
@RequestMapping("/doLogin")
@ResponseBody
public SysResult doLogin(User user, HttpServletResponse response){
//1.實作用戶的登錄操作!!!
String ticket = dubboUserService.doLogin(user);
//2.校驗ticket是否有值.
if(StringUtils.isEmpty(ticket)){
//用戶名或者密碼錯誤
return SysResult.fail();
}
//3.如果用戶的ticket不為null,則表示登錄正確,需要將資料保存到cookie中
//Cookie要求 1.7天有效 2.要求cookie可以在jt.com的域名中共享 3.cookie權限 /
Cookie cookie = new Cookie("JT_TICKET",ticket);
cookie.setMaxAge(7*24*3600);
cookie.setDomain("jt.com"); //在jt.com中實作頁面共享.
cookie.setPath("/"); //定于cookie的權限根目錄有效
response.addCookie(cookie); //利用response將cookie保存到客戶端中.
return SysResult.success();
}
3.3.3 編輯UserServiceImpl
/**
* 1.根據用戶名和密碼查詢資料庫
* 2.校驗用戶資料的有效性.
* 3.如果用戶的資料是正確的 則開始進行單點登錄操作.
* 4.如果用戶資料不正確 則ticket資料為null即可.
* @param user
* @return
*/
@Override
public String doLogin(User user) {
//1.將密碼進行加密處理
String password = DigestUtils.md5DigestAsHex(user.getPassword().getBytes());
user.setPassword(password);
//如果傳遞的是物件,則根據物件中不為null的屬性充當where條件
QueryWrapper<User> queryWrapper = new QueryWrapper<>(user);
User userDB = userMapper.selectOne(queryWrapper);
//2.校驗資料是否有效
if(userDB == null){
return null;
}
//userDB資料不為null,用戶的輸入資訊正確.開啟單點登錄操作.
//3.1動態生成uuid
String ticket = UUID.randomUUID().toString().replace("-", "");
//3.2脫敏處理
userDB.setPassword("123456你信不??");
String userJSON = ObjectMapperUtil.toJSON(userDB);
//3.3 將資料保存到redis中
jedisCluster.setex(ticket, 7*24*60*60, userJSON);
return ticket;
}
3.3.4 資料校驗

3.4 用戶登錄回顯
3.4.1 用戶資訊回顯說明
當用戶登錄成功之后會生成COOKIE資訊.根據cookie獲取TICKET資訊,之后根據ticket獲取user資訊,.之后在首頁展現用戶名稱即可.

3.4.2 頁面分析
1).頁面url分析

2).頁面JS分析

3.4.3 編輯JT-SSO UserController
/**
* 根據ticket資訊查詢用戶的json資訊 jsonp請求 回傳值使用特定的物件封裝.
* url地址:http://sso.jt.com/user/query/ca620491866a42e596b29ee52fc27aff?callback=jsonp1600333068471&_=1600333068521
*/
@RequestMapping("/query/{ticket}")
public JSONPObject findUserByTicket(@PathVariable String ticket, HttpServletResponse response,
String callback){
if(jedisCluster.exists(ticket)){
//可以正確回傳
String userJSON = jedisCluster.get(ticket);
return new JSONPObject(callback, SysResult.success(userJSON));
}else{
//如果根據ticket查詢有誤,則應該洗掉Cookie資訊.
Cookie cookie = new Cookie("JT_TICKET","");
cookie.setDomain("jt.com");
cookie.setPath("/");
cookie.setMaxAge(0);
response.addCookie(cookie);
return new JSONPObject(callback, SysResult.fail());
}
}
作業
1: 完成退出操作
1.要求當用戶點擊退出按鈕時 應該重定向到系統的首頁
2.洗掉Redis中的資料
3.洗掉Cookie中的資料.
2.將用戶模塊的代碼重新構建一遍
3.預習SpringMVC中的攔截器機制
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/82339.html
標籤:其他
上一篇:救救孩子,哪里錯了怎么改
下一篇:有關廣義定積分的問題
