挂面02

作者: 盼旺 | 来源:发表于2019-09-25 16:30 被阅读0次

    1.流量削峰这事应该怎么做

    1.一个是通过队列来缓冲请求,即控制请求的发出;
    2.一个是通过答题来延长请求发出的时间,在请求发出后承接请求时进行控制,最后再对不符合条件的请求进行过滤.(微信的“摇一摇”都是类似的方式)

    整个秒杀答题的逻辑主要分为3部分

    1、题库生成模块,这个部分主要就是生成一个个问题和答案,其实题目和答案本身并不需要很复杂,重要的是能够防止由机器来算出结果,即防止秒杀器来答题。

    2、题库的推送模块,用于在秒杀答题前,把题目提前推送给详情系统和交易系统。题库的推送主要是为了保证每次用户请求的题目是唯一的,目的也是防止答题作弊。

    3、题目的图片生成模块,用于把题目生成为图片格式,并且在图片里增加一些干扰因素。这也同样是为防止机器直接来答题,它要求只有人才能理解题目本身的含义。这里还要注意一点,由于答题时网络比较拥挤,我们应该把题目的图片提前推送到CDN上并且要进行预热,不然的话当用户真正请求题目时,图片可能加载比较慢,从而影响答题的体验。

    其实真正答题的逻辑比较简单,很好理解:当用户提交的答案和题目对应的答案做比较,如果通过了就继续进行下一步的下单逻辑,否则就失败。
    我们可以把问题和答案用下面这样的key来进行MD5加密:
    问题key:userId+itemId+question_Id+time+PK
    答案key:userId+itemId+answer+PK

    答题的验证逻辑
    注意,这里面的验证逻辑,除了验证问题的答案以外,还包括用户本身身份的验证,例如是否已经登录、用户的Cookie是否完整、用户是否重复频繁提交等。
    除了做正确性验证,我们还可以对提交答案的时间做些限制,例如从开始答题到接受答案要超过1s,因为小于1s是人为操作的可能性很小,这样也能防止机器答题的情况。
    3.最后一种是对请求进行分层过滤。

    2.Nginx实现负载均衡

    什么是负载均衡?
    建立很多很多服务器,组成一个服务器集群,当用户访问网站时,先访问一个中间服务器,在让这个中间服务器在服务器集群中选择一个压力较小的服务器,然后将该访问请求引入该服务器
    几种常用方式?
    1、轮询(默认)
    每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。

    upstream backserver {
        server 192.168.0.14;
        server 192.168.0.15;
    }
    

    2、weight
    指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的

    upstream backserver {
        server 192.168.0.14 weight=3;
        server 192.168.0.15 weight=7;
    }
    

    上述方式存在一个问题就是说,在负载均衡系统中,假如用户在某台服务器上登录了,那么该用户第二次请求的时候,因为我们是负载均衡系统,每次请求都会重新定位到服务器集群中的某一个,那么已经登录某一个服务器的用户再重新定位到另一个服务器,其登录信息将会丢失,这样显然是不妥的

    3.采用ip_hash指令解决这个问题,如果客户已经访问了某个服务器,当用户再次访问时,会将该请求通过哈希算法,自动定位到该服务器。
    每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。

    upstream backserver {
        ip_hash;
        server 192.168.0.14:88;
        server 192.168.0.15:80;
    }
    

    配置实例:

    #user  nobody;
    worker_processes  4;
    events {
        # 最大并发数
        worker_connections  1024;
    }
    http{
        # 待选服务器列表
        upstream myproject{
            # ip_hash指令,将同一用户引入同一服务器。
            ip_hash;
            server 125.219.42.4 fail_timeout=60s;
            server 172.31.2.183;
            }
    
        server{
                    # 监听端口
                    listen 80;
                    # 根目录下
                    location / {
                        # 选择哪个服务器列表
                        proxy_pass http://myproject;
                    }
    
                }
    }
    

    Cookie 和 Session 关系和区别

    https://juejin.im/post/5aa783b76fb9a028d663d70a

    sessionid如何产生?由谁产生?保存在哪里?

    1.sessionid是一个会话的key,浏览器第一次访问服务器会在服务器端生成一个session,有一个sessionid和它对应。
    2.tomcat生成的sessionid叫做jsessionid。
    3.session在访问tomcat服务器HttpServletRequestgetSession(true)的时候创建,tomcat的ManagerBase类提供创建sessionid的方法:随机数+时间+jvmid
    3.删除:超时;程序调用HttpSession.invalidate();程序关闭;
    4.session存放在哪里:服务器端的内存中。不过session可以通过特殊的方式做持久化管理(memcache,redis)

    tomcat中session的创建

    ManagerBase是所有session管理工具类的基类,它是一个抽象类,
    所有具体实现session管理功能的类都要继承这个类,该类有一个受保护的方法,该方法就是创建sessionId值的方法
    tomcat的session的id值生成的机制是一个
            随机数
    加
            时间
    加上
            jvm的id值
    jvm的id值会根据服务器的硬件信息计算得来,因此不同jvm的id值都是唯一的
    
    StandardManager类是tomcat容器里默认的session管理实现类,
    它会将session的信息存储到web容器所在服务器的内存里。
    PersistentManagerBase也是继承ManagerBase类,它是所有持久化存储session信息的基类,
    PersistentManager继承了PersistentManagerBase,但是这个类只是多了一个静态变量和一个getName方法,目前看来意义不大
    对于持久化存储session,tomcat还提供了StoreBase的抽象类,它是所有持久化存储session的基类,
    另外tomcat还给出了文件存储FileStore和数据存储JDBCStore两个实现。
    

    一条SQL语句执行得很慢的原因有哪些?

    2种状态
    1、大多数情况是正常的,只是偶尔会出现很慢的情况。
    本身是没什么问题的,而是其他原因导致的
    可能原因1:数据库在在同步数据到磁盘的时候,就有可能导致我们的SQL语句执行的很慢了。

    我们知道数据库会在内存中把对应字段的数据更新了,但是更新之后,这些更新的字段并不会马上同步持久化到磁盘中去,而是把这些更新的记录写入到 redo log 日记中去,等到空闲的时候,在通过 redo log 里的日记把最新的数据同步到磁盘中去。不过,redo log 里的容量是有限的,如果数据库一直很忙,更新又很频繁,这个时候 redo log很快就会被写满了,这个时候就没办法等到空闲的时候再把数据同步到磁盘的,只能暂停其他操作,全身心来把数据同步到磁盘中去的,而这个时候,就会导致我们平时正常的SQL语句突然执行的很慢

    可能原因2:要执行的这条语句,刚好这条语句涉及到的表,别人在用,并且加锁了,我们拿不到锁,只能慢慢等待别人释放锁了
    show processlist这个命令来显示用户正在运行的线程,需要注意的是,除了 root 用户能看到所有正在运行的线程外,其他用户都只能看到自己正在运行的线程,看不到其它用户正在运行的线程。除非单独个这个用户赋予了process 权限。
    可能又问锁https://www.jianshu.com/p/c12a863dfa1f

    2.一直都这么慢
    可能原因1:好好考虑下 SQL 书写
    字段没有索引
    字段有索引,但却没有用索引
    这个select * from t where c - 1 = 1000;即使c有索引,但是还是不会用,改成select * from t where c = 1000 + 1;还有就是函数操作导致没有用上索引
    可能原因2:当我们的查询语句有多个索引的时候,系统有可能也会选错索引
    可能又问索引https://www.jianshu.com/p/6e86b30386ff

    相关文章

      网友评论

          本文标题:挂面02

          本文链接:https://www.haomeiwen.com/subject/nneiuctx.html