Nginx实现服务器端集群搭建

Nginx实现服务器端集群搭建

Nginx与Tomcat部署

前面课程已经将Nginx的大部分内容进行了讲解,我们都知道了Nginx在高并发场景和处理静态资源是非常高性能的,但是在实际项目中除了静态资源还有就是后台业务代码模块,一般后台业务都会被部署在Tomcat,weblogic或者是websphere等web服务器上。那么如何使用Nginx接收用户的请求并把请求转发到后台web服务器?

Nginx实现服务器端集群搭建

步骤分析:

1.准备Tomcat环境,并在Tomcat上部署一个web项目
2.准备Nginx环境,使用Nginx接收请求,并把请求分发到Tomat上

环境准备(Tomcat)

浏览器访问:

http://192.168.200.146:8080/demo/index.html

Nginx实现服务器端集群搭建

获取动态资源的链接地址:

http://192.168.200.146:8080/demo/getAddress

本次课程将采用Tomcat作为后台web服务器

(1)在Centos上准备一个Tomcat

1.Tomcat官网地址:https://tomcat.apache.org/
2.下载tomcat,本次课程使用的是apache-tomcat-8.5.59.tar.gz
3.将tomcat进行解压缩
mkdir web_tomcat
tar -zxf apache-tomcat-8.5.59.tar.gz -C /web_tomcat

(2)准备一个web项目,将其打包为war

1.将资料中的demo.war上传到tomcat8目录下的webapps包下
2.将tomcat进行启动,进入tomcat8的bin目录下
./startup.sh

(3)启动tomcat进行访问测试。

静态资源: http://192.168.200.146:8080/demo/index.html
动态资源: http://192.168.200.146:8080/demo/getAddress

环境准备(Nginx)

(1)使用Nginx的反向代理,将请求转给Tomcat进行处理。

upstream webservice {
    server 192.168.200.146:8080;
}
server{
    listen      80;
    server_name localhost;
    location /demo {
        proxy_pass http://webservice;
    }
}

(2)启动访问测试

Nginx实现服务器端集群搭建

学习到这,可能大家会有一个困惑,明明直接通过tomcat就能访问,为什么还需要多加一个nginx,这样不是反而是系统的复杂度变高了么?

那接下来我们从两个方便给大家分析下这个问题,

第一个使用Nginx实现动静分离

第二个使用Nginx搭建Tomcat的集群

Nginx实现动静分离

什么是动静分离?

动:后台应用程序的业务处理

静:网站的静态资源(html,javaScript,css,images等文件)

分离:将两者进行分开部署访问,提供用户进行访问。举例说明就是以后所有和静态资源相关的内容都交给Nginx来部署访问,非静态内容则交个类似于Tomcat的服务器来部署访问。

为什么要动静分离?

​ 前面我们介绍过Nginx在处理静态资源的时候,效率是非常高的,而且Nginx的并发访问量也是名列前茅,而Tomcat则相对比较弱一些,所以把静态资源交个Nginx后,可以减轻Tomcat服务器的访问压力并提高静态资源的访问速度。

​ 动静分离以后,降低了动态资源和静态资源的耦合度。如动态资源宕机了也不影响静态资源的展示。

如何实现动静分离?

实现动静分离的方式很多,比如静态资源可以部署到CDN、Nginx等服务器上,动态资源可以部署到Tomcat,weblogic或者websphere上。本次课程只要使用Nginx+Tomcat来实现动静分离。

需求分析

Nginx实现服务器端集群搭建

动静分离实现步骤

1.将demo.war项目中的静态资源都删除掉,重新打包生成一个war包,在资料中有提供。

2.将war包部署到tomcat中,把之前部署的内容删除掉

进入到tomcat的webapps目录下,将之前的内容删除掉
将新的war包复制到webapps下
将tomcat启动

3.在Nginx所在服务器创建如下目录,并将对应的静态资源放入指定的位置

Nginx实现服务器端集群搭建

其中index.html页面的内容如下:


    Title

        $(function(){
           $.get('http://192.168.200.133/demo/getAddress',function(data){
               $("#msg").html(data);
           });
        });

    Nginx如何将请求转发到后端服务器

4.配置Nginx的静态资源与动态资源的访问

