EMQX物联网MQTT消息服务器集群搭建_mqtt 集群-程序员宅基地

技术标签: 物联网  分布式  iot  

EMQX官方介绍

1 环境准备

两台Ubuntu 20.04 作为EMQX节点

一台Ubuntu 20.04安装MYSQL数据库

2 搭建EMQX集群

2.1 下载EMQX开源版安装包

1访问https://www.emqx.com/zh/try?product=broker,选择对应的EMQX版本

2 点击免费下载,选择安装方式和CPU架构

3 下载EMQX安装包并解压

执行下面的命令下载EMQX安装包

​
wget https://www.emqx.com/zh/downloads/broker/4.4.5/emqx-4.4.5-otp24.1.5-3-ubuntu20.04-amd64.zip

解压安装包

2.2 修改EMQX配置文件

安装包解压后进入emqx文件夹

修改emqx.conf文件

vim etc/emqx.conf

(1)修改节点名称

节点1 node.name=emqx1@IP

节点2 node.name=emqx2@IP

(2)修改创建集群方式

方式一:使用 static模式

根据节点列表自动创建集群

修改cluster.discovery = static

修改cluster.static.seeds = emqx1@IP,emqx2@IP(多个节点以逗号分割)

修改完成后保存

方式二:手动(manual) 方式管理集群

# 配置集群名称
cluster.name = emqxcl
# 配置集群发现方式
cluster.discovery = manual
# 配置节点名称,节点名格式为 Name@Host, Host 必须是 IP 地址或 FQDN (主机名。域名)
node.name = emqx1@IP

2.3 防火墙配置

使用下面的命令在防火墙开放端口号

sudo ufw allow 端口号

防火墙开放以下端口:

(1)Dashboard访问端口18083

(2)ekka 模式(4.0 版本之后的默认模式):

在ekka 模式下,集群发现端口的映射关系是约定好的,而不是动态的。 node.dist_listen_min 和 node.dist_listen_max 两个配置在ekka 模式下不起作用。

如果集群节点间存在防火墙,防火墙需要放开这个约定的端口。约定端口的规则如下:

ListeningPort = BasePort + Offset

其中 BasePort 为 4370 (不可配置), Offset 为节点名的数字后缀. 如果节点名没有数字后缀的话, Offsset 为 0。

举例来说, 如果 emqx.conf 里配置了节点名:node.name = [email protected],那么监听端口为 4370, 但对于 emqx1 (或者 emqx-1) 端口就是 4371,以此类推。

(3)The Cluster RPC Port

每个节点还需要监听一个 RPC 端口,也需要被防火墙也放开。跟上面说的ekka 模式下的集群发现端口一样,这个 RPC 端口也是约定式的。

RPC 端口的规则跟ekka 模式下的集群发现端口类似,只不过 BasePort = 5370。就是说,如果 emqx.conf 里配置了节点名:node.name = [email protected],那么监听端口为 5370, 但对于 emqx1 (或者 emqx-1) 端口就是 5371,以此类推。

2.4 启动EMQX集群

(1)分别启动EMQX集群的每个节点

进入emqx文件夹执行下面的命令启动EMQX Broker

./bin/emqx start

使用 static模式创建集群时,当节点全部启动后,会自动创建集群

使用手动(manual) 方式管理集群:

在节点1加入节点2形成集群

# 在节点emqx1@IP上执行
./bin/emqx_ctl cluster join emqx2@IP
# 或者在节点在节点emqx2@IP执行
./bin/emqx_ctl cluster join emqx1@IP

节点退出集群:

# 让本节点退出集群

./bin/emqx_ctl cluster leave

# 从集群删除其他节点

./bin/emqx_ctl cluster force-leave emqx1@IP

(2)查看节点状态:

./bin/emqx_ctl status

(3)查看emqx集群状态:

./bin/emqx_ctl cluster status

2.5 访问EMQX Dashboard

访问 http://ip:18083 来查看Dashboard,默认用户名是 admin,密码是 public

3 EMQX认证

EMQX 的认证支持包括两个层面:

MQTT 协议本身在 CONNECT 报文中指定用户名和密码,EMQX 以插件形式支持基于 Username、ClientID、HTTP、JWT、LDAP 及各类数据库如 MongoDB、MySQL、PostgreSQL、Redis 等多种形式的认证。

