最近开始研究系统设计,本想着提升能力用在年后面试上,现在面试机会还没有…算了,先跟大家分享一些学习心得。

这是我总结的关于用户登录系统时需要了解的内容及设计方案(带案例及练手项目),详情也可以移步《系统架构设计 System Design》

首先,单点登录是指在多系统应用群中登录一个系统时,无需从其他系统中得到授权即可做到再次登录的过程。他的解决方案的核心是cookie。是实现session的一种方式。

所以在了解登录系统之前,应该先去了解cookie,session,单点登录SOS。

一、se·ssion

session存在于服务器上,通过他我们可以知道客户端的会话状态,用于标识用户。

当服务器创建了一个 Session 时,给客户端发送的响应报文包含了 Set-Cookie 字段,其中有一个名为 sid 的键值对,这个键值对就是 Session ID。客户端收到后就把 Cookie 保存在浏览器中,并且之后发送的请求报文都包含 Session ID

但他也有两个小缺陷:一个是在集群模式下需要进行同步转移,另一个是会大量消耗服务器内存。

二、session设计

正因为session会消耗服务器内存,为了解决这个问题,可以把sessionId存放在redis中作为token,流程图如下:

用户登录mysql 用户登录系统_用户登录mysql

三、cookie

cookie实际上是一段文本信息,浏览器可以通过用户请求时的同一网址连接的cookie,来查找和辨认用户状态。

我们经常看到的【下次自动登录】选项,就是根据这个原理来实现的。

四、cookie设计

cookie的关键性是保证信息的安全性,这里需要对token进行加密。

用户登录mysql 用户登录系统_高并发_02

五、代码实现

大型网站能实现的免密登录,用代码如何实现,这里提供一个案例,给大家交流参考:
以登录豆瓣为例,一般有两种方法实现

1、将登录成功的 cookie 写入到本地文件

#实例化一个 LWPCookieJar 对象,并设置保存 cookie 的文件
session = requests.session()
session.cookies = LWPCookieJar(filename=‘DouBanCookies.txt’)
复制代码

在使用代码登录成功之后,使用 session.save() 将自动将 cookie 写入到设置的 cookie 文件中

def login(): 
    name = input("输入账户:") 
    password = input("输入密码:") 
    url = "https://accounts.douban.com/j/mobile/login/basic" 
    data = { 
        "ck": "", 
        "name": name, 
        "password": password, 
        "remember": "True", 
        "ticket": "", 
    } 
    response = session.post(url, data=data) 
    print(response.text) 
    session.cookies.save()  # 保存 cookie

2、直接使用该文件中的 cookie 实现免密码登录

直接使用 load 方法,从文件中获取 cookie 到代码中。其中 load 方法有两个可选值,ignore_discard 主要是忽略关闭浏览器丢失, ignore_expires 是忽略 cookie 失效。可根据自己的实际场景自由选择。

session.cookies.load(ignore_discard=True)
复制代码

使用 cookie 登录之后,可以自主验证一下是否登录成功。一般选择访问个人主页,查看响应内容,判读是否登录成功。完整代码如下:

#coding: utf-8 
import requests 
from scrapy import Selector 
from http.cookiejar import LWPCookieJar 
 
session = requests.session() 
headers = { 
        "User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36" 
    } 
session.headers = headers 
session.cookies = LWPCookieJar(filename='DouBanCookies.txt')  # 实例化一个LWPCookieJar对象 
 
def login(): 
    name = input("输入账户:") 
    password = input("输入密码:") 
    url = "https://accounts.douban.com/j/mobile/login/basic" 
    data = { 
        "ck": "", 
        "name": name, 
        "password": password, 
        "remember": "True", 
        "ticket": "", 
    } 
    response = session.post(url, data=data) 
    print(response.text) 
    session.cookies.save() 
    verify_login() 
 
def verify_login(): 
    mine_url = "https://www.douban.com/mine/" 
    mine_response = session.get(mine_url) 
    selector = Selector(text=mine_response.text) 
    user_name = selector.css(".info h1 ::text").extract_first("") 
    print(f"豆瓣用户名:{user_name.strip()}") 
...

四、单点登录SOS