upstream webservice{
   server 192.168.200.146:8080;
}
server {
        listen       80;
        server_name  localhost;

        #动态资源
        location /demo {
                proxy_pass http://webservice;
        }
        #静态资源
        location ~/.*\.(png|jpg|gif|js){
                root html/web;
                gzip on;
        }

        location / {
            root   html/web;
            index  index.html index.htm;
        }
}

5.启动测试,访问http://192.168.200.133/index.html

Nginx实现服务器端集群搭建

假如某个时间点,由于某个原因导致Tomcat后的服务器宕机了,我们再次访问Nginx,会得到如下效果,用户还是能看到页面,只是缺失了访问次数的统计,这就是前后端耦合度降低的效果,并且整个请求只和后的服务器交互了一次,js和images都直接从Nginx返回,提供了效率,降低了后的服务器的压力。

Nginx实现服务器端集群搭建

Nginx实现Tomcat集群搭建

在使用Nginx和Tomcat部署项目的时候,我们使用的是一台Nginx服务器和一台Tomcat服务器,效果图如下:

Nginx实现服务器端集群搭建

那么问题来了,如果Tomcat的真的宕机了,整个系统就会不完整,所以如何解决上述问题,一台服务器容易宕机,那就多搭建几台Tomcat服务器,这样的话就提升了后的服务器的可用性。这也就是我们常说的集群,搭建Tomcat的集群需要用到了Nginx的反向代理和赋值均衡的知识,具体如何来实现?我们先来分析下原理

Nginx实现服务器端集群搭建

环境准备:

(1)准备3台tomcat,使用端口进行区分[实际环境应该是三台服务器],修改server.ml,将端口修改分别修改为8080,8180,8280

(2)启动tomcat并访问测试,

http://192.168.200.146:8080/demo/getAddress

Nginx实现服务器端集群搭建
http://192.168.200.146:8180/demo/getAddress

Nginx实现服务器端集群搭建
http://192.168.200.146:8280/demo/getAddress

Nginx实现服务器端集群搭建

(3)在Nginx对应的配置文件中添加如下内容:

upstream webservice{
        server 192.168.200.146:8080;
        server 192.168.200.146:8180;
        server 192.168.200.146:8280;
    }

好了,完成了上述环境的部署,我们已经解决了Tomcat的高可用性,一台服务器宕机,还有其他两条对外提供服务,同时也可以实现后台服务器的不间断更新。但是新问题出现了,上述环境中,如果是Nginx宕机了呢,那么整套系统都将服务对外提供服务了,这个如何解决?

Nginx高可用解决方案

针对于上面提到的问题,我们来分析下要想解决上述问题,需要面临哪些问题?

Nginx实现服务器端集群搭建
需要两台以上的Nginx服务器对外提供服务,这样的话就可以解决其中一台宕机了,另外一台还能对外提供服务,但是如果是两台Nginx服务器的话,会有两个IP地址,用户该访问哪台服务器,用户怎么知道哪台是好的,哪台是宕机了的?

Keepalived

使用Keepalived来解决,Keepalived 软件由 C 编写的,最初是专为 LVS 负载均衡软件设计的,Keepalived 软件主要是通过 VRRP 协议实现高可用功能。

VRRP介绍

Nginx实现服务器端集群搭建

VRRP(Virtual Route Redundancy Protocol)协议,翻译过来为虚拟路由冗余协议。VRRP协议将两台或多台路由器设备虚拟成一个设备,对外提供虚拟路由器IP,而在路由器组内部,如果实际拥有这个对外IP的路由器如果工作正常的话就是MASTER,MASTER实现针对虚拟路由器IP的各种网络功能。其他设备不拥有该虚拟IP,状态为BACKUP,处了接收MASTER的VRRP状态通告信息以外,不执行对外的网络功能。当主机失效时,BACKUP将接管原先MASTER的网络功能。

从上面的介绍信息获取到的内容就是VRRP是一种协议,那这个协议是用来干什么的?

1.选择协议

VRRP可以把一个虚拟路由器的责任动态分配到局域网上的 VRRP 路由器中的一台。其中的虚拟路由即Virtual路由是由VRRP路由群组创建的一个不真实存在的路由,这个虚拟路由也是有对应的IP地址。而且VRRP路由1和VRRP路由2之间会有竞争选择,通过选择会产生一个Master路由和一个Backup路由。

2.路由容错协议