在传输层上,TLS 可以保证使用客户端证书的客户端到服务器的身份验证,并确保服务器向客户端验证服务器证书。也支持基于 PSK 的 TLS/DTLS 认证。

本章节介绍了 EMQX 的MySQL认证插件的配置方法以及TLS认证配置。

3.1 开启认证模式

EMQ X 默认配置中启用了匿名认证,任何客户端都能接入 EMQX,因此,EMQX开启认证首先要关闭匿名认证。

vim etc/emqx.conf

将allow_anonymous设为false,关闭匿名访问,关闭后EMQX将不允许匿名用户连接,需要通过用户名密码连接。

3.2 MySQL认证

MySQL 认证使用外部 MySQL 数据库作为认证数据源,可以存储大量数据,同时方便与外部设备管理系统集成。

3.2.1 安装MySQL数据库

MySQL数据库配置

3.2.2 MySQL认证配置

1 在MySQL中创建emqx所需的数据库和用户认证表

(1)创建用户名emqx密码emqx

CREATE USER emqx@'%' IDENTIFIED BY 'emqx';

(2)创建emqx数据库

create database emqx character set utf8;

(3)将数据库emqx下的所有表授权给emqx用户

grant all privileges on emqx.* to 'emqx'@'%';

(4)创建认证用户表