1、登录
1.用户访问系统1的受保护资源,系统1发现用户未登录,跳转至sso认证中心,并将自己的地址作为参数
2.sso认证中心发现用户未登录,将用户引导至登录页面(带系统1地址)
3.用户输入用户名密码提交登录申请
4.sso认证中心校验用户信息,创建用户与sso认证中心之间的会话,称为全局会话(这时该会话信息保存到cookie中),同时创建授权令牌 5.sso认证中心带着令牌跳转到最初的请求地址(系统1)
6.系统1拿到令牌,去sso认证中心校验令牌是否有效
7.sso认证中心校验令牌,返回有效,注册系统1
8.系统1使用该令牌创建与用户的会话,称为局部会话(seesion),返回受保护资源 9.用户访问系统2的受保护资源
10.系统2发现用户未登录,跳转至sso认证中心,并将自己的地址和之前和sso认证中心的会话cookie信息作为参数
11.sso认证中心发现用户已登录,跳转回系统2的地址,并附上令牌
12.系统2拿到令牌,去sso认证中心校验令牌是否有效
13.sso认证中心校验令牌,返回有效,注册系统2
14.系统2使用该令牌创建与用户的局部会话,返回受保护资源

2、注销

1.用户向系统1发起注销请求
2.系统1根据用户与系统1建立的会话id拿到令牌,向sso认证中心发起注销请求
3.sso认证中心校验令牌有效,销毁全局会话,同时取出所有用此令牌注册的系统地址
4.sso认证中心向所有注册系统发起注销请求
5.各注册系统接收sso认证中心的注销请求,销毁局部会话
6.sso认证中心引导用户至登录页面

五、分享含金量较高的系统设计类项目

1、Twitter 后端系统 - Django 项目实战

设计Twitter本质上就是在考高并发的信息流系统,其涉及的技术难点非常多,项目的难度也更能检验面试者水平,而且从L3~L5都能问到。

用户登录mysql 用户登录系统_System Design_03

  • 对于初级程序员(SDE1),可以把“设计Twitter”拆解出单独设计一个关注功能来问
  • 对于高级程序员(SDE2+),面试官通常会要求面试者实现设计登陆、发推、点赞、关注、取关等一系列功能

这些技术难点在《Twitter后端系统 - Django项目实战》首节试听课中都有详细介绍,目前还能免费试听,感兴趣的可以体验一下。

2、电商秒杀系统:双十一购物秒杀

这是一个典型的秒杀系统遇到高并发的情况。借此项目可以深度学习高并发、高性能架构设计和技术方法。

用户登录mysql 用户登录系统_高并发_04

对应的秒杀业务流程如下:

1、数据库Mysql

2、持久层框架

3、基础框架:Springboot+Spring MVC

4、缓存中间件:Redis

5、消息中间件:RocketMQ

6、分布式唯一ID生成:雪花算法

7、流量控制框架:Sentinel

8、压力测试工具:Jmeter

如果遇到不会的技术点,最快的方式就是通过《电商秒杀系统 - Spring项目实战》学习。课程是由阿里巴巴技术部门架构师欧阳修讲解,覆盖Redis、缓存预热、防爬虫和黄牛恶意请求,乐观锁等技术。能在2周内快速完成秒杀项目。

课程还十分自信地开放了首节免费试听,会带大家了解秒杀系统实现的全流程、秒杀系统的重难点等,需要的朋友可以去体验看看~

3、AutoLoadCache

AutoLoadCache是基于AOP + Annotation等技术实现的高效的缓存管理解决方案,实现缓存与业务逻辑的分解,并增加了异步刷新和“拿来主义机制”,以适应高并发环境下的使用。

用户登录mysql 用户登录系统_用户登录mysql_05

4、springboot-seckill

本系统是使用SpringBoot开发的高并发限时抢购秒杀系统,除了实现基本的登录、查看商品列表、秒杀、下单等功能,项目中还针对高并发情况实现了系统缓存、降级和限流。

用户登录mysql 用户登录系统_高并发_06

有两个优化方向
1.将请求尽量拦截在系统上游:可以通过限流、降级等措施来最大化减少对数据库的访问,从而保护系统。
2.充分利用缓存:秒杀商品是一个典型的读多写少的应用场景,充分利用缓存将大大提高并发量

5、系统架构设计 System Design

如果希望在学会更多核心项目的同时,应对面试,追求去更大的公司工作的话,可以来体验下系统架构设计 System Design 。

在应对面试官可能提出的问题时,常见的错误是面试官给出问题后,候选人就开始怼各种关键词,什么Load Balancer,Memcache,NodeJS,MongoDB,MySQL……

实际上,针对系统设计问题,九章算法有一套4S分析法,即使完全不知道的问题也可以按照这个方法一步步去回答。

所谓4S分析法中的4S是指Scenario(场景)Service(服务)Storage(存储)Scale(扩展)

用户登录mysql 用户登录系统_系统设计_07

第一节的免费试听课程就会讲到设计Twitter和系统设计的通用解题法则,不妨去感受一下,简单入个门。