Master路由和Backup路由之间会有一个心跳检测,Master会定时告知Backup自己的状态,如果在指定的时间内,Backup没有接收到这个通知内容,Backup就会替代Master成为新的Master。Master路由有一个特权就是虚拟路由和后端服务器都是通过Master进行数据传递交互的,而备份节点则会直接丢弃这些请求和数据,不做处理,只是去监听Master的状态

用了Keepalived后,解决方案如下:

Nginx实现服务器端集群搭建

环境搭建

环境准备

VIP IP 主机名 主/从 192.168.200.133 keepalived1 Master 192.168.200.222 192.168.200.122 keepalived2 Backup

keepalived的安装

步骤1:从官方网站下载keepalived,官网地址https://keepalived.org/
步骤2:将下载的资源上传到服务器
    keepalived-2.0.20.tar.gz
步骤3:创建keepalived目录,方便管理资源
    mkdir keepalived
步骤4:将压缩文件进行解压缩,解压缩到指定的目录
    tar -zxf keepalived-2.0.20.tar.gz -C keepalived/
步骤5:对keepalived进行配置,编译和安装
    cd keepalived/keepalived-2.0.20
    ./configure --sysconf=/etc --prefix=/usr/local
    make && make install

安装完成后,有两个文件需要我们认识下,一个是 /etc/keepalived/keepalived.conf(keepalived的系统配置文件,我们主要操作的就是该文件),一个是/usr/local/sbin目录下的 keepalived,是系统配置脚本,用来启动和关闭keepalived

Keepalived配置文件介绍

打开keepalived.conf配置文件

这里面会分三部,第一部分是global全局配置、第二部分是vrrp相关配置、第三部分是LVS相关配置。
本次课程主要是使用keepalived实现高可用部署,没有用到LVS,所以我们重点关注的是前两部分

global全局部分:
global_defs {
   #通知邮件,当keepalived发送切换时需要发email给具体的邮箱地址
   notification_email {
     tom@itcast.cn
     jerry@itcast.cn
   }
   #设置发件人的邮箱信息
   notification_email_from zhaomin@itcast.cn
   #指定smpt服务地址
   smtp_server 192.168.200.1
   #指定smpt服务连接超时时间
   smtp_connect_timeout 30
   #运行keepalived服务器的一个标识,可以用作发送邮件的主题信息
   router_id LVS_DEVEL

   #默认是不跳过检查。检查收到的VRRP通告中的所有地址可能会比较耗时,设置此命令的意思是,如果通告与接收的上一个通告来自相同的master路由器,则不执行检查(跳过检查)
   vrrp_skip_check_adv_addr
   #严格遵守VRRP协议。
   vrrp_strict
   #在一个接口发送的两个免费ARP之间的延迟。可以精确到毫秒级。默认是0
   vrrp_garp_interval 0
   #在一个网卡上每组na消息之间的延迟时间,默认为0
   vrrp_gna_interval 0
}
VRRP部分,该部分可以包含以下四个子模块
1. vrrp_script
2. vrrp_sync_group
3. garp_group
4. vrrp_instance
我们会用到第一个和第四个,
#设置keepalived实例的相关信息,VI_1为VRRP实例名称
vrrp_instance VI_1 {
    state MASTER        #有两个值可选MASTER主 BACKUP备
    interface ens33     #vrrp实例绑定的接口,用于发送VRRP包[当前服务器使用的网卡名称]
    virtual_router_id 51#指定VRRP实例ID,范围是0-255
    priority 100        #指定优先级,优先级高的将成为MASTER
    advert_int 1        #指定发送VRRP通告的间隔,单位是秒
    authentication {    #vrrp之间通信的认证信息
        auth_type PASS  #指定认证方式。PASS简单密码认证(推荐)
        auth_pass 1111  #指定认证使用的密码,最多8位
    }
    virtual_ipaddress { #虚拟IP地址设置虚拟IP地址,供用户访问使用,可设置多个,一行一个
        192.168.200.222
    }
}

配置内容如下:

服务器1

global_defs {
   notification_email {
        tom@itcast.cn
        jerry@itcast.cn
   }
   notification_email_from zhaomin@itcast.cn
   smtp_server 192.168.200.1
   smtp_connect_timeout 30
   router_id keepalived1
   vrrp_skip_check_adv_addr
   vrrp_strict
   vrrp_garp_interval 0
   vrrp_gna_interval 0
}

vrrp_instance VI_1 {
    state MASTER
    interface ens33
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.200.222
    }
}

服务器2