CREATE TABLE `mqtt_user` (

  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,

  `username` varchar(100) DEFAULT NULL,

  `password` varchar(100) DEFAULT NULL,

  `salt` varchar(35) DEFAULT NULL,

  `is_superuser` tinyint(1) DEFAULT 0,

  `created` datetime DEFAULT NULL,

  PRIMARY KEY (`id`),

  UNIQUE KEY `mqtt_username` (`username`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

创建好数据库相关用户和表结构后在每个节点的配置文件etc/plugins/emqx_auth_mysql.conf 中配置以下内容:

2 修改MySQL认证配置文件

创建好数据库相关用户和表结构后在每个节点的配置文件etc/plugins/emqx_auth_mysql.conf 中配置以下内容:

(1)配置 MySQL 服务相关的连接地址,用户名密码和数据库

(2) 配置认证SQL

进行身份认证时,EMQX 将使用当前客户端信息填充并执行用户配置的认证 SQL,查询出该客户端在数据库中的认证数据。

你可以在认证 SQL 中使用以下占位符,执行时 EMQX 将自动填充为客户端信息:

%u:用户名

%c:Client ID

%C:TLS 证书公用名(证书的域名或子域名),仅当 TLS 连接时有效

%d:TLS 证书 subject,仅当 TLS 连接时有效

你可以根据业务需要调整认证 SQL,如添加多个查询条件、使用数据库预处理函数,以实现更多业务相关的功能。但是任何情况下认证 SQL 需要满足以下条件:

a.查询结果中必须包含 password 字段,EMQX 使用该字段与客户端密码比对

b.如果启用了加盐配置,查询结果中必须包含 salt 字段,EMQX 使用该字段作为 salt(盐)值

c.查询结果只能有一条,多条结果时只取第一条作为有效数据

(3) 配置加盐规则与哈希方法

配置密码加密方式,本文密码加密采用加盐+sha256方式

3.3 TLS认证双向认证

1 MQTT TLS 的默认端口是 8883:

2 配置证书和 CA

开启TLS双向认证时需要创建客户端和服务端证书,并在此处配置服务端证书的位置,在使用TLS双向认证连接时,需要在客户端配置客户端证书。

创建自签名证书方法参考附录6.1章节

3 开启双向认证

以下两个配置是 打开服务端 验证客户端证书 (默认关闭 即单向验证 打开即可实现双向认证)

作为一种性能优化设置,它允许客户端重用预先存在的会话,而不是初始化新的会话。

EMQX集群所有节点配置完成后,分别重启每个节点

3.4 认证验证

3.4.1 开启emqx_auth_mysql插件认证

开启所有节点的emqx_auth_mysql插件认证,打开emqx Dashboard界面,点击插件模块,启动emqx_auth_mysql插件。

3.4.2 创建emqx用户名和密码

在emqx数据库的mqtt_user表中新增一个用户

INSERT INTO `mqtt_user` ( `username`, `password`, `salt`) VALUES

(‘test’, ‘62a11257d24e7b577b87936eaf7931a0f15bc7b4e52f2c37507b7792c38b6d0c’, ‘secret’);

注意:

密码是经过加密后的密文,如果采用了加盐,需要添加加盐字段,可以在网上搜索加密工具,本文使用的加密工具地址:md5加密,sha1加密--md5在线解密

选择正确的加密方式生成的密码hash值(本文是采用salt+sha256)

3.4.3 验证
3.4.3.1 使用WebSocket工具

使用EMQX Dashboard Websocket工具可以进行简单的客户端连接服务端测试,主题订阅和发布消息。

开启MYSQL认证后,需要通过已创建的用户名和密码连接,否则会显示连接失败。

使用WebSocket工具的SSL连接需要安装客户端证书,否则无法连接,本文推荐使用MQTTX客户端工具进行SSL认证连接测试。

3.4.3.2 MQTTX客户端连接工具

1 安装MQTTX客户端

访问MQTTX:全功能 MQTT 客户端工具下载安装MQTTX客户端

2 打开客户端新建连接

(1)新建一个连接,填写服务端地址、端口号、用户名和密码,开启SSL/TLS双向认证,选择自定义证书,开启SSL Secure。

(2)选择本地客户端证书的位置

点击connect进行连接

MQTTX其他功能可以参考官方文档,在次不做过多介绍

MQTTX:全功能 MQTT 客户端工具

4 发布订阅 ACL

发布订阅 ACL 指对 发布 (PUBLISH)/订阅 (SUBSCRIBE) 操作的 权限控制。例如拒绝用户名为 Anna 向 open/elsa/door 发布消息。

EMQX 支持通过客户端发布订阅 ACL 进行客户端权限的管理,本章节介绍了 EMQX 发布订阅 ACL 以及对应MYSQL插件的配置方法。

4.1 MySQL插件配置

发布订阅 ACL功能包含在emqx_auth_mysql 插件中,在3.2MySQL认证小节中已经开启了此插件,并进行了数据库配置,在此基础上还需进行如下配置。

4.1.1 创建ACL规则表

在emqx数据库中创建acl规则表mqtt_acl

CREATE TABLE `mqtt_acl` (

  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,

  `allow` int(1) DEFAULT 1 COMMENT '0: deny, 1: allow',

  `ipaddr` varchar(60) DEFAULT NULL COMMENT 'IpAddress',

  `username` varchar(100) DEFAULT NULL COMMENT 'Username',

  `clientid` varchar(100) DEFAULT NULL COMMENT 'ClientId',

  `access` int(2) NOT NULL COMMENT '1: subscribe, 2: publish, 3: pubsub',

  `topic` varchar(100) NOT NULL DEFAULT '' COMMENT 'Topic Filter',

  PRIMARY KEY (`id`),

  INDEX (ipaddr),

  INDEX (username),

  INDEX (clientid)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

规则表字段说明:

allow:禁止(0),允许(1)

ipaddr:设置 IP 地址

username:连接客户端的用户名,此处的值如果设置为 $all 表示该规则适用于所有的用户

clientid:连接客户端的 Client ID

access:允许的操作:订阅(1),发布(2),订阅发布都可以(3)

topic:控制的主题,可以使用通配符,并且可以在主题中加入占位符来匹配客户端信息,例如 t/%c 则在匹配时主题将会替换为当前客户端的 Client ID

%u:用户名

%c:Client ID

4.1.2 超级用户 SQL(super_query)

进行 ACL 鉴权时,EMQX 将使用当前客户端信息填充并执行用户配置的超级用户 SQL,查询客户端是否为超级用户。客户端为超级用户时将跳过 ACL SQL。

在etc/plugins/emqx_auth_mysql.conf配置中做如下修改

你可以在 SQL 中使用以下占位符,执行时 EMQX 将自动填充为客户端信息:

%u:用户名

%c:Client ID

%C:TLS 证书公用名(证书的域名或子域名),仅当 TLS 连接时有效

%d:TLS 证书 subject,仅当 TLS 连接时有效

你可以根据业务需要调整超级用户 SQL,如添加多个查询条件、使用数据库预处理函数,以实现更多业务相关的功能。但是任何情况下超级用户 SQL 需要满足以下条件:

(1)查询结果中必须包含 is_superuser 字段,is_superuser 应该显式的为 true;

(2)查询结果只能有一条,多条结果时只取第一条作为有效数据。

提示

如果不需要超级用户功能,注释并禁用该选项能有效提高效率

4.1.3 ACL SQL(acl_query)

进行 ACL 鉴权时,EMQX 将使用当前客户端信息填充并执行用户配置的超级用户 SQL,如果没有启用超级用户 SQL 或客户端不是超级用户,则使用 ACL SQL 查询出该客户端在数据库中的 ACL 规则。

在etc/plugins/emqx_auth_mysql.conf配置中做如下修改

你可以在 ACL SQL 中使用以下占位符,执行时 EMQX 将自动填充为客户端信息:

%u:用户名

%c:Client ID

%C:TLS 证书公用名(证书的域名或子域名),仅当 TLS 连接时有效

%d:TLS 证书 subject,仅当 TLS 连接时有效

你可以根据业务需要调整 ACL SQL,如添加多个查询条件、使用数据库预处理函数,以实现更多业务相关的功能。但是任何情况下 ACL SQL 需要满足以下条件:

查询结果中必须包含 allow、access、topic、clientid、username、ipaddr 字段,如果字段不想参与比对则使用 $all 字符串或者数据库 NULL 值

查询结果可以有多条,多条结果时按照从上到下的顺序进行匹配

提示

可以在 SQL 中调整查询条件、指定排序方式实现更高效率的查询。

4.2 ACL全局配置

修改etc/emqx.conf 中的 ACL 配置

(1)acl_nomatch

 ACL 未匹配时默认授权,deny拒绝授权

(2)acl_file

配置默认 ACL 文件,使用文件定义默认 ACL 规则

(3)acl_deny_action

配置 ACL 授权结果为禁止的响应动作,为 disconnect 时将断开设备

(4)enable_acl_cache

ACL 缓存开关

(5)acl_cache_max_size

单个客户端最大缓存规则数量

(6)acl_cache_ttl

缓存失效时间,超时后缓存将被清除

ACL 缓存允许客户端在命中某条 ACL 规则后,便将其缓存至内存中,以便下次直接使用,客户端发布、订阅频率较高的情况下开启 ACL 缓存可以提高 ACL 检查性能。

4.3 内置ACL配置

通过etc/acl.conf文件配置ACL内置规则

内置 ACL 优先级最低,可以被 ACL 插件覆盖,如需禁用全部注释即可。规则文件更改后需重启 EMQX 以应用生效。

内置 ACL 是优先级最低规则表,在所有的 ACL 检查完成后,如果仍然未命中则检查默认的 ACL 规则。

本文在此配置几条ACL默认规则

(1)允许 "dashboard" 用户 订阅 "$SYS/#" 主题

{allow, {user, "dashboard"}, subscribe, ["$SYS/#"]}.

(2) 允许 IP 地址为 "127.0.0.1" 的用户 发布/订阅 "$SYS/#","#" 主题

{allow, {ipaddr, "127.0.0.1"}, pubsub, ["$SYS/#", "#"]}.

(3)拒绝 "所有用户" 订阅 "$SYS/#" "#" 主题

{deny, all, subscribe, ["$SYS/#", {eq, "#"}]}.

acl.conf具体编写规则请参考官方文档

内置 ACL | EMQX 4.4 文档

将每个节点上述配置修改完毕后重启后生效

重启EMQX节点命令

./bin/emqx restart

4.4 ACL功能验证

使用EMQX Dashboard Websocket工具可以进行简单验证,开启topic发布订阅ACL后,必须在mqtt_acl表中为用户配置topic权限后,用户才可以发布或订阅该topic。

如下图,为test用户赋予test-topic主题的发布订阅权限

使用Websocket工具进行验证:

(1)首先使用test用户连接服务端

(2)连接服务端后尝试订阅其他未授权主题会显示订阅失败,只能订阅test-topic,订阅成功后可以在订阅模块显示订阅信息

 (3)向已授权的指定topic发送信息

(4)向未授权的topic发送消息

向未授权的topic发送消息时在websocket工具界面仍会显示消息已发出,但可以在emqx日志查看到不能向未授权的topic发送消息。

5 EMQX系统优化

5.1 Linux 操作系统参数

1 系统全局允许分配的最大文件句柄数:

# 2 millions system-wide

sysctl -w fs.file-max=2097152

sysctl -w fs.nr_open=2097152

echo 2097152 > /proc/sys/fs/nr_open

2 允许当前会话 / 进程打开文件句柄数:

ulimit -n 1048576

3 /etc/sysctl.conf

持久化 'fs.file-max' 设置到 /etc/sysctl.conf 文件:

fs.file-max = 1048576

4 /etc/systemd/system.conf 设置服务最大文件句柄数

DefaultLimitNOFILE=1048576

5 /etc/security/limits.conf

/etc/security/limits.conf 持久化设置允许用户 / 进程打开文件句柄数:

*      soft   nofile      1048576

*      hard   nofile      1048576

5.2 TCP 协议栈网络参数

1 并发连接 backlog 设置:

sysctl -w net.core.somaxconn=32768

sysctl -w net.ipv4.tcp_max_syn_backlog=16384

sysctl -w net.core.netdev_max_backlog=16384

2 可用知名端口范围:

sysctl -w net.ipv4.ip_local_port_range='1000 65535'

3 TCP Socket 读写 Buffer 设置:

sysctl -w net.core.rmem_default=262144

sysctl -w net.core.wmem_default=262144

sysctl -w net.core.rmem_max=16777216

sysctl -w net.core.wmem_max=16777216

sysctl -w net.core.optmem_max=16777216



sysctl -w net.ipv4.tcp_rmem='1024 4096 16777216'

sysctl -w net.ipv4.tcp_wmem='1024 4096 16777216'

4 TCP 连接追踪设置:

sysctl -w net.netfilter.nf_conntrack_max=1000000

sysctl -w net.netfilter.nf_conntrack_tcp_timeout_time_wait=30

5 TIME-WAIT Socket 最大数量、回收与重用设置:

sysctl -w net.ipv4.tcp_max_tw_buckets=1048576

6 FIN-WAIT-2 Socket 超时设置:

sysctl -w net.ipv4.tcp_fin_timeout=15

5.3 Erlang 虚拟机参数

优化设置 Erlang 虚拟机启动参数,配置文件 emqx/etc/emqx.conf:

## Erlang Process Limit

node.process_limit = 2097152

## Sets the maximum number of simultaneously existing ports for this system

node.max_ports = 1048576

5.4 EMQX 消息服务器参数

ceptor 池大小,最大允许连接数。 emqx/etc/emqx.conf

## TCP Listener

listener.tcp.external = 0.0.0.0:1883

listener.tcp.external.acceptors = 64

listener.tcp.external.max_connections = 1024000

注意:EMQX节点参数的配置需要重启节点后生效

6 附录

6.1 openssl生成证书

6.1.1 生成自签名 CA 证书

首先,我们需要一个自签名的 CA 证书。生成这个证书需要有一个私钥为它签名,可以执行以下命令来生成私钥:

openssl genrsa -out ca.key 2048

这个命令将生成一个密钥长度为 2048 的密钥并保存在 ca.key 中。有了这个密钥,就可以用它来生成 EMQX 的根证书了:

openssl req -x509 -new -nodes -key ca.key -sha256 -days 3650 -out ca.pem

根证书是整个信任链的起点,如果一个证书的每一级签发者向上一直到根证书都是可信的,那个我们就可以认为这个证书也是可信的。有了这个根证书,我们就可以用它来给其他实体签发实体证书了。

6.1.2 生成服务端证书

实体(在这里指的是 EMQX)也需要一个自己的私钥对来保证它对自己证书的控制权。生成这个密钥的过程和上面类似:

openssl genrsa -out emqx.key 2048

新建 openssl.cnf 文件,

req_distinguished_name :根据情况进行修改,

alt_names: BROKER_ADDRESS 修改为 EMQX 服务器实际的 IP 或 DNS 地址,例如:IP.1 = 127.0.0.1,或 DNS.1 = broker.xxx.com

注意:IP 和 DNS 二者保留其一即可,如果已购买域名,只需保留 DNS 并修改为你所使用的域名地址。

[req]

default_bits  = 2048

distinguished_name = req_distinguished_name

req_extensions = req_ext

x509_extensions = v3_req

prompt = no

[req_distinguished_name]

countryName = CN

stateOrProvinceName = Zhejiang

localityName = Hangzhou

organizationName = EMQX

commonName = CA

[req_ext]

subjectAltName = @alt_names

[v3_req]

subjectAltName = @alt_names

[alt_names]

IP.1 = BROKER_ADDRESS

DNS.1 = BROKER_ADDRESS

然后以这个密钥和配置签发一个证书请求:

openssl req -new -key ./emqx.key -config openssl.cnf -out emqx.csr

然后以根证书来签发 EMQX 的实体证书:

openssl x509 -req -in ./emqx.csr -CA ca.pem -CAkey ca.key -CAcreateserial -out emqx.pem -days 3650 -sha256 -extensions v3_req -extfile openssl.cnf
6.1.3 生成客户端证书

双向连接认证还需要创建客户端证书,首先需要创建客户端密钥:

openssl genrsa -out client.key 2048

使用生成的客户端密钥来创建一个客户端请求文件:

openssl req -new -key client.key -out client.csr -subj "/C=CN/ST=Zhejiang/L=Hangzhou/O=EMQX/CN=client"

最后使用先前生成好的服务端 CA 证书来给客户端签名,生成一个客户端证书:

openssl x509 -req -days 3650 -in client.csr -CA ca.pem -CAkey ca.key -CAcreateserial -out client.pem

准备好服务端和客户端证书后,我们就可以在 EMQX 中启用 TLS/SSL 双向认证功能。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/zhangzhanghaohao94/article/details/137784504

智能推荐

分布式光纤传感器的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告_预计2026年中国分布式传感器市场规模有多大-程序员宅基地

文章浏览阅读3.2k次。本文研究全球与中国市场分布式光纤传感器的发展现状及未来发展趋势,分别从生产和消费的角度分析分布式光纤传感器的主要生产地区、主要消费地区以及主要的生产商。重点分析全球与中国市场的主要厂商产品特点、产品规格、不同规格产品的价格、产量、产值及全球和中国市场主要生产商的市场份额。主要生产商包括:FISO TechnologiesBrugg KabelSensor HighwayOmnisensAFL GlobalQinetiQ GroupLockheed MartinOSENSA Innovati_预计2026年中国分布式传感器市场规模有多大

07_08 常用组合逻辑电路结构——为IC设计的延时估计铺垫_基4布斯算法代码-程序员宅基地

文章浏览阅读1.1k次,点赞2次,收藏12次。常用组合逻辑电路结构——为IC设计的延时估计铺垫学习目的:估计模块间的delay,确保写的代码的timing 综合能给到多少HZ,以满足需求!_基4布斯算法代码

OpenAI Manager助手(基于SpringBoot和Vue)_chatgpt网页版-程序员宅基地

文章浏览阅读3.3k次,点赞3次,收藏5次。OpenAI Manager助手(基于SpringBoot和Vue)_chatgpt网页版

关于美国计算机奥赛USACO,你想知道的都在这_usaco可以多次提交吗-程序员宅基地

文章浏览阅读2.2k次。USACO自1992年举办,到目前为止已经举办了27届,目的是为了帮助美国信息学国家队选拔IOI的队员,目前逐渐发展为全球热门的线上赛事,成为美国大学申请条件下,含金量相当高的官方竞赛。USACO的比赛成绩可以助力计算机专业留学,越来越多的学生进入了康奈尔,麻省理工,普林斯顿,哈佛和耶鲁等大学,这些同学的共同点是他们都参加了美国计算机科学竞赛(USACO),并且取得过非常好的成绩。适合参赛人群USACO适合国内在读学生有意向申请美国大学的或者想锻炼自己编程能力的同学,高三学生也可以参加12月的第_usaco可以多次提交吗

MySQL存储过程和自定义函数_mysql自定义函数和存储过程-程序员宅基地

文章浏览阅读394次。1.1 存储程序1.2 创建存储过程1.3 创建自定义函数1.3.1 示例1.4 自定义函数和存储过程的区别1.5 变量的使用1.6 定义条件和处理程序1.6.1 定义条件1.6.1.1 示例1.6.2 定义处理程序1.6.2.1 示例1.7 光标的使用1.7.1 声明光标1.7.2 打开光标1.7.3 使用光标1.7.4 关闭光标1.8 流程控制的使用1.8.1 IF语句1.8.2 CASE语句1.8.3 LOOP语句1.8.4 LEAVE语句1.8.5 ITERATE语句1.8.6 REPEAT语句。_mysql自定义函数和存储过程

半导体基础知识与PN结_本征半导体电流为0-程序员宅基地

文章浏览阅读188次。半导体二极管——集成电路最小组成单元。_本征半导体电流为0

随便推点

【Unity3d Shader】水面和岩浆效果_unity 岩浆shader-程序员宅基地

文章浏览阅读2.8k次,点赞3次,收藏18次。游戏水面特效实现方式太多。咱们这边介绍的是一最简单的UV动画(无顶点位移),整个mesh由4个顶点构成。实现了水面效果(左图),不动代码稍微修改下参数和贴图可以实现岩浆效果(右图)。有要思路是1,uv按时间去做正弦波移动2,在1的基础上加个凹凸图混合uv3,在1、2的基础上加个水流方向4,加上对雾效的支持,如没必要请自行删除雾效代码(把包含fog的几行代码删除)S..._unity 岩浆shader

广义线性模型——Logistic回归模型(1)_广义线性回归模型-程序员宅基地

文章浏览阅读5k次。广义线性模型是线性模型的扩展,它通过连接函数建立响应变量的数学期望值与线性组合的预测变量之间的关系。广义线性模型拟合的形式为:其中g(μY)是条件均值的函数(称为连接函数)。另外,你可放松Y为正态分布的假设,改为Y 服从指数分布族中的一种分布即可。设定好连接函数和概率分布后,便可以通过最大似然估计的多次迭代推导出各参数值。在大部分情况下,线性模型就可以通过一系列连续型或类别型预测变量来预测正态分布的响应变量的工作。但是,有时候我们要进行非正态因变量的分析,例如:(1)类别型.._广义线性回归模型

HTML+CSS大作业 环境网页设计与实现(垃圾分类) web前端开发技术 web课程设计 网页规划与设计_垃圾分类网页设计目标怎么写-程序员宅基地

文章浏览阅读69次。环境保护、 保护地球、 校园环保、垃圾分类、绿色家园、等网站的设计与制作。 总结了一些学生网页制作的经验:一般的网页需要融入以下知识点:div+css布局、浮动、定位、高级css、表格、表单及验证、js轮播图、音频 视频 Flash的应用、ul li、下拉导航栏、鼠标划过效果等知识点,网页的风格主题也很全面:如爱好、风景、校园、美食、动漫、游戏、咖啡、音乐、家乡、电影、名人、商城以及个人主页等主题,学生、新手可参考下方页面的布局和设计和HTML源码(有用点赞△) 一套A+的网_垃圾分类网页设计目标怎么写

C# .Net 发布后,把dll全部放在一个文件夹中,让软件目录更整洁_.net dll 全局目录-程序员宅基地

文章浏览阅读614次,点赞7次,收藏11次。之前找到一个修改 exe 中 DLL地址 的方法, 不太好使,虽然能正确启动, 但无法改变 exe 的工作目录,这就影响了.Net 中很多获取 exe 执行目录来拼接的地址 ( 相对路径 ),比如 wwwroot 和 代码中相对目录还有一些复制到目录的普通文件 等等,它们的地址都会指向原来 exe 的目录, 而不是自定义的 “lib” 目录,根本原因就是没有修改 exe 的工作目录这次来搞一个启动程序,把 .net 的所有东西都放在一个文件夹,在文件夹同级的目录制作一个 exe._.net dll 全局目录

BRIEF特征点描述算法_breif description calculation 特征点-程序员宅基地

文章浏览阅读1.5k次。本文为转载,原博客地址:http://blog.csdn.net/hujingshuang/article/details/46910259简介 BRIEF是2010年的一篇名为《BRIEF:Binary Robust Independent Elementary Features》的文章中提出,BRIEF是对已检测到的特征点进行描述,它是一种二进制编码的描述子,摈弃了利用区域灰度..._breif description calculation 特征点

房屋租赁管理系统的设计和实现,SpringBoot计算机毕业设计论文_基于spring boot的房屋租赁系统论文-程序员宅基地

文章浏览阅读4.1k次,点赞21次,收藏79次。本文是《基于SpringBoot的房屋租赁管理系统》的配套原创说明文档,可以给应届毕业生提供格式撰写参考,也可以给开发类似系统的朋友们提供功能业务设计思路。_基于spring boot的房屋租赁系统论文