公司的 C 端用户中心,入口流量极大。 有两个接口,都是修改的用户的某个信息,在高并发下,出现了一点问题。 A 用户有两个属性,名字和年龄,接口 a 修改了名字,接口 b 修改了职业,但是一旦并发执行,总会有一个修改失败,这个失败的频率还很高。 之前并发量不高的时候,这个是没有问题的,并发量一起来,这个问题就是很严重的了。 初步判定,是锁的问题了。
from flask import Flask, request, jsonify from sqlalchemy import create_engine from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import Column, Integer, String from sqlalchemy.orm import sessionmaker
class(Base): __tablename__ = "tb_user" id = Column(Integer, primary_key=True, autoincrement=True) name = Column(String(64)) age = Column(Integer)
def(): session = Session() name = request.json.get("key") id = request.json.get("id") user = session.query(TbUser).filter_by(id=id).first() print(f"name origin {user.name}, new {name}") user.name = name session.add(session.merge(user)) session.commit() return""
@app.route("/user/age", methods=["PUT"]) defmodify_age(): session = Session() age = request.json.get("key") id = request.json.get("id") user = session.query(TbUser).filter_by(id=id).first() print(f"age origin {user.age}, new {age}") user.age = age session.add(session.merge(user)) session.commit() return""
我又细查了一下代码。 由于公司的 C 端用户量极大,于是架构上我们采纳了分库分表。 于是,这要求我们在 model 的建立上,需要极其抽象。 细剥这一部分的代码,然后发现了一个问题。 获取 user 的代码里面,单独获取了一次 session, 而保存 user 又获取了一次 session。基本确定问题出现在这里了。 这是,头脑也有了代码的基本运行模型了。 如下图所示:
from flask import Flask, request, jsonify from sqlalchemy import create_engine from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import Column, Integer, String from sqlalchemy.orm import sessionmaker
classTbUser(Base): __tablename__ = "tb_user" id = Column(Integer, primary_key=True, autoincrement=True) name = Column(String(64)) age = Column(Integer)
@app.route("/user/name", methods=["PUT"]) defmodify_name(): session = Session() name = request.json.get("key") id = request.json.get("id") user = session.query(TbUser).filter_by(id=id).first() session.close() print(f"name origin {user.name}, new {name}") user.name = name session = Session() session.add(session.merge(user)) session.commit() return""
@app.route("/user/age", methods=["PUT"]) defmodify_age(): session = Session() age = request.json.get("key") id = request.json.get("id") user = session.query(TbUser).filter_by(id=id).first() session.close() print(f"age origin {user.age}, new {age}") user.age = age session = Session() session.add(session.merge(user)) session.commit() return""