! Configuration File for keepalived

global_defs {
   notification_email {
        tom@itcast.cn
        jerry@itcast.cn
   }
   notification_email_from zhaomin@itcast.cn
   smtp_server 192.168.200.1
   smtp_connect_timeout 30
   router_id keepalived2
   vrrp_skip_check_adv_addr
   vrrp_strict
   vrrp_garp_interval 0
   vrrp_gna_interval 0
}

vrrp_instance VI_1 {
    state BACKUP
    interface ens33
    virtual_router_id 51
    priority 90
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.200.222
    }
}

访问测试

  1. 启动keepalived之前,咱们先使用命令 ip a,查看192.168.200.133和192.168.200.122这两台服务器的IP情况。

Nginx实现服务器端集群搭建
  1. 分别启动两台服务器的keepalived
cd /usr/local/sbin
./keepalived

再次通过 ip a查看ip

Nginx实现服务器端集群搭建
  1. 当把192.168.200.133服务器上的keepalived关闭后,再次查看ip

Nginx实现服务器端集群搭建

通过上述的测试,我们会发现,虚拟IP(VIP)会在MASTER节点上,当MASTER节点上的keepalived出问题以后,因为BACKUP无法收到MASTER发出的VRRP状态通过信息,就会直接升为MASTER。VIP也会”漂移”到新的MASTER。

上面测试和Nginx有什么关系?

我们把192.168.200.133服务器的keepalived再次启动下,由于它的优先级高于服务器192.168.200.122的,所有它会再次成为MASTER,VIP也会”漂移”过去,然后我们再次通过浏览器访问:

http://192.168.200.222/

Nginx实现服务器端集群搭建

如果把192.168.200.133服务器的keepalived关闭掉,再次访问相同的地址

Nginx实现服务器端集群搭建

效果实现了以后, 我们会发现要想让vip进行切换,就必须要把服务器上的keepalived进行关闭,而什么时候关闭keepalived呢?应该是在keepalived所在服务器的nginx出现问题后,把keepalived关闭掉,就可以让VIP执行另外一台服务器,但是现在这所有的操作都是通过手动来完成的,我们如何能让系统自动判断当前服务器的nginx是否正确启动,如果没有,要能让VIP自动进行”漂移”,这个问题该如何解决?

keepalived之vrrp_script

keepalived只能做到对网络故障和keepalived本身的监控,即当出现网络故障或者keepalived本身出现问题时,进行切换。但是这些还不够,我们还需要监控keepalived所在服务器上的其他业务,比如Nginx,如果Nginx出现异常了,仅仅keepalived保持正常,是无法完成系统的正常工作的,因此需要根据业务进程的运行状态决定是否需要进行主备切换,这个时候,我们可以通过编写脚本对业务进程进行检测监控。

实现步骤:

  1. 在keepalived配置文件中添加对应的配置像
vrrp_script 脚本名称
{
    script "脚本位置"
    interval 3 #执行时间间隔
    weight -20 #动态调整vrrp_instance的优先级
}
  1. 编写脚本

ck_nginx.sh

#!/bin/bash
num=ps -C nginx --no-header | wc -l
if [ $num -eq 0 ];then
 /usr/local/nginx/sbin/nginx
 sleep 2
 if [ ps -C nginx --no-header | wc -l -eq 0 ]; then
  killall keepalived
 fi
fi

Linux ps命令用于显示当前进程 (process) 的状态。

-C(command) :指定命令的所有进程

–no-header 排除标题

  1. 为脚本文件设置权限
chmod 755 ck_nginx.sh
  1. 将脚本添加到
vrrp_script ck_nginx {
   script "/etc/keepalived/ck_nginx.sh" #执行脚本的位置
   interval 2       #执行脚本的周期,秒为单位
   weight -20       #权重的计算方式
}
vrrp_instance VI_1 {
    state MASTER
    interface ens33
    virtual_router_id 10
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.200.111
    }
    track_script {
      ck_nginx
    }
}
  1. 如果效果没有出来,可以使用 tail -f /var/log/messages查看日志信息,找对应的错误信息。
  2. 测试

问题思考:

通常如果master服务死掉后backup会变成master,但是当master服务又好了的时候 master此时会抢占VIP,这样就会发生两次切换对业务繁忙的网站来说是不好的。所以我们要在配置文件加入 nopreempt 非抢占,但是这个参数只能用于state 为backup,故我们在用HA的时候最好master 和backup的state都设置成backup 让其通过priority来竞争。

