关注「WeiyiGeek」公众号

设为「特别关注」每天带你玩转网络安全运维、应用开发、物联网IOT学习!

希望各位看友【关注、点赞、评论、收藏、投币】,助力每一个梦想.


本章目录

目录

首发地址: https://mp.weixin.qq.com/s/u-zb-BxG6VyaLY4EQLKlOQ


0x0n 前言简述

Why has this article?

描述: In the company's image in the study of storage solutions,The first is ready to useFastDFS,But deliberate,Late and operational costs or give up,Can only be used to store to store image files directly,Direct request tip leverage efficiency,But how to ensure maximum business security and reduce the burden on the business to add and delete database? 在 Google 、GithubAfter a search found that can be used directly Nginx + Lua To access data for static resources information,Instead of a business system to access the database directly obtained static resource path,The explicit show real exposure to external resources,Very easy to be batch fetching.

Secondly, the author found that in practice the current search to the installation of the deploymentNginx+LuaMay have will not apply the latest stable versionNginx版本,基本上都是 1.15.x ~ 1.18.x,对于当前Nginx 1.22.0 Obviously is too old version.

So this chapter on the issue of Nginx + Lua + Redis Module environmental practices and simple,Hope I can help you to have the same demandPerson.

基础知识:

  • Nginx: 是一个高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务, Its three core functions,包含静态资源、反向代理、api模块扩展,对于lua脚本的扩展,例如由lua-nginx-module模块,就是apiPart of the module extension,并且nginx可以通过luaScript called directlyredis服务器;
  • Lua: 是一种功能强大,高效,轻量级,可嵌入的脚本语言,Very easy to embedded in our application, It is used in various applications,从游戏到WebThe application and image processing.
  • lua-nginx-module : 该模块是 OpenResty 的核心组件,Directory is tolua的功能嵌入到Nginx http服务器中.
  • lua-resty-redis : 该模块是在 OpenResty Under the project based on cosocket API 的 ngx_lua 的 Lua redis 客户端驱动.

温馨提示: If not existing business a lot of useNginxFor bearing cannot be directly replace other good solution,只能一步一步来,从而转入 OpenResty 或者 caddy Set up to deal with super-high concurrency、扩展性极高的动态 Web 应用、Web 服务和动态网关.

原文地址: https://blog.weiyigeek.top


知识引入

Nginx Instructions are to install the execution order?

答: Now that I have asked the answer is obvious,This is the most novice frequently encountered a confused,Of course also confused the author,Otherwise I wouldn't ask.

Then we down to see such an example: (Verify the sample you might want to start in the next chapter【0x01 部署环境】To prepare the relevant environment), You may say that output is not at this timeWeiyiGeek吗?

location /sequence_demo_1 {
set $a Weiyi;
echo $a;
set $a Geek;
echo $a;
}

But if the request is theURLYou will find that the real time is not the case.

$ curl http://demo.weiyigeek.top/sequence_demo_1
Geek
Geek

Why this irrational phenomenon?

答: 为了解释此现象, We have to introduceNginx的请求处理的11阶段,分别是post-read、server-rewrite、find-config、rewrite、post-rewrite、preaccess、access、post-access、precontent、content以及log,其中3A more common in accordance with the order of execution, in turn, isrewrite阶段、access阶段以及content阶段.

Nginx Configuration instructions generally just registered and operating in one of these processing phase,比如 set 指令就是在rewrite阶段运行的,而echoInstruction will only be incontent阶段运行, In a request processingrewriteStage is alwayscontent阶段之前执行.

因此,属于rewrite阶段的配置指令(示例中的set)Always unconditionally incontent阶段的配置指令(示例中的echo)之前执行,即便是echo指令出现在set指令的前面, In the example above instructions according to the request processing phase sequence sorting,The actual execution order is as follows:

location /sequence_demo_1 {
# rewrite阶段的配置指令,执行在前面
set $a Weiyi;
set $a Geek ;
# content阶段的配置指令,执行在后面
echo $a;
echo $a;
}

所以,输出的结果就是Weiyi Geek了.

LuaModule instruction stage

Each stage of useLua模块指令

描述: 由于本章 Nginx 也是使用 OpenResty Lua Parsing module implementsLua脚本,So the instruction we also need to do a simple understanding,For follow-up study has a very big help.

指令语法: https://github.com/openresty/lua-nginx-module#synopsis

使用Lua来构建nginxOne script is through the instructions to complete,Instructions often is used to specify the Lua When code is executed, as well as the results of how to use the run,lua Instructions are divided into configuration、控制指令, And the control instruction is divided into two ways.

  • lua脚本块 :*_by_lua_block
  • lua脚本文件 :*_by_lua_file

The figure below shows the instruction execution order:从上至下:初始化、重写/访问、内容处理、Log output four stages

lua-nginx-module Directives Document(Lua Nginx Module instruction document):

值得注意的是NginxCan terminate the request(至少),This means that the normal running of the skip stages,Such as rewriting or access stage.这也意味着,Regardless of the running late stage(例如log_by_lua)Will not be able to access in these phases usually set of information.

400 (Bad Request)
405 (Not Allowed)
408 (Request Timeout)
413 (Request Entity Too Large)
414 (Request URI Too Large)
494 (Request Headers Too Large)
499 (Client Closed Request)
500 (Internal Server Error)
501 (Not Implemented)

好了,Here is just a simple click first,In the subsequent practice you can be in looking back on it.


0x01 部署环境

安装说明

环境描述:

# 系统信息
$ cat /etc/issue.net
Ubuntu 20.04.3 LTS
$ uname -a
Linux weiyigeek.top 5.4.0-92-generic \#103-Ubuntu SMP Fri Nov 26 16:13:00 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux # 软件版本
Nginx - 1.22.0 (stable 版本)
pcre - 8.45
zlib - 1.2.12
Lua - 5.4
openssl - 1.1.1q
ngx_devel_kit - v0.3.1
lua-nginx-module - v0.10.21
echo-nginx-module - v0.62
lua-resty-core - v0.1.23
lua-resty-lrucache - v0.13
lua-resty-redis - v0.29

温馨提示: 此处使用的是 Ubuntu 20.04 操作系统, 该系统已做安全加固和内核优化符合等保2.0要求【SecOpsDev/Ubuntu-InitializeSecurity.sh at master · WeiyiGeek/SecOpsDev 】, 如你的Linux未进行相应配置环境可能与读者有些许差异, 如需要进行(windows server、Ubuntu、CentOS)安全加固请参照如下加固脚本进行加固, 请大家疯狂的 star .

