Code war of Angel


  • Home

  • Archives

浏览器相关流程及优化

Posted on 2018-11-21

####组成

浏览器

####渲染引擎:
Trident, Gecko, Presto, Webkit, Blink

####流程

  1. **DNS解析(迭代查询)
    ######优化:
  • 减少dns请求
  • dns预解析
  • httpdns防劫持
  • dns负载均衡**

DNS

  1. 浏览器以一个随机端口进入到网卡,进入TCP/IP协议栈,然后可能经过防火墙过滤,
  2. 建立TCP链接:
    ######优化:
    用https/http2

    tcp
  • 第一次握手:客户端A将标志位SYN置为1,随机产生一个值为seq=J(J的取值范围为=1234567)的数据包到服务器,客户端A进入SYN_SENT状态,等待服务端B确认;
  • 第二次握手:服务端B收到数据包后由标志位SYN=1知道客户端A请求建立连接,服务端B将标志位SYN和ACK都置为1,ack=J+1,随机产生一个值seq=K,并将该数据包发送给客户端A以确认连接请求,服务端B进入SYN_RCVD状态。
  • 第三次握手:客户端A收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给服务端B,服务端B检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,客户端A和服务端B进入ESTABLISHED状态,完成三次握手,随后客户端A与服务端B之间可以开始传输数据了
    tcp
  1. 发送HTTP请求(**GET 或者 POST 等,不常用的还有 PUT 和 DELETE 、HEAD、OPTION以及 TRACE ):静态资源缓存,can,服务器负载均衡,服务器缓存,**
  2. 服务器给浏览器响应一个**301**永久重定向响应
  3. 浏览器跟踪重定向地址
  4. 服务器处理请求:nginx->应用服务器
  5. 服务器返回一个http响应
  6. 客户端渲染:jscss位置,减少体积,

####渲染流程

  1. 加载HTML内容,处理HTML标记,构建DOM树
  2. 加载css,处理css标记,构建CSSOM树
  3. 将DOM和CSSOM合并成一个渲染树
  4. Layout:CPU根据渲染树来布局,计算及节点几何信息
  5. Paint:GPU根据每个Layer位置绘制点,以渲染层缓存
  6. Composition:处理多层渲染层Layers之间的关系,合成一个页面
    其中:
  7. CSS 被视为阻塞渲染的资源,这意味着浏览器将不会渲染任何已处理的内容,直至 CSSOM 构建完毕。存在阻塞的 CSS 资源时,浏览器会延迟 JavaScript 的执行和 DOM 构建。
  8. 当浏览器遇到一个 script 标记时,DOM 构建将暂停,直至脚本完成执行

####css优化:

  1. 设置了媒体类型,会加载但不会阻塞
    ####js优化:
  2. async 与 defer 属性对于 inline-script 都是无效的
  3. defer 属性:载入 JavaScript 文件时不阻塞 HTML 的解析,执行阶段被放到 HTML 标签解析完成之后。
  4. async属性:表示异步执行引入的 JavaScript,如果已经加载好,就会开始执行,加载的 JavaScript 依然会阻塞 load 事件。多个 async-script 的执行顺序是不确定的
  5. 使用 document.createElement 创建的 script 默认是异步async的
    ####dns优化
  6. 减少 DNS 请求
  7. 缩短 DNS 解析路径
  8. dns预解析 dns-prefetch
  9. localDns:缓存挟持,转发
  10. HttpDns:
    客户端直接访问HttpDNS接口,获取业务在域名配置管理系统上配置的访问延迟最优的IP。客户端向获取到的IP后就向直接往此IP发送业务协议请求。
    ####CDN功能:
  11. 调度分配主机;负载均衡,根据 IP,网络流量情况分配最靠近,网络最通畅的 CDN 节点实现加速
  12. 反向代理
  13. 静态缓存;缓存静态资源(html,图片,音乐,视频等)
  14. 防止 DDOS 攻击