Nginx制作下载站点

首先我们先要清楚什么是下载站点?

我们先来看一个网站 http://nginx.org/download/这个我们刚开始学习Nginx的时候给大家看过这样的网站,该网站主要就是用来提供用户来下载相关资源的网站,就叫做下载网站。

如何制作一个下载站点:

nginx使用的是模块ngx_http_autoindex_module来实现的,该模块处理以斜杠(“/”)结尾的请求,并生成目录列表。

nginx编译的时候会自动加载该模块,但是该模块默认是关闭的,我们需要使用下来指令来完成对应的配置

(1)autoindex:启用或禁用目录列表输出

语法 autoindex on|off; 默认值 autoindex off; 位置 http、server、location

(2)autoindex_exact_size:对应HTLM格式,指定是否在目录列表展示文件的详细大小

默认为on,显示出文件的确切大小,单位是bytes。
改为off后,显示出文件的大概大小,单位是kB或者MB或者GB

语法 autoindex_exact_size on|off; 默认值 autoindex_exact_size on; 位置 http、server、location

(3)autoindex_format:设置目录列表的格式

语法 autoindex_format html|xml|json|jsonp; 默认值 autoindex_format html; 位置 http、server、location

注意:该指令在1.7.9及以后版本中出现

(4)autoindex_localtime:对应HTML格式,是否在目录列表上显示时间。

默认为off,显示的文件时间为GMT时间。
改为on后,显示的文件时间为文件的服务器时间

语法 autoindex_localtime on | off; 默认值 autoindex_localtime off; 位置 http、server、location

配置方式如下:

location /download{
    root /usr/local;
    autoindex on;
    autoindex_exact_size on;
    autoindex_format html;
    autoindex_localtime on;
}

XML/JSON格式[一般不用这两种方式]

Nginx实现服务器端集群搭建

Nginx实现服务器端集群搭建

Nginx的用户认证模块

对应系统资源的访问,我们往往需要限制谁能访问,谁不能访问。这块就是我们通常所说的认证部分,认证需要做的就是根据用户输入的用户名和密码来判定用户是否为合法用户,如果是则放行访问,如果不是则拒绝访问。

Nginx对应用户认证这块是通过ngx_http_auth_basic_module模块来实现的,它允许通过使用”HTTP基本身份验证”协议验证用户名和密码来限制对资源的访问。默认情况下nginx是已经安装了该模块,如果不需要则使用–without-http_auth_basic_module。

该模块的指令比较简单,

(1)auth_basic:使用” HTTP基本认证”协议启用用户名和密码的验证

语法 auth_basic string|off; 默认值 auth_basic off; 位置 http,server,location,limit_except

开启后,服务端会返回401,指定的字符串会返回到客户端,给用户以提示信息,但是不同的浏览器对内容的展示不一致。

(2)auth_basic_user_file:指定用户名和密码所在文件

语法 auth_basic_user_file file; 默认值 — 位置 http,server,location,limit_except

指定文件路径,该文件中的用户名和密码的设置,密码需要进行加密。可以采用工具自动生成

实现步骤:

1.nginx.conf添加如下内容

location /download{
    root /usr/local;
    autoindex on;
    autoindex_exact_size on;
    autoindex_format html;
    autoindex_localtime on;
    auth_basic 'please input your auth';
    auth_basic_user_file htpasswd;
}

2.我们需要使用 htpasswd工具生成

yum install -y httpd-tools
htpasswd -c /usr/local/nginx/conf/htpasswd username //创建一个新文件记录用户名和密码
htpasswd -b /usr/local/nginx/conf/htpasswd username password //在指定文件新增一个用户名和密码
htpasswd -D /usr/local/nginx/conf/htpasswd username //从指定文件删除一个用户信息
htpasswd -v /usr/local/nginx/conf/htpasswd username //验证用户名和密码是否正确

Nginx实现服务器端集群搭建

上述方式虽然能实现用户名和密码的验证,但是大家也看到了,所有的用户名和密码信息都记录在文件里面,如果用户量过大的话,这种方式就显得有点麻烦了,这时候我们就得通过后台业务代码来进行用户权限的校验了。

Nginx的扩展模块

Nginx是可扩展的,可用于处理各种使用场景。本节中,我们将探讨使用Lua扩展Nginx的功能。

