主题
Nginx是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP服务器。在学习Nginx的过程中,开发了一个简单的静态资源库BirdNest。😃
核心代码
js
// birdnest.js
const doc = document
const frag = doc.createDocumentFragment()
const $container = doc.getElementById("hero")
const $footer = doc.getElementById("footer")
const LOG = console.info.bind(console)
const IS_DEV = false
const DEV_URL = '../app/json/db-test.json'
const PROD_URL = '../app/json/db.json'
const URL = IS_DEV ? DEV_URL : PROD_URL
const WORKER_PATH = '../app/js/work.js'
const CHUNK_COUNT = 500
const FPS = 1000 / 60
const OPEN_GPU_TURBO = Symbol.for('addStyleWillChange')
const CLOSE_GPU_TURBO = Symbol.for('removeStyleWillChange')
const CONFIG = {
year: new Date().getFullYear(),
author: " Chiang ",
copyrightSign: "Copyright © ",
rights: " All rights reserved ",
email: ". jiangqizhi@aliyun.com"
}
const initFooter = () => {
const {
copyrightSign,
year,
author,
rights,
email
} = CONFIG
$footer.innerHTML = `${copyrightSign}${year}${author}${copyright}${email}`
}
const createEle = (tagName , props) => {
const dom = doc.createElement(tagName)
Reflect.ownKeys(props).forEach((k) => {
dom[k] = props[k]
})
return dom
}
const compose = (...fns) => {
return fns.reduce((a, b) => (...args) => a(b(...args)))
}
const handleError = () => {
frag.appendChild(createEle('div', {
className: "row animated fadeInUp",
innerHTML: `<div class="col-offset-2">Something is wrong here...</div>`
}))
$container.appendChild(frag)
initFooter()
}
const frame = (list = []) => {
const create = (_) => createEle('div', {
className: "row animated fadeInUp",
innerHTML: _.innerHTML
})
const append = (_) => frag.appendChild(_)
const pack = compose(append, create)
list.forEach(pack)
const insert = () => $container.appendChild(frag)
window.requestAnimationFrame(insert)
}
const gpuTurbo = (action) => {
const eventMap = {
OPEN_GPU_TURBO: 'contents, opacity, transform, scroll-position',
CLOSE_GPU_TURBO: 'auto'
}
$container.style.willChange = eventMap[action]
}
const defer = (fn, delay = 0) => {
return new Promise((resolve) => {
setTimeout(()=> {
typeof fn === 'function' ? fn() : null
resolve()
}, delay)
})
}
const render = ({ list = [] }) => {
const len = list.length
if (len <= 0) return handleError()
gpuTurbo(OPEN_GPU_TURBO)
if (len < CHUNK_COUNT) {
frame(list)
gpuTurbo(CLOSE_GPU_TURBO)
initFooter()
} else {
const slices = (p) => list.splice(0, parseInt(p * len, 10))
Promise
.all([
defer(() => frame(slices(0.1))),
defer(() => frame(slices(0.2)), FPS * 200),
defer(() => frame(slices(0.3)), FPS * 500),
defer(() => frame(list), FPS * 900)
])
.then(() => {
gpuTurbo(CLOSE_GPU_TURBO)
initFooter()
})
}
}
const io = new IntersectionObserver((observers) => {
observers.map((ele) => {
if (ele.intersectionRatio > 0 && ele.intersectionRatio <= 1) {
ele.target.className = "logo-content animated fadeInUp"
} else {
ele.target.className = "logo-content"
}
})
})
const observer = () => {
io.observe(doc.getElementsByClassName('logo-content')[0])
}
observer()
const init = ($ = {}) => {
const worker = new Worker(WORKER_PATH)
worker.postMessage($)
worker.onmessage = (e) => {
render(e.data)
worker.terminate()
}
worker.onerror = () => {
handleError()
worker.terminate()
}
}
const debounce = (fn, delay) => {
let timer = null
return function () {
const self = this
const args = arguments
!!timer
? clearTimeout(timer)
: timer = setTimeout(() => {
timer= null
fn.apply(self, args)
}, delay)
}
}
const loader = () => {
if (!fetch) {
handleError()
throw new Error('Sorry. Your browser does not support fetch.')
}
fetch(URL)
.then((resp) => {
if ( (resp.status >= 200 && resp.status < 300) || resp.status == 304 ) {
return resp.json()
}
})
.then((data) => {
init(data)
})
.catch(() => {
handleError()
})
}
window.onload = () => {
window.requestAnimationFrame(debounce(loader, 200))
}
js
// work.js
this.addEventListener('message', (e) => {
const T = (to = {}) => {
let { name, url } = to
if (name && url) {
return `<div class="col-2 col-offset-2">
<span class="icon-leaf"></span>
<span>${name}</span>
</div>
<div class="col-4 col-offset-2">
<a href="${url}" target="_blank" rel="noopener noreferrer">${url}</a>
</div>`
}
}
const handleData = (data = {}) => {
const { ip, list = [] } = data
const format = (item) => {
if (!item._key) {
item._key = item.key.toLowerCase()
}
if (item.url && item.url.indexOf('{ip}') > -1) {
item.url = item.url.replace(/{ip}/g, ip)
}
if (!item.innerHTML) {
item.innerHTML = T(item)
}
}
list.sort((x, y) => {
format(x)
format(y)
if (x._key > y._key) {
return 1
} else if (x._key < y._key) {
return -1
} else {
return 0
}
})
return data
}
postMessage(handleData(e.data))
})
下面是我在学习Nginx的时候,对nginx.conf的配置:
# cpu核心数
worker_processes auto;
# 更改worker进程的最大打开文件数限制
worker_rlimit_nofile 204800;
events {
worker_connections 102400;
multi_accept on;
}
http {
# 解析type
include mime.types;
default_type application/octet-stream;
charset uft-8;
#请求数量控制,每秒20个
limit_req_zone $binary_remote_addr zone=one:10m rate=20r/s;
#并发限制30个
limit_conn_zone $binary_remote_addr zone=addr:10m;
server_names_hash_bucket_size 128;
client_header_buffer_size 2k;
large_client_header_buffers 4 4k;
client_max_body_size 8m;
server_tokens off;
access_log off;
sendfile on;
# 数据包里发送所有头文件
tcp_nopush on;
# 不缓存数据,一段一段的发送
tcp_nodelay on;
keepalive_timeout 60;
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
fastcgi_buffer_size 64k;
fastcgi_buffers 4 64k;
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 128k;
open_file_cache max=204800 inactive=20s;
open_file_cache_min_uses 1;
open_file_cache_valid 30s;
gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_http_version 1.0;
gzip_comp_level 2;
gzip_types text/plain application/x-javascript text/css application/xml;
gzip_vary on;
server {
listen 80;
server_name localhost;
limit_req zone=one burst=5;
limit_conn addr 30;
location / {
root html;
expires 6h;
index index.html;
}
location ~ .*\.(app|ico|gif|bmp|jpg|jpeg|png|mp3|mid|wma|mp4|swf|flv|rar|zip|txt|doc|ppt|xls|pdf|json|svg|ttf|eot|otf|woff)$ {
root static;
expires 7d;
# 解决跨域问题
proxy_set_header Cookie $http_cookie;
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Headers Content-Type;
add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
add_header Access-Control-Allow-Credentials true;
}
location ~ .*\.(css|js)$ {
root static;
expires 30m;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
Nginx的一些常见命令:
1、启动:start nginx
2、停止:nginx.exe -s stop 或 nginx.exe -s quit(注:stop是快速停止nginx,可能并不保存相关信息;quit是完整有序的停止nginx,并保存相关信息。)
3、重新载入Nginx:nginx.exe -s reload 当配置信息修改,需要重新载入这些配置时使用此命令。
4、重新打开日志文件:nginx.exe -s reopen
5、查看Nginx版本:nginx -v
6、查看进程:tasklist /fi "imagename eq nginx.exe"
7、强制杀掉进程:taskkill /pid 11992 -t -f