利用hexo搭建个人blog

Posted on 2018-11-20
  1. 安装

    1
    2
    3
    4
    5
    6
    >>> npm install -g hexo
    >>> cd /blog-project
    >>> hexo init
    >>> npm install
    >>> hexo g
    >>> hexo server #启动一个本地服务器
  2. 修改配置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    #修改 _config.yml
    ....
    # URL
    ## If your site is put in a subdirectory, set url as 'http://yoursite.com/child' and root as '/child/'
    url: https://angelteng.github.io/blog/ # git仓库地址
    root: /blog/ #根目录
    permalink: :year/:month/:day/:title/
    permalink_defaults:
    .....
    deploy:
    type: git
    repo: git@github.com:angelteng/blog.git
    branch: gh-pages #发布分支
    name:
    email:

    server:
    port: 8080 #本地服务器端口
  3. 去git新增一个仓库
    修改git page选项
    git page
    新增一个ssh key

  4. 管理:建议源代码根目录 git init 之后放在master分支,发布代码放在gh-pages分支

  5. 新增及发布

    1
    2
    3
    4
    5
    # 新增 
    >>> hexo new post "blog title"
    # 发布
    >>> hexo g
    >>> hexo d
  6. 静态资源引用

    1
    2
    # 将图片放在 /source/_post/blogTitle 文件夹下
    {% asset_img hexoLocal.png 图片描述 %}

参考

Flask视图装饰器

Posted on 2018-11-19 | In Python

框架已有:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 路由装饰器
@app.route

# 登陆装饰器
from flask_login import login_required, current_user
@app.route('/')
@login_required
def account():
pass

# 缓存装饰器
from flask_cache import Cache
@app.route('/')
@cache.cached(timeout=60)
def index():
pass

自定义:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 定义一个装饰器
def check_expired(func):
@wraps(func)
def decorated_function(*args, **kwargs):
# 一些逻辑
return func(*args, **kwargs)
return decorated_function

# 使用
@check_expired
def get_something():
pass;

# 定义一个类装饰器
class Timeit(object):
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
print("invoking Timer")
def __get__(self, instance, owner):
return lambda *args, **kwargs: self.func(instance, *args, **kwargs)

# 使用
class A(object):
@Timeit
def func(self):
time.sleep(1)
return "invoking method func"

参考

Flask项目组织