Lua

概念

Lua是一种轻量、小巧的脚本语言,用标准C语言编写并以源代码形式开发。设计的目的是为了嵌入到其他应用程序中,从而为应用程序提供灵活的扩展和定制功能。

特性

跟其他语言进行比较,Lua有其自身的特点:

(1)轻量级

Lua用标准C语言编写并以源代码形式开发,编译后仅仅一百余千字节,可以很方便的嵌入到其他程序中。

(2)可扩展

Lua提供非常丰富易于使用的扩展接口和机制,由宿主语言(通常是C或C++)提供功能,Lua可以使用它们,就像内置的功能一样。

(3)支持面向过程编程和函数式编程

应用场景

Lua在不同的系统中得到大量应用,场景的应用场景如下:

游戏开发、独立应用脚本、web应用脚本、扩展和数据库插件、系统安全上。

Lua的安装

在linux上安装Lua非常简单,只需要下载源码包并在终端解压、编译即可使用。

Lua的官网地址为: https://www.lua.org

Nginx实现服务器端集群搭建
  1. 点击download可以找到对应版本的下载地址,我们本次课程采用的是lua-5.3.5,其对应的资源链接地址为https://www.lua.org/ftp/lua-5.4.1.tar.gz,也可以使用wget命令直接下载:
wget https://www.lua.org/ftp/lua-5.4.1.tar.gz
  1. 编译安装
cd lua-5.4.1
make linux test
make install

如果在执行make linux test失败,报如下错误:

Nginx实现服务器端集群搭建

说明当前系统缺少libreadline-dev依赖包,需要通过命令来进行安装

yum install -y readline-devel

验证是否安装成功

lua -v

Lua的语法

Lua和C/C++语法非常相似,整体上比较清晰,简洁。条件语句、循环语句、函数调用都与C/C++基本一致。如果对C/C++不太熟悉的同学来说,也没关系,因为天下语言是一家,基本上理解起来都不会太困难。我们一点点来讲。

第一个Lua程序

大家需要知道的是,Lua有两种交互方式,分别是:交互式和脚本式,这两者的区别,下面我们分别来讲解下:

交互式之HELLOWORLD

交互式是指可以在命令行输入程序,然后回车就可以看到运行的效果。

Lua交互式编程模式可以通过命令lua -i 或lua来启用:

Nginx实现服务器端集群搭建

在命令行中key输入如下命令,并按回车,会有输出在控制台:

Nginx实现服务器端集群搭建

脚本式之HELLOWORLD

脚本式是将代码保存到一个以lua为扩展名的文件中并执行的方式。

方式一:

我们需要一个文件名为 hello.lua,在文件中添加要执行的代码,然后通过命令 lua hello.lua来执行,会在控制台输出对应的结果。

hello.lua

print("Hello World!!")

Nginx实现服务器端集群搭建

方式二:

将hello.lua做如下修改

#!/usr/local/bin/lua
print("Hello World!!!")

第一行用来指定Lua解释器所在位置为 /usr/local/bin/lua,加上#号标记解释器会忽略它。一般情况下#!就是用来指定用哪个程序来运行本文件。但是hello.lua并不是一个可执行文件,需要通过chmod来设置可执行权限,最简单的方式为:

chmod 755 hello.lua

然后执行该文件

./hello.lua

Nginx实现服务器端集群搭建

补充一点,如果想在交互式中运行脚本式的hello.lua中的内容,我们可以使用一个dofile函数,如:

dofile("lua_demo/hello.lua")

注意:在Lua语言中,连续语句之间的分隔符并不是必须的,也就是说后面不需要加分号,当然加上也不会报错,

在Lua语言中,表达式之间的换行也起不到任何作用。如以下四个写法,其实都是等效的

写法一
a=1
b=a+2
写法二
a=1;
b=a+2;
写法三
a=1; b=a+2;
写法四
a=1 b=a+2

不建议使用第四种方式,可读性太差。

Lua的注释

关于Lua的注释要分两种,第一种是单行注释,第二种是多行注释。

单行注释的语法为:

--注释内容

多行注释的语法为:

--[[
    注释内容
    注释内容
--]]

如果想取消多行注释,只需要在第一个–之前在加一个-即可,如:

`

Original: https://www.cnblogs.com/wxdnq/p/15774182.html
Author: 微笑带你去
Title: Nginx实现服务器端集群搭建

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/576324/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • sql查询结果的排序问题

    在sql语句中的查询语句,不同的写入顺序会导致查询的结果不一样 比如我要查询一个联合表中的同学,如果查询的顺序不一样的话,那么结果就会不同 上图为数据的关系图 下面我们要查询张三老…

    数据库 2023年6月11日
    090
  • OpenSSH制作rpm包和升级OpenSSH过程中遇到的问题

    百度网盘:https://pan.baidu.com/s/1gqpH2xeOkYHJ0CiztbmqoQ 提取码:imfg cp x11-ssh-askpass-1.2.4.1.t…

    数据库 2023年6月14日
    0102
  • 查看PostgreSQL监听端口

    如何查看PostgreSQL的监听端口呢?下面总结一下查看PostgreSQL监听端口的方法。 方法1:netstat命令查看 或者sudo netstat -plunt |gre…

    数据库 2023年6月11日
    081
  • windows安装mysql8.0.29(ZIP解压安装版本)

    一. 下载mysql 8.0.29软件包 二. 解压,初始化安装 1,打开下载后文件所在目录,使用解压软件解压,打开文件夹!(如图,文件路径不要出现中文!) 2,创建my.ini文…

    数据库 2023年5月24日
    083
  • 关于.net6项目发布到docker(nginx)踩到的一些坑

    开发环境:桌面云系统(无法使用docker desktop),win10系统 后端开发工具:vs2022 数据库:mysql 缓存:redis 队列和事件处理:rabbitmq 前…

    数据库 2023年6月9日
    078
  • 学习笔记——Django项目中新增数据、修改数据

    2022-09-30 新增数据 方式一: 进入虚拟环境,进入shell工具环境中(”python manage.py shell”),插入数据。在插入数据之…

    数据库 2023年6月14日
    0102
  • 设计模式之简单工厂

    一、简单工厂:为了客户类和服务类之间的解耦,把对象的创建任务交给第三方类,这个第三方类就充当工厂的作用,严格来说简单工厂不属于23种设计模式之一。 二、实现思路 :创建一个简单工厂…

    数据库 2023年6月14日
    085
  • MySQL学习(3)—MySQL常用命令

    ps:此随笔基于mysql 5.7.*版本。 准备 net start mysql 启动MySQL服务 net stop mysql 关闭MySQL服务 mysql [-h exi…

    数据库 2023年5月24日
    083
  • mapreduce统计单词个数

    WordCount类代码: import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.Pat…

    数据库 2023年6月11日
    088
  • 我的创作纪念日

    机缘 2018 年 08 月 07 日是我的创作一周年纪念日。大三刚过完,我还是一名 IT 小白,也并没有考研的想法,当时应该是在实习,偶尔一次上网搜索代码问题的时候看到了 CSD…

    数据库 2023年6月6日
    094
  • Spring Boot MongoDB

    Linux下启动MongoDB并使用mongosh连接 启动方式有两种: systemctl start mongod mongod 启动的时候有可能会报类似如下的错误: Exec…

    数据库 2023年6月14日
    085
  • JVM-堆

    堆 JAVA技术交流群:737698533 堆核心概述 此内存区域的唯一目的就是存放对象实例 一个JVM实例只存在一个堆内存,堆也是Java内存管理的核心区域。 Java堆区在JV…

    数据库 2023年6月16日
    0109
  • SQL Server2008 Order by在union子句不可直接使用的原因

    按照要求,每个取top 20,既然是随机的取,那么就SQL Server Order by newid()就是了,然后把所有数据union起来就得了。所以我立即给出了答案: sel…

    数据库 2023年6月14日
    073
  • 域名SSL认

    阿里云:域名SSL认证-视频 Hole yor life get everything if you never give up. Original: https://www.cn…

    数据库 2023年6月9日
    0121
  • 23种设计模式之备忘录模式

    文章目录 概述 备忘录模式的优缺点 备忘录模式的结构和实现 * 模式结构 模式实现 总结 概述 备忘录模式(Memento Pattern) 保存一个对象的某个状态,以便在适当的时…

    数据库 2023年6月6日
    088
  • [Mysql]如何查看初次安装后的默认密码

    mysql初次安装时,会设置一个临时密码,不允许用空密码直接登录: ubuntu系统上这个密码的存放位置是 /etc/mysql/debian.cnf Original: http…

    数据库 2023年6月16日
    086
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球