加固脚本地址:【 https://github.com/WeiyiGeek/SecOpsDev/blob/master/OS-操作系统/Linux/Ubuntu/Ubuntu-InitializeSecurity.sh

In order to save everyone's practice time,I've put the need to use the source code package uploaded to the space,有需要的朋友可以看一下,下载地址: [http://share.weiyigeek.top/d/36158960-50338508-7c5982?p=2088](http://share.weiyigeek.top/d/36158960-50338508-7c5982?p=2088)(访问密码:2088)

温馨提示: If the certificate is wrong,Please click advanced continue to visit.

安装部署

源代码编译构建

Step 1.在 Ubuntu 20.04 LTS System installation needed for compiling environment.

apt install -y gcc g++ make perl net-tools

Step 2.下载 Nginx、PCRE、zlib、OpenSSL 源代码包,And compile build PCRE、zlib、OpenSSL.

cd /usr/local/src
# Nginx 轻量级的Web代理服务器.
# 官网: https://nginx.org/en/download.html
wget -c https://nginx.org/download/nginx-1.22.0.tar.gz -O /usr/local/src/nginx-1.22.0.tar.gz
tar -zxf nginx-1.22.0.tar.gz # PCRE – 支持正则表达式,NGINX Core 和 Rewrite 模块需要
# 官网: http://pcre.org/
wget -c https://nchc.dl.sourceforge.net/project/pcre/pcre/8.45/pcre-8.45.tar.bz2
tar -jxf pcre-8.45.tar.bz2 && cd pcre-8.45
./configure
make && sudo make install # zlib – 支持标头压缩, NGINX Gzip 模块需要.
# 官网:http://www.zlib.net/
wget -c http://www.zlib.net/zlib-1.2.12.tar.gz
tar -zxf zlib-1.2.12.tar.gz && cd zlib-1.2.12
./configure
make && sudo make install # OpenSSL – 支持 HTTPS 协议, NGINX SSL 模块和其他模块需要.
# 官网: https://www.openssl.org/source/
wget -c https://www.openssl.org/source/openssl-1.1.1q.tar.gz
tar -zxf openssl-1.1.1q.tar.gz && cd openssl-1.1.1q
./config --prefix=/usr/local/openssl
make && sudo make install
ln -s /usr/local/openssl/bin/openssl /usr/local/bin/openssl
# lib 库加载到系统
echo "/usr/local/openssl/lib" >> /etc/ld.so.conf.d/libc.conf
ldconfig
# Execute the command validation system OpenSSL 版本
/usr/local/bin/openssl version
OpenSSL 1.1.1q 5 Jul 2022

温馨提示: 如./configure未指定--prefixParameter will directly installed in/usr/local目录下的bin、lib、shareDengZi directory.

Step 3.Download the compiler to buildLua解析器以及NginxThe development kit andLua模块.

cd /usr/local/src
# ngx_devel_kit - 是Nginx开发工具包,Can, in fact, as aNginx模块,It add extra universal tool,Module developers can use these tools in their own module.
# 项目地址: https://github.com/simpl/ngx_devel_kit
# 项目地址: https://github.com/vision5/ngx_devel_kit
wget -c https://github.com/vision5/ngx_devel_kit/archive/refs/tags/v0.3.1.tar.gz -O ngx_devel_kit-v0.3.1.tar.gz
tar -zxf ngx_devel_kit-v0.3.1.tar.gz && ls ngx_devel_kit-0.3.1
# auto config docs examples LICENSE ngx_auto_lib_core notes objs patches README_AUTO_LIB.md README.md src # lua-nginx-module - 将Lua的强大功能嵌入到NGINX HTTP服务器中
# 项目地址: https://github.com/openresty/lua-nginx-module
wget -c https://github.com/openresty/lua-nginx-module/archive/refs/tags/v0.10.21.tar.gz -O /usr/local/src/lua-nginx-module-v0.10.21.tar.gz
tar -zxf lua-nginx-module-v0.10.21.tar.gz && ls lua-nginx-module-0.10.21
# config doc dtrace misc README.markdown src t tapset util valgrind.suppress # echo-nginx-module - 一个Nginx的输出模块,用于将“echo”、“sleep”、“time”The function such as introduceNginx的配置文件, This module is not overNginxSource distribution together.
# 项目地址: https://github.com/openresty/echo-nginx-module
wget --no-check-certificate -c https://github.com/openresty/echo-nginx-module/archive/refs/tags/v0.62.tar.gz -O /usr/local/src/echo-nginx-module-v0.62.tar.gz
tar -zxf echo-nginx-module-v0.62.tar.gz && ls echo-nginx-module-0.62
# config LICENSE README.markdown src t util valgrind.suppress # luajit2 - lua 解析器 LuaJIT 2 OpenResty 的分支,And pay attention to the parserLua版本为5.1
# 项目地址: https://github.com/openresty/luajit2
wget -c https://github.com/openresty/luajit2/archive/refs/tags/v2.1-20220411.tar.gz -O /usr/local/src/luajit2-v2.1-20220411.tar.gz
tar -zxvf luajit2-v2.1-20220411.tar.gz && cd luajit2-2.1-20220411
make PREFIX=/usr/local/luajit && make install PREFIX=/usr/local/luajit
ln -s /usr/local/luajit/bin/luajit /usr/local/bin/luajit # 链接库设置
echo "/usr/local/luajit/lib" >> /etc/ld.so.conf.d/libc.conf
ldconfig # 临时生效
export LUAJIT_LIB=/usr/local/luajit/lib
export LUAJIT_INC=/usr/local/luajit/include/luajit-2.1 /usr/local/bin/luajit -v
# LuaJIT 2.1.0-beta3 -- Copyright (C) 2005-2017 Mike Pall. http://luajit.org/

温馨提示: 上述 lua The parser used here is LuaJIT 官方的 OpenResty 分支, 而不是 luajit 的主分支https://luajit.org/download/LuaJIT-2.1.0-beta3.tar.gz,In the hole behind the pit would explain why do.

Step 4.为了使Nginx可以连接到redisThe database to perform some column operation,此处借助于lua-nginx-moduleDownload and unpack the required modulelua-resty-core、lua-resty-lrucache、lua-resty-redis.

cd /usr/local/src
# 基于 FFI 的 lua-nginx-module API
# 项目地址: https://github.com/openresty/lua-resty-core
wget -c https://github.com/openresty/lua-resty-core/archive/refs/tags/v0.1.23.tar.gz -O /usr/local/src/lua-resty-core.tar.gz
tar -zxvf lua-resty-core.tar.gz && ls lua-resty-core-0.1.23
# dist.ini lib Makefile README.markdown t valgrind.suppress # 基于 LuaJIT FFI 的 Lua-land LRU Cache
# 项目地址: https://github.com/openresty/lua-resty-lrucache
wget -c https://github.com/openresty/lua-resty-lrucache/archive/refs/tags/v0.13.tar.gz -O /usr/local/src/lua-resty-lrucache-v0.13.tar.gz
tar -zxvf lua-resty-lrucache-v0.13.tar.gz && ls lua-resty-lrucache-0.13/
# dist.ini lib Makefile README.markdown t valgrind.suppress # 基于 cosocket API 的 ngx_lua 的 Lua redis 客户端驱动
# 项目地址: https://github.com/openresty/lua-resty-redis
wget -c https://github.com/openresty/lua-resty-redis/archive/refs/tags/v0.29.tar.gz -O /usr/local/src/lua-resty-redis-v0.29.tar.gz
tar -zxvf lua-resty-redis-v0.29.tar.gz && ls lua-resty-redis-0.29/
# 在使用时可将lua脚本放入到nginx配置目录中.
mkdir -vp /usr/local/nginx/lua/
cp -a /usr/local/src/lua-resty-redis-0.29/lib /usr/local/nginx/lua/
# Displayed in a tree structure that directory
$ tree /usr/local/nginx/lua/
/usr/local/nginx/lua/
├── hello.lua
└── lib
└── resty
└── redis.lua

Step 5.In the above steps after,我们便可以进行nginx编译安装了,构建流程如下(In front of the blogger explainedNginxSeries has detailed 【[Nginx进阶学习之最佳配置实践指南][https://blog.weiyigeek.top/2019/9-1-124.html]】,Described here are not much tired):

# 创建允许用户和组,Don't need a home directory does not log inbash
useradd -M -s /sbin/nologin nginx # 创建 Nginx 所需目录
sudo mkdir -vp /usr/local/nginx/{module,modules,lua} /var/cache/nginx/{client_temp,proxy_temp,fastcgi_temp,uwsgi_temp,scgi_temp}
cd /usr/local/src/nginx-1.22.0 # Nginx Precompiled parameter Settings
./configure \
--prefix=/usr/local/nginx \
--user=nginx --group=nginx \
--with-pcre=../pcre-8.45 \
--with-zlib=../zlib-1.2.12 \
--with-openssl=../openssl-1.1.1q \
--sbin-path=/usr/sbin/nginx \
--conf-path=/usr/local/nginx/nginx.conf \
--pid-path=/usr/local/nginx/nginx.pid \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--lock-path=/var/run/nginx.lock \
--modules-path=/usr/local/nginx/modules \
--http-client-body-temp-path=/var/cache/nginx/client_temp \
--http-proxy-temp-path=/var/cache/nginx/proxy_temp \
--http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp \
--http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp \
--http-scgi-temp-path=/var/cache/nginx/scgi_temp \
--with-threads \
--with-http_sub_module --with-http_v2_module \
--with-http_auth_request_module --with-http_realip_module --with-http_secure_link_module \
--with-http_gunzip_module --with-http_gzip_static_module --with-http_ssl_module \
--with-http_slice_module --with-http_stub_status_module \
--with-http_dav_module --with-http_flv_module --with-http_mp4_module \
--with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-stream_geoip_module \
--with-mail --with-mail_ssl_module \
--with-http_addition_module --with-http_random_index_module \
--with-compat --with-file-aio \
--with-cc-opt='-Os -fomit-frame-pointer -g' \
--with-ld-opt='-Wl,-rpath,/usr/local/luajit/lib,--as-needed,-O1,--sort-common' \
--add-module=/usr/local/src/ngx_devel_kit-0.3.1 \
--add-module=/usr/local/src/lua-nginx-module-0.10.21 \
--add-dynamic-module=/usr/local/src/echo-nginx-module-0.62 \ # Compile the building installation
make & make install

温馨提示: 上述 ./configure Compiler configuration used in the static link library to addngx_devel_kit-0.3.1/lua-nginx-module-0.10.21 模块, And to demonstrate to the use of dynamic link library,此处使用--add-dynamic-module参数指定echo-nginx-module-0.62的解压目录,If you use dynamic link libraries way load module will show in the subsequent practice.

构建结果:

# configure 结果
Configuration summary
# + using threads
# + using PCRE library: ../pcre-8.45
# + using OpenSSL library: ../openssl-1.1.1q
# + using zlib library: ../zlib-1.2.12
# nginx path prefix: "/usr/local/nginx"
# ....................................
# nginx http scgi temporary files: "/var/cache/nginx/scgi_temp" # Make Build after installation hintslibThe dynamic link library address.
- add LIBDIR to the 'LD_LIBRARY_PATH' environment variable during execution
- add LIBDIR to the 'LD_RUN_PATH' environment variable during linking
- use the '-Wl,-rpath -Wl,LIBDIR' linker flag # Or adding in the compilation is dependent onLib目录.
- have your system administrator add LIBDIR to '/etc/ld.so.conf' /usr/local/src/nginx-1.22.0# ls objs/
# ls objs/
# addon ngx_auto_config.h
# autoconf.err ngx_auto_headers.h
# Makefile ngx_http_echo_module_modules.c
# nginx ngx_http_echo_module_modules.o
# ngx_modules.c src
# nginx.8 ngx_http_echo_module.so ngx_modules.o

Step 6.在NginxAfter the success of the installation deployment,为了验证Nginx + Lua安装环境,我们需要再 nginx The main configuration file entry configuration key contents as follows,Pay attention to the following text annotation part.

$ grep -v "^#|^$|#" /usr/local/nginx/conf.d/nginx.conf
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
# 去除 log_format The former comment `#`
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
sendfile on;
keepalive_timeout 65;
# lua Dependency path module package
lua_package_path '/usr/local/src/lua-resty-core-0.1.23/lib/?.lua;/usr/local/src/lua-resty-lrucache-0.13/lib/?.lua;';
...
# 添加加载nginx家目录下的conf.d/Configuration file directory son (通配符)
include conf.d/*.conf;
}

Then create a configuration directory withdemo.weiyigeek.top站点配置demo.conf文件中,添加如下serverField content fragment.

mkdir /usr/local/nginx/conf.d
tee /usr/local/nginx/conf.d/demo.conf <<'EOF'
# https - demo.weiyigeek.top
server {
listen 80;
server_name demo.weiyigeek.top;
charset utf-8;
access_log /var/log/nginx/demo-access.log main buffer=128k flush=1m;
# 方式1.content_by_lua_block lua 片段
location /hello-lua {
default_type 'text/plain';
content_by_lua_block {
ngx.say("Hello World! Lua & Nginx .")
}
} # 方式2.content_by_lua_file lua 脚本文件路径
location /hello-lua-file {
default_type 'text/html';
content_by_lua_file ./lua/hello.lua;
} # 方式3.access_by_lua In the request access phase processing is used to access control.
location /hello-lua-access {
default_type 'text/html';
access_by_lua '
local message = "403 - Hello World! Lua & Nginx access_by_lua"
ngx.say(message)
';
} # 方式4.content_by_lua Accept the request processing phase content and the output response.
location /hello-lua-content {
default_type 'text/html';
content_by_lua "ngx.print('Hello World!')";
}
}
EOF

温馨提示:access_by_lua content_by_lua Is the difference between the forNginxThe request of different processing stages,The former is used to access the access stage processing control(适用于http、server、location、location if),The latter content handler to accept the request and response,适用于location、location if

Step 7.After completion of the above configuration in order to verify the configuration file if there is a question,Can perform the following command if show successful 表示配置没有问题,After can be overloaded nginx 服务.

$ nginx -t
# nginx: the configuration file /usr/local/nginx/nginx.conf syntax is ok
# nginx: configuration file /usr/local/nginx/nginx.conf test is successful $ /usr/sbin/nginx -s reload
$ ps -ef | grep "nginx"
# root 244962 1 0 16:40 ? 00:00:00 nginx: master process nginx
# nginx 245707 244962 0 21:42 ? 00:00:00 nginx: worker process
# root 245710 245523 0 21:42 pts/0 00:00:00 grep nginx

Step 8.Verify the basicNginx+Lua环境,We visit the domain name in the configuration file and directory,Access to the results as shown in the figure below represents the environmentOK,Otherwise please troubleshoot errors or to check whether there is the following issues into the hole out of the pit.

curl -H "host:demo.weiyigeek.top" 10.20.172.201/hello-lua
Hello World! Lua & Nginx . curl -H "host:demo.weiyigeek.top" 10.20.172.201/hello-lua-file
<h2> Hello world! Lua & Nginx with Hello.lua. </h2> curl -H "host:demo.weiyigeek.top" 10.20.172.201/hello-lua-access
Hello World! Lua & Nginx access_by_lua curl -H "host:demo.weiyigeek.top" 10.20.172.201/hello-lua-content
Hello World!

知识扩展: 编译构建nginxAfter we can benginx -VCommand to see once./configurePrecompiled parameter Settings.

$ nginx -V
nginx version: nginx/1.22.0
built by gcc 9.4.0 (Ubuntu 9.4.0-1ubuntu1~20.04.1)
built with OpenSSL 1.1.1q 5 Jul 2022
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx
....
--add-module=/usr/local/src/lua-nginx-module-0.10.21 --add-dynamic-module=/usr/local/src/echo-nginx-module-0.62 -

0x02 使用实践

1.Nginx 实践使用 echo-nginx-module Module of the dynamic link library loading

描述: 从 NGINX 1.9.11 开始,You can also use this module to compile for dynamic module,Method is in the above ./configure 命令行中使用 --add-dynamic-module=PATH 选项而不是--add-module=PATH选项,然后你可以通过 load_module Instructions in your nginx.conf In explicit loading module,注意必须在 events{} 片段之前.

模块语法: https://github.com/openresty/echo-nginx-module#synopsis

Step 1.在Nginx.conf文件中配置load_moduleInstructions to dynamic loading echo-nginx-module 模块.

# 方式1.绝对路径
load_module /usr/local/nginx/modules/ngx_http_echo_module.so;
# 方式2.相对路径
load_module ./modules/ngx_http_echo_module.so;
.....
events {
worker_connections 1024;
}

Step 2.同样在demo.confThe use of file for the module in the conventional practice.

$ cat conf.d/demo.conf
server {
...
# 示例1.常规输出(Pay attention to the text type feedback to show the data in the web page is not the same).
location /nginx-module/echo {
default_type 'text/html';
echo -n "<b>Domain: demo.weiyigeek.top</b> <br/>";
echo "Hello World! by ngx_http_echo_module.so";
} # 示例2.Request latency display and reset time timer.
location /nginx-module/timed {
default_type 'text/plain';
echo "Hello World! by ngx_http_echo_module.so \r";
echo_reset_timer;
echo "1.takes about $echo_timer_elapsed sec \r";
echo_flush;
echo_sleep 2.5; # in sec
echo "2.takes about $echo_timer_elapsed sec.";
echo "End";
} # 示例3.BodyInsert the data before and after the document and inserted in the middle embedded reverse proxy site source code.
location /nginx-module/body {
resolver 223.6.6.6;
default_type 'text/html';
echo "Hello World! by ngx_http_echo_module.so";
echo_before_body 'Blog - ';
proxy_pass $scheme://www.weiyigeek.top:$server_port/index.html;
echo_before_body 'www.WeiyiGeek.top';
echo_after_body '[END]';
} # 示例4.Multiple output the same string and display the client requestheader与请求body主体参数
location /nginx-module/duplicate {
default_type 'text/plain';
echo_duplicate 3 "--";
echo_duplicate 1 "\rHello World! by ngx_http_echo_module.so \r\r";
# echo_duplicate 1000_000 "Hello World! by ngx_http_echo_module.so";
echo "\r";
echo_duplicate 1 $echo_client_request_headers;
echo "\r";
echo_read_request_body;
echo "\r";
echo_request_body;
echo_duplicate 3 "--";
echo;
} # 示例5.Regular matching request parameters,注意`$arg_var`后面的varCan be customized Settings,此处为flag参数.
location ^~ /nginx-module/if {
default_type 'text/plain';
set $res default;
echo $arg_flag;
if ($arg_flag ~* '^a') {
set $res change;
echo $arg_flag, $res;
}
echo $res;
}
....
}

补充 echo_subrequest_async 异步请求

描述: 使用 HTTP 方法、可选的 url 参数(或查询字符串)And optional request subject by different steps,Requests can be defined as a string or contain subject file path.

 # GET /multi will yields
# querystring: foo=Foo
# method: POST
# body: hi
# content length: 2
# ///
# querystring: bar=Bar
# method: PUT
# body: hello
# content length: 5
# ///
location /multi {
echo_subrequest_async POST '/sub' -q 'foo=Foo' -b 'hi';
echo_subrequest_async PUT '/sub' -q 'bar=Bar' -b 'hello';
}
location /sub {
echo "querystring: $query_string";
echo "method: $echo_request_method";
echo "body: $echo_request_body";
echo "content length: $http_content_length";
echo '///';
}

Step 3.After complete the configuration reloadingnginx服务, Through the browser to access the path validation module USES and output,效果如下图所示:

The module of other use please refer to the project addressReadme文档,Here demonstrates how to loading the dynamic link library tonginx,And use the link in the library module.

2.Nginx 实践使用 lua-resty-redis 模块连接 Redis For data operation and display

描述: In front of the deployment environment have downloaded ngx_lua_nginx 模块的 Redis 客户端驱动程序Lua库, 下面将演示如何在 Nginx 基于 ngx_lua_nginx 模块连接到RedisMemory database for data to find the corresponding,Okay, this section is to the point.

语法参考: https://github.com/openresty/lua-resty-redis#synopsis

废话不多说,实践出真知

Step 1.Environment installed in front of us decompression in ngx_lua_nginx 模块使用 Redis 客户端驱动程序Lua库,并将其 Lib 目录复制到 /usr/local/nginx/lua/ 目录中,Secondly I also preparedRedis数据库环境,To install deployment steps would not be in details, Want to quickly install friends can refer to my this article【[RedisMemory database fleetly deployment environment][https://blog.weiyigeek.top/2022/4-24-653.html]】.

$ tree /usr/local/nginx/lua/lib/
/usr/local/nginx/lua/lib/
└── resty
└── redis.lua # Redis 数据库 & In order to demonstrate data preparation twoKey即domain/blog
192.168.1.22 6379 weiyigeek.top
/data # redis-cli
127.0.0.1:6379> auth weiyigeek.top
OK
127.0.0.1:6379> ping
PONG
127.0.0.1:6379> set domain www.weiyigeek.top
OK
127.0.0.1:6379> set blog blog.weiyigeek.top
OK

Step 2.想要在Nginx使用该redis.lua链接到数据库,首先我们需要在nginx.confThe configuration file to join thelua包路径/usr/local/nginx/lua/lib/,例如:

$ grep "lua_package_path" /usr/local/nginx/nginx.conf
lua_package_path '/usr/local/nginx/lua/lib/?.lua;/usr/local/src/lua-resty-core-0.1.23/lib/?.lua;/usr/local/src/lua-resty-lrucache-0.13/lib/?.lua;'

Step 3.Here is also in demo.conf 中进行配置使用Redis客户端驱动程序Lua库,连接到Redis数据库中, Here for the convenience of presentation in the configuration file directlycontent_by_lua_block 代码块中使用lua语法,In the enterprise production practice environment must be written to thelua文件文件中.

# /usr/local/nginx/conf.d/demo.conf
server {
...
location /redis/get {
default_type 'text/html';
set $key $arg_key;
content_by_lua_block {
-- # 引入resty.redisModule and create instantiation object
local redis = require "resty.redis"
local client = redis:new()
local REDIS_HOST = "192.168.1.22"
local REDIS_PROT = 6379
local REDIS_AUTH = "weiyigeek.top"
-- # ngx.log(ngx.ERR, ngx.var.key)
-- # , respectively, set up the connection、Send and read timeout threshold(以毫秒为单位),For subsequent socket operation.
client:set_timeouts(1000, 1000, 1000) -- # 创建链接对象, 连接到Redis数据库
ngx.say("1.connect redis server..... <br>");
local ok, err = client:connect(REDIS_HOST, REDIS_PROT)
if not ok then
ngx.say("failed to connect: ", err)
return
end -- # 认证
ngx.say("2.auth redis server..... <br>");
local res, err = client:auth(REDIS_AUTH)
if not res then
ngx.say("failed to authenticate: ", err)
return
end -- # Access to specify request keys
ngx.say("3.get custom KV for redis server, Key = ",ngx.var.key," <br>");
local res, err = client:get(ngx.var.key)
if not res then
ngx.say("failed to get key: ", err)
return
end
if res == ngx.null then
ngx.say("key not found.")
return
end -- # 输出结果
ngx.say("<b style='color:red'>4.result value: ",res,"</b><br/>") -- # Immediately after using closed destroyedRedis连接(Short connection can use so,If it is a long link Suggestions to recycle the connection pool object can be)
local ok, err = client:close()
if not ok then
ngx.say("failed to close: ", err)
return
else
ngx.say("5.just close the Redis connection right away <br/>")
end
}
}
...
}

Step 5.In a demonstration example,We can one-time perform multipleredis操作命令 lua-resty-redis 库支持pipeline提交,下面我们演示使用 content_by_lua_file Specified keyword join operationredis的lua脚本地址(/usr/local/nginx/lua/custom/nginx-redis.lua)实践, It is recommended to use in the online environment.

# 1) 操作 redis 数据库的 lua 脚本示例.
tee /usr/local/nginx/lua/custom/nginx-redis.lua <<'EOF'
-- # 引入resty.redisModule and create instantiation object
local redis = require "resty.redis"
local client = redis:new()
local REDIS_HOST = "192.168.1.22"
local REDIS_PROT = 6379
local REDIS_AUTH = "weiyigeek.top"
-- # ngx.log(ngx.ERR, ngx.var.key)
-- # , respectively, set up the connection、Send and read timeout threshold(以毫秒为单位),For subsequent socket operation.
client:set_timeouts(1000, 1000, 1000) -- # Validate request parameters is there
if (ngx.var.key == ngx.null and ngx.var.value == ngx.null)
then
ngx.say("Request parameters : key + value not found!")
ngx.exit(404)
end -- # 创建链接对象, 连接到Redis数据库
ngx.say("1.connect redis server..... <br>");
local ok, err = client:connect(REDIS_HOST, REDIS_PROT)
if not ok then
ngx.say("failed to connect: ", err)
return
end -- # 认证
ngx.say("2.auth redis server..... <br>");
local res, err = client:auth(REDIS_AUTH)
if not res then
ngx.say("failed to authenticate: ", err)
return
end -- # 使用 pipeline Channel wayredis 数据库操作
client:init_pipeline()
client:set(ngx.var.key, ngx.var.value)
client:get(ngx.var.key)
client:get("domain")
local results, err = client:commit_pipeline()
if not results then
ngx.say("failed to commit the pipelined requests: ", err)
return
end -- 结果遍历
for i, res in ipairs(results) do
if type(res) == "table" then
if res[1] == false then
ngx.say("failed to run command ", i, ": ", res[2],"<br/>")
else
-- process the table value
ngx.say("3) 3.",i, ": ", res[2],"<br/>")
end
else
-- process the scalar value
ngx.say("<p style='color:red'>3) ",i,"---",res,"</p>")
end
end -- 将当前 Redis Connection immediately into the ngx_lua cosocket 连接池(Put it in the size of100的连接池中,最大空闲时间为10秒).
local ok, err = client:set_keepalive(10000, 100)
if not ok then
ngx.say("failed to set keepalive: ", err)
return
end
ngx.say("4.将当前 Redis Connection immediately into the ngx_lua cosocket 连接池<br/>")
EOF # 2) 配置 demo.conf 文件 同样在 server Fragment to add the following location 片段.
server {
....
location /redis/pipeline {
default_type 'text/html';
# 获取请求参数中key的值与valueThe value of the coexist innginx环境变量中
set $key $arg_key;
set $value $arg_value;
# Call and perform the specifiedlua脚本
content_by_lua_file ./lua/custom/nginx-redis.lua;
}
....
}

After completion of the configuration we can overridenginx,And use the access to the browser to access the path,例如: http://demo.weiyigeek.top/redis/pipeline?key=name&value=WeiyiGeek,Here I demonstrate the results as shown in the figure below.

3.Nginx Practice readingRedisImages in the database corresponding key values and binding pictures show

描述: If in such a scenario,In order to avoid malicious users to traverse the regular pictures to download,那如何解决这个问题呢?

Method is to win a few, but not limited to the practice of this section case,Here we can name or picturesmd5值存入到Redis数据库中作为Key,While the actual path of the picture forValue,When we request the wemd5Value as a parameter to the incoming,经过 Nginx 对请求参数的处理,Use the way in Lua 脚本中连接Redis,并将URL传递的md5参数作为key进行get查询,And the query to the image path,反馈给setInstruction set of variables,然后我们便可以通过 proxy_pass 进行代理访问(地址栏中的url不会变化,To ensure that the actual image path),Or you can add a headContent-DispositionDirectly to download images.

Not much any of that crap,Only practice is king.

实践流程:

  • Step 1.Prepare a picture catalogue and in a few images demonstrate,You can use the picture name heremd5Also can use a graphical file itselfmd5效验值.
$ tree /usr/local/nginx/html/
/usr/local/nginx/html/
├── 50x.html
├── images
│   ├── 1562941454569.jpeg
│   ├── 1562941454570.jpeg
│   └── 1562941454571.png
└── index.html # 文件的MD5值
/usr/local/nginx/html/images# md5sum * | awk '{print "set "$1" "$2}'
set 6fad4c2466dc7f61fb055021ec65324d 1562941454569.jpeg
set 611877180883388de4752ded33a81165 1562941454570.jpeg
set 6636d52bfbe068177df5219edf4dd456 1562941454571.png # 写入KV到redis数据库中
127.0.0.1:6379> set 6fad4c2466dc7f61fb055021ec65324d 1562941454569.jpeg
OK
127.0.0.1:6379> set 611877180883388de4752ded33a81165 1562941454570.jpeg
OK
127.0.0.1:6379> set 6636d52bfbe068177df5219edf4dd456 1562941454571.png
OK
  • Step 2.在demo.conf文件中的serverSegments increase location 片段,Among them are the following configuration:
$ vim conf.d/demo.conf
server {
......
location = /api/v2/images/get {
resolver 223.6.6.6;
set $key $arg_md5sum;
set $name "";
access_by_lua_block {
local redis = require "resty.redis"
local client = redis:new()
local REDIS_HOST = "192.168.1.22"
local REDIS_PROT = 6379
local REDIS_AUTH = "weiyigeek.top"
client:set_timeouts(1000, 1000, 1000)
local ok, err = client:connect(REDIS_HOST, REDIS_PROT)
if not ok then
ngx.say("failed to connect: ", err)
return
end
local res, err = client:auth(REDIS_AUTH)
if not res then
ngx.say("failed to authenticate: ", err)
return
end
local res, err = client:get(ngx.var.key)
if not res then
ngx.say("failed to get key: ", err)
return
end
if res == ngx.null then
ngx.say("key not found.")
return
else
-- # The key pointredisThe value of the specified key given tonginx指定变量
ngx.var.name = res
end
local ok, err = client:set_keepalive(10000, 100)
if not ok then
ngx.say("failed to set keepalive: ", err)
return
end
}
proxy_pass $scheme://$server_name/images/$name;
}
......
}

After completion of the configuration we overloaded Nginx,And then using the browser to access the aboveURL,例如http://demo.weiyigeek.top/api/v2/images/get?md5sum=6636d52bfbe068177df5219edf4dd456,执行结果如下所示:

  • Step 3.If we want to directly through the browser to access the above address pop-up source file name to download,我们则可以在 proxy_pass Fragments after add the following header 头: add_header Content-Disposition "attachment;filename=$name";
...
proxy_pass $scheme://$server_name/images/$name;
add_header Content-Disposition "attachment;filename=$name";
... # 重载Nginx后利用CURL访问该URL
$ curl -I http://demo.weiyigeek.top/api/v2/images/get?md5sum=6636d52bfbe068177df5219edf4dd456
HTTP/1.1 200 OK
Server: nginx/1.22.0
Date: Tue, 02 Aug 2022 02:23:12 GMT
Content-Type: image/png
Content-Length: 32641
Connection: keep-alive
Last-Modified: Wed, 23 Mar 2022 00:48:26 GMT
ETag: "623a6e5a-7f81"
Accept-Ranges: bytes
Content-Disposition: attachment;filename=1562941454571.png

  • Step 4.当然,你也可使用rewrite_by_lua_block代码块包含LuaCan be direct or image path,然后使用ngx.redirect()方法进行跳转.
$ vim conf.d/demo.conf
server {
......
location = /api/v1/images/get {
resolver 223.6.6.6;
set $key $arg_md5sum;
rewrite_by_lua_block {
local redis = require "resty.redis"
local client = redis:new()
local REDIS_HOST = "192.168.1.22"
local REDIS_PROT = 6379
local REDIS_AUTH = "weiyigeek.top"
client:set_timeouts(1000, 1000, 1000)
local ok, err = client:connect(REDIS_HOST, REDIS_PROT)
if not ok then
ngx.say("failed to connect: ", err)
return
end
local res, err = client:auth(REDIS_AUTH)
if not res then
ngx.say("failed to authenticate: ", err)
return
end
local res, err = client:get(ngx.var.key)
if not res then
ngx.say("failed to get key: ", err)
return
end
if res == ngx.null then
ngx.say("key not found.")
else
-- # The key image format.
return ngx.redirect(string.format("%s%s","/images/",res))
end
local ok, err = client:set_keepalive(10000, 100)
if not ok then
ngx.say("failed to set keepalive: ", err)
return
end
}
# If there is no matching collocation to jump to jump, visit the home page
proxy_pass $scheme://$server_name/index.html;
}
......
}

好了,This chapter practice has been to the here,More exotic curiosity-a solution looking in [weiyigeek] 公众号.


0x03 扩展补充

示例1.使用 ngx.location.capture() Request the internal interface

location = /auth {
internal;
retur 200 '{"status":"$auth_status"}'
} # According to the needs of the business here to write a regular expression,一定要个 redis 里的 KEY 对应上
location ~/[0-9].*\.(gif|jpg|jpeg|png)$ {
set $target '';
access_by_lua '
# 使用 nginx 的内部参数 ngx.var.uri To obtain a request uri 地址,如 /000001.jpg
local key = ngx.var.uri
# 根据正则匹配到 KEY ,从 redis Database access file ID (路径和文件名)
local res = ngx.location.capture(
"/Redis", { args = { key = key } }
)
if res.status ~= 200 then
ngx.log(ngx.ERR, "Redis server returned bad status: ",res.status)
ngx.exit(res.status)
end
if not res.body then
ngx.log(ngx.ERR, "Redis returned empty body")
ngx.exit(500)
end
local parser = require "Redis.parser"
local filename, typ = parser.parse_reply(res.body)
if typ ~= parser.BULK_REPLY or not server then
ngx.log(ngx.ERR, "bad Redis response: ", res.body)
ngx.exit(500)
end ngx.var.target = filename
';
proxy_pass http://10.20.172.196/$target;
}

0x0n 入坑出坑

问题1. 当编译 Nginx 时报checking for LuaJIT 2.x ... not found, ./configure: error: unsupported LuaJIT version; ngx_http_lua_module requires LuaJIT 2.x. 错误时的解决办法.

问题描述: tell nginx's build system where to find LuaJIT 2.1

解决办法:

# 临时生效
export LUAJIT_LIB=/usr/local/luajit/lib
export LUAJIT_INC=/usr/local/luajit/include/luajit-2.1 # 永久生效
tee -a /etc/profile <<'EOF'
export LUAJIT_LIB=/usr/local/luajit/lib
export LUAJIT_INC=/usr/local/luajit/include/luajit-2.1
EOF
source /etc/profile

问题2.在使用luajit官方主分支LuaJIT-2.1.0-beta3提供LuaJITInstall deployment therenginx: [alert] detected a LuaJIT version which is not OpenResty's;以及nginx: [alert] failed to load the 'resty.core' module警告.

错误信息:

$ /usr/sbin/nginx
nginx: [alert] detected a LuaJIT version which is not OpenResty's; many optimizations will be disabled and performance will be compromised (see https://github.com/openresty/luajit2 for OpenResty's LuaJIT or, even better, consider using the OpenResty releases from https://openresty.org/en/download.html)
nginx: [alert] failed to load the 'resty.core' module (https://github.com/openresty/lua-resty-core); ensure you are using an OpenResty release from https://openresty.org/en/download.html (reason: module 'resty.core' not found:
no field package.preload['resty.core']
no file './resty/core.lua'
no file '/usr/local/share/luajit-2.1.0-beta3/resty/core.lua'
no file '/usr/local/share/lua/5.1/resty/core.lua'
no file '/usr/local/share/lua/5.1/resty/core/init.lua'
no file './resty/core.so'
no file '/usr/local/lib/lua/5.1/resty/core.so'
no file '/usr/local/lib/lua/5.1/loadall.so'
no file './resty.so'
no file '/usr/local/lib/lua/5.1/resty.so'
no file '/usr/local/lib/lua/5.1/loadall.so') in /usr/local/nginx/nginx.conf:117

问题原因1: 提示LuaJIT的版本不匹配OpenResty's内核版本, Let me not to use thisluajit版本,可以用openresty提供的luajit优化版本,或者干脆直接用openresty,The following will be installed unloadingluajit官网版本,下载openresty提供的luajit优化版本(As the environment has been practice,According to the above version for installation does not generally exist the problem).

# You could make a Lua The installation of the script interpreter LuaJIT
http://luajit.org/download.html
wget -c https://luajit.org/download/LuaJIT-2.1.0-beta3.tar.gz
tar -zxf LuaJIT-2.1.0-beta3.tar.gz && cd LuaJIT-2.1.0-beta3
make && make install
ln -sf /usr/local/bin/luajit-2.1.0-beta3 /usr/local/bin/luajit
# 卸载LuaJITOfficer of the webmaster branch version,然后重新安装openresty提供的luajitOptimized version can be
make uninstall
make clean

问题原因2: 提示加载'resty.core'模块失败,其解决办法,按照https://github.com/openresty/lua-nginx-module/issues/1509上面所说, 安装lua-resty-core和依赖文件lua-resty-lrucache解决问题,That I have to practice in front of the part of the operation,If can't work, please turn to 【安装部署】Title to view.

原文地址: https://blog.weiyigeek.top/2022/7-2-676.html

本文至此完毕,更多技术文章,尽情期待下一章节!


WeiyiGeek Blog 个人博客 - 为了能到远方,脚下的每一步都不能少 】

欢迎各位志同道合的朋友一起学习交流,如文章有误请在下方留下您宝贵的经验知识!

作者主页: 【 https://weiyigeek.top

博客地址: 【 https://blog.weiyigeek.top 】

专栏书写不易,如果您觉得这个专栏还不错的,请给这篇专栏 【点个赞、投个币、收个藏、关个注,转个发,留个言】(人间六大情),这将对我的肯定,谢谢!.

  • echo "【点个赞】,动动你那粗壮的拇指或者芊芊玉手,亲!"

  • printf("%s", "【投个币】,万水千山总是情,投个硬币行不行,亲!")

  • fmt.Printf("【收个藏】,阅后即焚不吃灰,亲!")

  • console.info("【转个发】,让更多的志同道合的朋友一起学习交流,亲!")

  • System.out.println("【关个注】,后续浏览查看不迷路哟,亲!")

  • cout << "【留个言】,文章写得好不好、有没有错误,一定要留言哟,亲! " << endl;

更多网络安全、系统运维、应用开发、物联网实践、网络工程、全栈文章,尽在 https://blog.weiyigeek.top 之中,谢谢各位看又支持!

运维实践-最新NginxBinary build compilelua-nginx-module动态链接Lua脚本访问RedisDatabase read static implicit resources show more related articles

  1. vivo大规模 Kubernetes 集群自动化运维实践

    作者:vivo 互联网服务器团队-Zhang Rong 一.背景 随着vivo业务迁移到K8s的增长,我们需要将K8s部署到多个数据中心.如何高效.可靠的在数据中心管理多个大规模的K8sA cluster is we face ...

  2. HBase运维实践-聊聊RIT的那点事

    相信长时间运维HBase集群的童鞋肯定都会对RIT(Region-In-Transition,很多参考资料误解为Region-In-Transaction,需要注意)有一种咬牙切齿的痛恨感,一旦Reg ...

  3. 关于Prometheus运维实践项目

    关于Promethues运维实践项目 1. 什么是Prometheus运维实践项目 ​ 是什么 ​ Prometheus,普罗米修斯,是古希腊神话中为人间带来火种的神. ​ Prometheus运维实 ...

  4. elasticsearch基本概念理解+elasticsearch 的shards unassigned处理方法 -- 最佳运维实践 - 集群规划

    1.es与MySQL的概念对比 2.概念理解 2.1 Index : 一个索引即是文档的集合 2.2 Document : 一个文档即是一个可被索引的基础单元信息,一条记录: 2.3 Replicas ...

  5. 华为刘腾:华为终端云Cassandra运维实践分享

    点击此处观看完整活动视频 各位线上的嘉宾朋友大家好,我是来自华为消费者BG云服务部的刘腾,我今天给大家分享的主题是华为终端云Cassandra运维实践.和前面王峰老师提到的Cassandra在360中 ...

  6. 阿里智能运维实践|阿里巴巴DevOps实践指南

    编者按:本文源自阿里云云效团队出品的<阿里巴巴DevOps实践指南>,扫描上方二维码或前往:https://developer.aliyun.com/topic/devops,下载完整版电 ...

  7. 企业运维实践-还不会部署高可用的kubernetes集群?使用kubeadm方式安装高可用k8s集群v1.23.7

    关注「WeiyiGeek」公众号 设为「特别关注」每天带你玩转网络安全运维.应用开发.物联网IOT学习! 希望各位看友[关注.点赞.评论.收藏.投币],助力每一个梦想. 文章目录: 0x00 前言简述 ...

  8. 【MySQL运维实践】

    什么是日志 日志(log)Is a sequence file record events running water Record what happened during the operation of computer program A variety of purposes  Help analysis program problem The analysis of features of the service request.流量等 Determine whether work on success 等等…… MySQL日 ...

  9. 基于 ANSIBLE 自动化运维实践

    摘要:运维这个话题很痛苦,你做任何的产品都离不开运维.不管你用什么语言.什么平台.什么技术,真正能够决定你产品成熟度的很有可能就是你运维的能力.取自 云巴 CEO 张虎在 ECUG 大会上的分享. 云 ...

  10. 灵雀云:etcd 集群运维实践

    [编者的话]etcd 是 Kubernetes 集群的数据核心,最严重的情况是,当 etcd 出问题彻底无法恢复的时候,解决问题的办法可能只有重新搭建一个环境.因此围绕 etcd 相关的运维知识就比较 ...

随机推荐

  1. 在WINDOWSThe preliminary trialOMNET++ 4

    闲扯: Recently the internship company to doZIGBEE,I am interested in this little,But still work to do,Now look for suitable with the help of simulation software,什么NS-2啊,OPNET啊. 正文: This software directly go to website to download software,免费开源. Installation is also ...

  2. Fragment基础----信息传递

    如何通过activity来访问fragment的信息呢,We can through an instance to get to know. 使用两个Fragment和一个activity管理 效果图: 第一个fragmentTo represent the input box 第二个fragm ...

  3. PowerDesigner15中定义varbinary(max)列

    PowerDesigner15 概念数据模型(Entity)中要定义数据类型为varbinary(max)的特性(Attribute),应将数据类型(Data Type)选择为other,在代码(Co ...

  4. Into the pit of the seriesHAProxy负载均衡

    In the large system design used in load balancing is one of the most common way,And relatively of solutionNginx.HAProxy.LVS.F5In the field is common used in doing,Each have each advantage and usage scenarios,Because want to use to thisTCP,因此Nginx ...

  5. Visual Studio 2015创建ASP.NET5项目“DNX SDK version 'dnx-clr-win-x86.1.0.0-beta5' Can't install error

    使用asp.net5建立web application时遇到DNX SDK版本 “dnx-clr-win-x86.1.0.0-beta5”Can't install error 解决办法: 运行cmd: 1.输入: @pow ...

  6. Visual Studio Package 插件开发之自动生成实体工具(Visual Studio SDK)

    前言 这一篇是VS插件基于Visual Studio SDK扩展开发的,可能有些朋友看到[生成实体]心里可能会暗想,T4模板都可以做了.动软不是已经做了么.不就是读库保存文件到指定路径么…… 我希望做 ...

  7. Oracle 条件判断函数decode和case when then案例

    --decode条件判断函数 ,,,,,) from dual --需求:Not through the query table,According to owner type name column values ,,,'商业','其他') from t_owners --case when the ...

  8. java之jdbc使用

    简单使用 Statement 通过 Statement 执行 ,其实是拼接 sql 语句的.  先拼接 sql 语句,然后在一起执行. package com.zze.test; import jav ...

  9. javascript中的iterable

    遍历Array可以采用下标循环,遍历Map和Set就无法使用下标.为了统一集合类型,ES6标准引入了新的iterable类型,Array.Map和Set都属于iterable类型. 具有iterabl ...

  10. redis学习之集群报错Node is not empty

    遇到的问题及解决办法 在redis.conf里bind 真机ip后,接着重新执行每个redis.conf,最后再创建集群,但报错,如下图所示: 图中报的错即: [ERR] Node 192.168.1 ...