Posted on 2018-11-16 | In Python
  1. 一个基于 WSGI 的 Python web 应用必须有一个实现实际的应用的中心调用对象。在 Flask 中,中心调用对象是一个 Flask类的实例
    1
    app = Flask(__name__)
  • 保证实例的唯一性
  • 当进行单元测试的时候,创建一个最小应用用于测试特定的功能,会用到多应用
  • 使用显式对象时,可以继承基类Flask, 以便于修改特定的功能
  • Flask 需要包的名称。当你创建一个 Flask 实例时, 通常会传递 ___name___ 作为包的名称。 Flask 根据包的名称来载入也模块相关的正确资源。
  • “显式比隐式更好”
    [Flask设计思路](https://dormousehole.readthedocs.io/en/latest/design.html)
  1. 使用蓝图进行模块化组织
    Flask 用 蓝图(blueprints) 的概念来在一个应用中或跨应用制作应用组件和支持通用的模式。蓝图很好地简化了大型应用工作的方式,并提供给 Flask 扩展在应用上注册操作的核心方法。
    例子:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    # routes/identify.py
    from flask import Blueprint

    identify = Blueprint('identify', __name__)

    @identify.route('/check-pics-quality',methods=['POST', 'GET'])
    def check_pics_quality():
    pass;


    # routes/__init__.py
    from .identify import identify
    def init_app(app):
    app.register_blueprint(identify, url_prefix='/identify')

Flask中并发优化jMeter测试

Posted on 2018-11-15 | In Python
  1. Queue的使用
    参考
    in Python3.x should use ‘pip install q’
    in Python2.x should use ‘pip install queue’

  2. 关于模块:除了包含函数定义外,模块也可以包含可执行语句。这些语句一般用来初始化模块。他们仅在 第一次 被导入的地方执行一次。所以如果有需要预初始化对象并共享,可以在模块执行语句中写。

  3. 关于并发测试:
    postman的runner是串行的,上一个请求结束后才开始下一个请求,只能算连续测试但不是并发测试。
    推荐使用JMeter。
    安装:

    1
    2
    3
    4
    >>> brew install jmeter
    # 如果提示没有安装java
    >>> brew install brew cask
    >>> brew cask install java

使用:

1
>>> open /usr/local/bin/jmeter

入门教程
固定qps压力测试
测试结果

  1. 使用htop查看服务器cpu使用情况
    1
    2
    3
    >>> yum install htop
    >>> htop #打开
    >>> q #退出

入门教程
htop

asyncio报错

Posted on 2018-11-14 | In Python

在flask中使用

1
2
3
4
import asyncio
.....
loop = asyncio.get_event_loop()
....

发现报错
RuntimeError: There is no current event loop in thread ‘Thread-2’.

修改为

1
2
3
4
5
import asyncio
...
new_loop = asyncio.new_event_loop()
asyncio.set_event_loop(new_loop)
loop = asyncio.get_event_loop()

原因:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 源码
def get_event_loop(self):
"""Get the event loop.
This may be None or an instance of EventLoop.
"""
if (self._local._loop is None and
not self._local._set_called and
isinstance(threading.current_thread(), threading._MainThread)):
self.set_event_loop(self.new_event_loop())

if self._local._loop is None:
raise RuntimeError('There is no current event loop in thread %r.'
% threading.current_thread().name)

return self._local._loop

在主线程中,调用get_event_loop总能返回属于主线程的event loop对象,如果是处于非主线程中,还需要调用set_event_loop方法指定一个event loop对象,这样get_event_loop才会获取到被标记的event loop对象:

1
2
3
4
5
def set_event_loop(self, loop):
"""Set the event loop."""
self._local._set_called = True
assert loop is None or isinstance(loop, AbstractEventLoop)
self._local._loop = loop

参考
由于Flask工作流程:
如果启动app时将threaded参数设定为True,flask才会以多线程的方式去处理每一个请求,
否则,所有请求是在一个工作线程(非主线程)运行。具体。此时与直接命令行运行脚本不同,请留意。

Python项目相关路径配置

Posted on 2018-11-14 | In Python
  1. python相关环境变量
  • PYTHONPATH : PYTHONPATH是Python搜索路径,默认我们import的模块都会从PYTHONPATH里面寻找。
  • PYTHONSTARTUP: Python启动后,先寻找PYTHONSTARTUP环境变量,然后执行此变量指定的文件中的代码。
  • PYTHONCASEOK: 加入PYTHONCASEOK的环境变量, 就会使python导入模块的时候不区分大小写.
  • PYTHONHOME: 另一种模块搜索路径。它通常内嵌于的PYTHONSTARTUP或PYTHONPATH目录中,使得两个模块库更容易切换。
  1. 配置LD_LIBRARY_PATH
    LD_LIBRARY_PATH is used by your program to search for directories containing the libraries after it has been successfully compiled and linked.
    执行二进制文件时的动态库搜索路径

    1
    2
    3
    4
    5
    6
    >>> vim  ~/.bashrc
    ......
    export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib
    >>> source ~/.bashrc
    >>> 重启进程
    `
  2. 配置PYTHONPATH
    Python模块路径

    1
    2
    3
    4
    5
    6
    7
    8
    >>> vim /etc/profile
    .......
    source /apps/sh/flask_local_com.sh
    >>> vim /apps/sh/flask_local_com.sh
    .......
    export FLASK_DEBUG=1;
    export PYTHONPATH=/vagrant/project/libs:$PYTHONPATH;
    >>> source /etc/profile

flask 使用

Posted on 2018-11-13 | In Python
  1. 开启debug模式
  • 使用uswgi

    1
    2
    3
    4
    5
    from werkzeug.debug import DebuggedApplication
    app.wsgi_app = DebuggedApplication( app.wsgi_app, True )

    if __name__ == '__main__':
    app.run(debug=True)
  • 不使用uswgi

    1
    2
    3
    >>> export FLASK_DEBUG=1 && flask run
    >>> * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
    Nginx 改为反向代理到127.0.0.1:5000
  1. 目录结构
    目录
    作者参考
    论坛参考
    图灵《 Flask Web 开发》董伟明《 Flask Web 开发实战》

  2. 绝对路径 ‘./‘
    相对路径 ‘../‘

Flask安装配置

Posted on 2018-11-12 | In Python
  1. 安装

    1
    2
    pip install uwsgi
    pip install flask
  2. uwsgi
    WSGI(Web Server Gateway Interface),定义了web服务器(nginx、apache、iis等)和 web应用(或者将web框架,flask、django等)之间的接口规范。也就是说,只要 web服务器和 web应用都遵守WSGI协议,那么 web服务器和 web应用就可以随意的组合。

配置uwsgi启动文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# uwsgi.ini
[uwsgi]
socket = 127.0.0.1:5051 # 使用socket
# http = 127.0.0.1:8888 # 使用http协议
pythonpath = /vagrant/flask。# 根项目根目录
module = index
wsgi-file = /vagrant/flask/index.py
callable = app # flask应用实例的名称
processes = 4
threads = 2
daemonize = /vagrant/flask/uwsgi/uwsgi.log
python-autoreload=1
status=/vagrant/flask/uwsgi/uwsgi.status
pidfile=/vagrant/flask/uwsgi/uwsgi.pid

uwsgi命令

1
2
3
uwsgi --ini uwsgi.ini             # 启动
uwsgi --reload uwsgi.pid # 重启
uwsgi --stop uwsgi.pid # 关闭

  1. nginx配置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    server {
    charset utf-8;
    client_max_body_size 128M;
    listen 80;
    server_name flask.local.com;
    root /vagrant/flask;
    index index.py;

    # 如果使用socket协议
    location / {
    include uwsgi_params;
    uwsgi_pass 127.0.0.1:5051; # 配置uwsgi端口
    }
    # 如果使用http协议,则要配置方向代理
    location / {
    proxy_pass http://127.0.0.1:8888;
    }
    }
  2. 业务代码例子

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    # index.py
    from flask import Flask,request
    import json

    app = Flask(__name__)
    app.debug = True

    @app.route("/")
    def helloWorld():
    return json.dumps({
    'code':200,
    'msg':123
    })

    if __name__ == '__main__':
    app.run(host='0.0.0.0', debug=True)
  3. 配置host ,访问即可

Python虚拟环境

Posted on 2018-11-09 | In Python
  1. 函数 str() 用于将值转化为适于人阅读的形式
    repr() 转化为供解释器读取的形式(如果没有等价的语法,则会发生SyntaxError异常)

  2. 虚拟环境

    1
    2
    3
    4
    5
    6
    # 创建虚拟环境
    virtualenv --no-site-package venv
    # 启用
    source ./venv/bin/activate
    # 停用
    deactivate
  3. 可执行python脚本

    1
    #!/usr/bin/env python3.5
  4. 记录依赖变更
    requirements.txt是一个常常被许多Flask应用用于列出它所依赖的包的文本文件。它是通过pip freeze > requirements.txt生成的。 使用pip install -r requirements.txt,你就能安装所有的包。

1…8910
Angel Teng

Angel Teng

97 posts
14 categories
37 tags
© 2021 Angel Teng
Powered by Hexo
|
Theme — NexT.Muse v5.1.4