文章目录

  • 项目名称:基于Docker Swarm的高可用Web集群
  • 网络拓扑图
  • 数据流程图
  • 项目环境:Docker 20.10.3,CentOS 8.2(8台 1核1G),Ansible 2.9.17,Keepalived,Nginx 1.19.7,NFS
  • 项目描述:
    • 实现一个高可用的负载均衡Web服务器集群,融入Ansible实现自动化运维,后端采用Swarm管理的Docker集群来提供Web服务,大量使用容器来完成Web服务的扩展性、高可用性。
  • 项目步骤:
    • 1.规划设计整个集群的架构、网络拓扑,安装好8台CentOS 8.2的系统,部署好Ansible服务器,在所有的机器之间配置ssh免密通道;
    • 2.负载均衡器部署好Keepalived,为内网提供网关,实现内网访问外网的功能;
    • 3.编写好制作Nginx容器 镜像的脚本(编译安装Nginx),指定参数(如:安装路径等),里面可以使用netstat,vim,ping,ip等命令;
    • 4.编写好部署Docker,Docker镜像,Nginx,Keepalived,NFS的脚本,编写Ansible的Playbook实现批量部署;
    • 5.前端使用Nginx做负载均衡、Keepalived的双vip实现高可用,后端使用Swarm来实现负载均衡和高可用;
    • 6.使用NFS服务为所有的Docker节点提供相同的Web数据,实现数据一致性;
    • 7.后端采用Swarm来管理整个Docker集群,在Swarm manager节点上创建40个Nginx容器的副本,并使用Volume(挂载目录到NFS服务器下)来提供Web服务,达到所有容器都使用相同的数据;
    • 8.访问测试、整理文档。
  • 项目心得:
    • 1.提前规划好整个集群的架构,可以提高项目开展时效率;
    • 2.对本地hosts文件进行DNS集群域名解析记录,效果并不明显,考虑在前面加一个负载均衡器,实现论询效果;
    • 3.通过整个项目更加深刻的理解了Docker的相关技术,使用Docker的集群解决方案比传统的集群解决方案更加快捷方便,Docker内部的高可用和负载均衡也非常不错;
    • 4.通过实验锻炼了自己细心和trouble shooting的能力。

个人博客
https://blog.csdn.net/cPen_web


项目名称:基于Docker Swarm的高可用Web集群


网络拓扑图

数据流程图

项目环境:Docker 20.10.3,CentOS 8.2(8台 1核1G),Ansible 2.9.17,Keepalived,Nginx 1.19.7,NFS

项目描述:

实现一个高可用的负载均衡Web服务器集群,融入Ansible实现自动化运维,后端采用Swarm管理的Docker集群来提供Web服务,大量使用容器来完成Web服务的扩展性、高可用性。


项目步骤:

1.规划设计整个集群的架构、网络拓扑,安装好8台CentOS 8.2的系统,部署好Ansible服务器,在所有的机器之间配置ssh免密通道;

[root@ansible ~]# ssh-keygen -t ecdsa           # 生成密钥对
[root@ansible ~]# ssh-copy-id -i ~/.ssh/id_ecdsa.pub 192.168.55.210        # loadbalancer-1
[root@ansible ~]# ssh-copy-id -i ~/.ssh/id_ecdsa.pub 192.168.55.220        # loadbalancer-2
[root@ansible ~]# ssh-copy-id -i ~/.ssh/id_ecdsa.pub 192.168.55.10     # NFS-Server
[root@ansible ~]# ssh-copy-id -i ~/.ssh/id_ecdsa.pub 192.168.55.1      # Swarm manager1
[root@ansible ~]# ssh-copy-id -i ~/.ssh/id_ecdsa.pub 192.168.55.2      # Swarm node2
[root@ansible ~]# ssh-copy-id -i ~/.ssh/id_ecdsa.pub 192.168.55.3      # Swarm node3
[root@ansible ~]# ssh-copy-id -i ~/.ssh/id_ecdsa.pub 192.168.55.4      # Swarm node4

目的:让内网能够ping通外网

[root@loadbalancer-1 ~]# vim iptables_snat.sh
#!/bin/bashservice firewalld stop
systemctl disable firewalldecho 1 >/proc/sys/net/ipv4/ip_forward
iptables -F
iptables -F -t natiptables -t nat -A POSTROUTING -s 192.168.55.0/24 -o ens33 -j SNAT --to-source 192.168.0.198
#iptables -t nat -A POSTROUTING -s 192.168.55.0/24 -o ens33 -j MASQUERADE[root@loadbalancer-1 ~]# bash iptables_snat.sh
[root@loadbalancer-2 ~]# vim iptables_snat.sh
#!/bin/bashservice firewalld stop
systemctl disable firewalldecho 1 >/proc/sys/net/ipv4/ip_forward
iptables -F
iptables -F -t natiptables -t nat -A POSTROUTING -s 192.168.55.0/24 -o ens33 -j SNAT --to-source 192.168.0.199
#iptables -t nat -A POSTROUTING -s 192.168.55.0/24 -o ens33 -j MASQUERADE[root@loadbalancer-2 ~]# bash iptables_snat.sh

2.负载均衡器部署好Keepalived,为内网提供网关,实现内网访问外网的功能;

目的:让内网能够ping通外网

[root@loadbalancer-1 ~]# yum install keepalived -y
[root@loadbalancer-1 ~]# vim /etc/keepalived/keepalived.conf
[root@loadbalancer-1 ~]# cat /etc/keepalived/keepalived.conf
! Configuration File for keepalivedglobal_defs {notification_email {acassen@firewall.locfailover@firewall.locsysadmin@firewall.loc}notification_email_from Alexandre.Cassen@firewall.locsmtp_server 192.168.200.1smtp_connect_timeout 30router_id LVS_DEVELvrrp_skip_check_adv_addr#vrrp_strictvrrp_garp_interval 0vrrp_gna_interval 0
}vrrp_instance VI_3 {state MASTERinterface ens33virtual_router_id 201priority 110advert_int 1authentication {auth_type PASSauth_pass 123456}virtual_ipaddress {192.168.55.254}
}
[root@loadbalancer-1 ~]# service keepalived restart
[root@loadbalancer-2 ~]# yum install keepalived -y
[root@loadbalancer-2 ~]# vim /etc/keepalived/keepalived.conf
[root@loadbalancer-2 ~]# cat /etc/keepalived/keepalived.conf
! Configuration File for keepalivedglobal_defs {notification_email {acassen@firewall.locfailover@firewall.locsysadmin@firewall.loc}notification_email_from Alexandre.Cassen@firewall.locsmtp_server 192.168.200.1smtp_connect_timeout 30router_id LVS_DEVELvrrp_skip_check_adv_addr#vrrp_strictvrrp_garp_interval 0vrrp_gna_interval 0
}vrrp_instance VI_3 {state BACKUPinterface ens33virtual_router_id 201priority 100advert_int 1authentication {auth_type PASSauth_pass 123456}virtual_ipaddress {192.168.55.254}
}
[root@loadbalancer-2 ~]# service keepalived restart

3.编写好制作Nginx容器 镜像的脚本(编译安装Nginx),指定参数(如:安装路径等),里面可以使用netstat,vim,ping,ip等命令;

[root@ansible ~]# cat onekey_build_nginx_images.sh
#!/bin/bashcurl -O http://nginx.org/download/nginx-1.19.7.tar.gz# 编译安装脚本
cat >onekey_install_nginx.sh <<EOF
#!/bin/bash#解决软件的依赖关系,需要安装的软件包
yum -y install zlib zlib-devel openssl openssl-devel pcre pcre-devel gcc gcc-c++ autoconf automake make
#download nginx
mkdir -p /nginx
cd /nginx
#解压 下载的nginx的源码包
tar xf nginx-1.19.7.tar.gz
cd nginx-1.19.7
#生成编译前配置工作 --> Makefile
./configure --prefix=/usr/local/nginx --with-threads --with-http_ssl_module --with-http_realip_module  --with-http_v2_module --with-file-aio  --with-http_stub_status_module --with-stream
#编译
make
#编译安装 --> 将编译好的二进制程序安装到指定目录 /usr/local/nginx1
make install
EOF# 编写Dockerfile
cat >Dockerfile <<EOF
FROM centos:latest
ENV NGINX_VERSION   1.19.7
ENV OS_VERSION   1.0
LABEL maintainer="chenpeng <1533431376@qq.com>"WORKDIR /nginx
COPY . .
RUN bash onekey_install_nginx.sh; \yum install net-tools iproute iputils vim -y
EXPOSE 80STOPSIGNAL SIGQUIT
ENV PATH /usr/local/nginx/sbin:$PATH
CMD ["nginx", "-g", "daemon off;"]
EOF# 制作镜像
docker build -t centos-nginx:1.0 .

4.编写好部署Docker,Docker镜像,Nginx,Keepalived,NFS的脚本,编写Ansible的Playbook实现批量部署;

[root@ansible ~]# yum install epel-release -y
[root@ansible ~]# yum install ansible -y
[root@ansible ~]# cat /etc/ansible/hosts
[docker-swarm]
192.168.55.1
192.168.55.2
192.168.55.3
192.168.55.4[loadbalancer]
192.168.55.210
192.168.55.220[nfs]
192.168.55.10
192.168.55.1
192.168.55.2
192.168.55.3
192.168.55.4
[root@ansible ~]# cat ansible_playbook.yaml
- hosts: docker-swarmremote_user: roottasks:- name: deploy dockerscript: ~/install_docker.sh- name: build docker-imagesscript: ~/onekey_build_nginx_images.sh- hosts: loadbalancerremote_user: roottasks:- name: deploy keepalivedscript: ~/install_keepalived.sh- name: deploy nginxscript: ~/onekey_install_nginx.sh- hosts: nfsremote_user: roottasks:- name: install nfs-utilsscript: ~/install_nfs.sh[root@ansible ~]# ansible-playbook ansible_playbook.yaml

使用ansible实现批量部署 效果图

部署Docker的脚本

[root@ansible ~]# cat install_docker.sh
#!/bin/bashyum install yum-utils -y
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
systemctl start docker
systemctl enable dockersetenforce 0
sed -i '/^SELINUX=/ s/enforcing/disabled/' /etc/sysconfig/selinux

部署Nginx的脚本

[root@ansible ~]# cat onekey_install_nginx.sh
#!/bin/bash#解决软件的依赖关系,需要安装的软件包
yum -y install zlib zlib-devel openssl openssl-devel pcre pcre-devel gcc gcc-c++ autoconf automake make
#useradd cPen
id cPen || useradd -s /sbin/nologin cPen
#download nginx
mkdir -p /nginx
cd /nginx
curl -O http://nginx.org/download/nginx-1.19.7.tar.gz
#解压 下载的nginx的源码包
tar xf nginx-1.19.7.tar.gz
cd nginx-1.19.7
#生成编译前配置工作 --> Makefile
./configure --prefix=/usr/local/nginx  --user=cPen  --group=cPen --with-threads --with-http_ssl_module  --with-http_realip_module  --with-http_v2_module --with-file-aio  --with-http_stub_status_module --with-stream
#编译
make -j 2
#编译安装 --> 将编译好的二进制程序安装到指定目录 /usr/local/nginx1
make install#修改PATH变量
echo "PATH=$PATH:/usr/local/nginx/sbin" >>/root/.bashrc
#执行修改了环境变量的脚本
source /root/.bashrc#启动nginx
/usr/local/nginx/sbin/nginx#firewalld and selinux#stop firewalld和设置下次开机不启动firewalld
service firewalld stop
systemctl disable firewalld#临时停止selinux和永久停止selinux
setenforce 0
sed -i '/^SELINUX=/ s/enforcing/disabled/' /etc/sysconfig/selinux#开机自启
echo "/usr/local/nginx/sbin/nginx" >>/etc/rc.local
chmod +x /etc/rc.d/rc.local

制作Docker镜像的脚本

[root@ansible ~]# cat onekey_build_nginx_images.sh
#!/bin/bashcurl -O http://nginx.org/download/nginx-1.19.7.tar.gz# 编译安装脚本
cat >onekey_install_nginx.sh <<EOF
#!/bin/bash#解决软件的依赖关系,需要安装的软件包
yum -y install zlib zlib-devel openssl openssl-devel pcre pcre-devel gcc gcc-c++ autoconf automake make
#download nginx
mkdir -p /nginx
cd /nginx
#解压 下载的nginx的源码包
tar xf nginx-1.19.7.tar.gz
cd nginx-1.19.7
#生成编译前配置工作 --> Makefile
./configure --prefix=/usr/local/nginx --with-threads --with-http_ssl_module --with-http_realip_module  --with-http_v2_module --with-file-aio  --with-http_stub_status_module --with-stream
#编译
make
#编译安装 --> 将编译好的二进制程序安装到指定目录 /usr/local/nginx1
make install
EOF# 编写Dockerfile
cat >Dockerfile <<EOF
FROM centos:latest
ENV NGINX_VERSION   1.19.7
ENV OS_VERSION   1.0
LABEL maintainer="chenpeng <1533431376@qq.com>"WORKDIR /nginx
COPY . .
RUN bash onekey_install_nginx.sh; \yum install net-tools iproute iputils vim -y
EXPOSE 80STOPSIGNAL SIGQUIT
ENV PATH /usr/local/nginx/sbin:$PATH
CMD ["nginx", "-g", "daemon off;"]
EOF# 制作镜像
docker build -t centos-nginx:1.0 .

部署Keepalived的脚本

[root@ansible ~]# cat install_keepalived.sh
#!/bin/bash#安装keepalived
yum install keepalived -y#关闭防火墙
service firewalld stop
systemctl disable firewalld

部署NFS的脚本

[root@ansible ~]# cat install_nfs.sh
#!/bin/bashyum install nfs-utils -y
service nfs-server start
systemctl enable nfs-serversetenforce 0
sed -i '/^SELINUX=/ s/enforcing/disabled/' /etc/sysconfig/selinux
service firewalld stop
systemctl disable firewalld

5.前端使用Nginx做负载均衡、Keepalived的双vip实现高可用,后端使用Swarm来实现负载均衡和高可用;

Nginx做7层负载均衡

[root@loadbalancer-1 ~]# vim /usr/local/nginx/conf/nginx.confupstream myweb {server 192.168.55.1;server 192.168.55.2;server 192.168.55.3;server 192.168.55.4;}server {listen       80;server_name  www.web_cPen.com;location / {proxy_pass  http://myweb;}[root@loadbalancer-1 ~]# nginx -s reload
[root@loadbalancer-2 ~]# vim /usr/local/nginx/conf/nginx.confupstream myweb {server 192.168.55.1;server 192.168.55.2;server 192.168.55.3;server 192.168.55.4;}server {listen       80;server_name  www.web_cPen.com;location / {proxy_pass  http://myweb;}[root@loadbalancer-2 ~]# nginx -s reload

Keepalived的双vip配置

[root@loadbalancer-1 ~]# cat /etc/keepalived/keepalived.conf
! Configuration File for keepalivedglobal_defs {notification_email {acassen@firewall.locfailover@firewall.locsysadmin@firewall.loc}notification_email_from Alexandre.Cassen@firewall.locsmtp_server 192.168.200.1smtp_connect_timeout 30router_id LVS_DEVELvrrp_skip_check_adv_addr#vrrp_strictvrrp_garp_interval 0vrrp_gna_interval 0
}vrrp_instance VI_3 {state MASTERinterface ens33virtual_router_id 201priority 110advert_int 1authentication {auth_type PASSauth_pass 123456}virtual_ipaddress {192.168.55.254}
}vrrp_instance VI_1 {state MASTERinterface ens33virtual_router_id 199priority 110advert_int 1authentication {auth_type PASSauth_pass 123456}virtual_ipaddress {192.168.0.154}
}vrrp_instance VI_2 {state BACKUPinterface ens33virtual_router_id 200priority 100advert_int 1authentication {auth_type PASSauth_pass 123456}virtual_ipaddress {192.168.0.155}
}[root@loadbalancer-1 ~]# service keepalived restart
[root@loadbalancer-2 ~]# cat /etc/keepalived/keepalived.conf
! Configuration File for keepalivedglobal_defs {notification_email {acassen@firewall.locfailover@firewall.locsysadmin@firewall.loc}notification_email_from Alexandre.Cassen@firewall.locsmtp_server 192.168.200.1smtp_connect_timeout 30router_id LVS_DEVELvrrp_skip_check_adv_addr#vrrp_strictvrrp_garp_interval 0vrrp_gna_interval 0
}vrrp_instance VI_3 {state BACKUPinterface ens33virtual_router_id 201priority 100advert_int 1authentication {auth_type PASSauth_pass 123456}virtual_ipaddress {192.168.55.254}
}vrrp_instance VI_1 {state BACKUPinterface ens33virtual_router_id 199priority 100advert_int 1authentication {auth_type PASSauth_pass 123456}virtual_ipaddress {192.168.0.154}
}vrrp_instance VI_2 {state MASTERinterface ens33virtual_router_id 200priority 110advert_int 1authentication {auth_type PASSauth_pass 123456}virtual_ipaddress {192.168.0.155}
}[root@loadbalancer-2 ~]# service keepalived restart

6.使用NFS服务为所有的Docker节点提供相同的Web数据,实现数据一致性;

NFS-Server共享文件

[root@nfs-server ~]# service nfs-server restart
[root@nfs-server ~]# systemctl enable nfs-server
[root@nfs-server ~]# cat /etc/exports
/web  192.168.55.0/24(rw,all_squash,sync)
[root@nfs-server ~]# mkdir /web
[root@nfs-server ~]# echo "welcome to www.web_test.com" >/web/index.html
[root@nfs-server ~]# chmod 777 /web
[root@nfs-server ~]# exportfs -rv

7.后端采用Swarm来管理整个Docker集群,在Swarm manager节点上创建40个Nginx容器的副本,并使用Volume(挂载目录到NFS服务器下)来提供Web服务,达到所有容器都使用相同的数据;

[root@ansible ~]# cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.50.1  manager1
192.168.50.2  node2
192.168.50.3  node3
192.168.50.4  node4
[root@ansible ~]# scp /etc/hosts 192.168.55.1:/etc/hosts
[root@ansible ~]# scp /etc/hosts 192.168.55.2:/etc/hosts
[root@ansible ~]# scp /etc/hosts 192.168.55.3:/etc/hosts
[root@ansible ~]# scp /etc/hosts 192.168.55.4:/etc/hosts

创建Swarm集群

[root@manager-1 ~]# service firewalld stop
[root@manager-1 ~]# docker swarm init --advertise-addr 192.168.55.1
Swarm initialized: current node (8xl5paxx507g8dcb8fdima7qm) is now a manager.To add a worker to this swarm, run the following command:docker swarm join --token SWMTKN-1-3k05xqndk80tbjmhp0jy1875bkvu3w2x3u3xizsmmr5dbrx0ze-0ptold2kyw0oobung79jjz71e 192.168.55.1:2377To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

添加节点主机到Swarm集群

[root@node-2 ~]# service firewalld stop
[root@node-2 ~]# docker swarm join --token SWMTKN-1-3k05xqndk80tbjmhp0jy1875bkvu3w2x3u3xizsmmr5dbrx0ze-0ptold2kyw0oobung79jjz71e 192.168.55.1:2377
This node joined a swarm as a worker.
[root@node-3 ~]# service firewalld stop
[root@node-3 ~]# docker swarm join --token SWMTKN-1-3k05xqndk80tbjmhp0jy1875bkvu3w2x3u3xizsmmr5dbrx0ze-0ptold2kyw0oobung79jjz71e 192.168.55.1:2377
This node joined a swarm as a worker.
[root@node-4 ~]# service firewalld stop
Redirecting to /bin/systemctl stop firewalld.service
[root@node-4 ~]# docker swarm join --token SWMTKN-1-3k05xqndk80tbjmhp0jy1875bkvu3w2x3u3xizsmmr5dbrx0ze-0ptold2kyw0oobung79jjz71e 192.168.55.1:2377
This node joined a swarm as a worker.

Swarm批量起容器

[root@manager-1 ~]# docker service create -d \
>   --name web-service \
>   --mount 'type=volume,source=nfsvolume,target=/usr/local/nginx/html,volume-driver=local,volume-opt=type=nfs,volume-opt=device=:/web,"volume-opt=o=addr=192.168.55.10,rw,nfsvers=4,async"' \
>   --replicas 40  \
>   -p 80:80 \
>   centos-nginx:1.0

8.访问测试、整理文档。

修改Windows物理机本地hosts文件,模仿云服务器DNS集群域名解析
C:\Windows\System32\drivers\etc\hosts

192.168.0.154  www.web_test.com
192.168.0.155  www.web_test.com

浏览器访问 效果图


项目心得:

1.提前规划好整个集群的架构,可以提高项目开展时效率;

2.对本地hosts文件进行DNS集群域名解析记录,效果并不明显,考虑在前面加一个负载均衡器,实现论询效果;

3.通过整个项目更加深刻的理解了Docker的相关技术,使用Docker的集群解决方案比传统的集群解决方案更加快捷方便,Docker内部的高可用和负载均衡也非常不错;

4.通过实验锻炼了自己细心和trouble shooting的能力。

03_项目-基于Docker Swarm的高可用Web集群相关推荐

  1. 项目 - 基于Docker Swarm的高可用Web集群

    目录 项目名称:基于Docker Swarm的高可用Web集群 项目环境:Docker 20.10.3,CentOS 8.2 (8台 1核1G),Ansible 2.9.17,Keepalived,N ...

  2. 项目名称:基于Docker Swarm的高可用Web集群

    文章目录 项目名称:基于Docker Swarm的高可用Web集群 网络拓扑图 数据流程图 项目环境:Docker 20.10.3,CentOS 8.2(8台 1核1G),Ansible 2.9.17 ...

  3. 基于nginx的高可用web集群

    文章目录 一.写在前面 编译下载 nginx.conf文件解析 安装好后的操作 日志问题,不同级别的错误 二.环境搭建学习 web服务器配置 错误页面跳转 IO多路复用 在nginx里部署https服 ...

  4. corosync+pacemaker+crmsh的高可用web集群的实现

    网络规划: node1:eth0:172.16.31.10/16 node2: eth0: 172.16.31.11/16 nfs:   eth0: 172.16.31.12/15 注: nfs在提供 ...

  5. heartbeat v2版CRM的高可用web集群的实现

    接上一篇文章:heartbeat v1版CRM的高可用集群的实现 架构图: 网络地址规划: 一.关闭heartbeat服务 node1和node2都需要关闭: # service heartbeat ...

  6. heartbeat v1版CRM的高可用web集群的实现

    实验环境规划: 实验环境: CentOS release 6.6(Final)  三台 IP地址: Node1: eth0:172.16.31.10/16 Node2:  eth0:172.16.31 ...

  7. 搭建基于Heartbeat v2+NFS的高可用Web集群

    1.实验环境 HA1:192.168.1.17(RHEL5.8_32bit,web server) HA2:192.168.1.18(RHEL5.8_32bit,web server) NFS:192 ...

  8. 使用Docker Compose部署基于Sentinel的高可用Redis集群

    大家一定非常熟悉如何利用Docker启动单个Redis容器用于开发环境,本文将介绍如何利用Docker Compose模板在本机和云端部署基于Sentinel的高可用Redis 3集群. Redis集 ...

  9. 基于 Docker 的 Redis 高可用集群搭建(redis-sentinel)

    前言   之前介绍了用docker来搭建redis主从环境,但这只是对数据添加了从库备份(主从复制),当主库down掉的时候,从库是不会自动升级为主库的,也就是说,该redis主从集群并非是高可用的. ...

最新文章

  1. 解决Visual Studio For Mac Restore失败的问题
  2. 2017杭州·云栖大会第二天:阿里云发布了这些“黑科技”
  3. Keras:保存模型并载入模型继续训练
  4. 本文详解5G是个什么鬼,程序员都准备好了吗?
  5. 纯粹数学:哈代的世外桃源
  6. CVE-2017-10271 WebLogic XMLDecoder反序列化漏洞
  7. 使用EasyMock
  8. 去除字符串中的html标记
  9. Web应用测试(一)Selenium介绍及环境搭建
  10. N1网络命令-ping
  11. #美化ggplot2生成的原始图片至清爽的感觉
  12. 戴尔N5110装WIN10的体验
  13. 我不曾忘记的初心-屌丝逆袭
  14. ionic android 证书,Ionic 5/Angular Android和iOS 指纹认证
  15. iOS AudioQueue实现音频的录制和播放(附Demo)
  16. 百度云不限速下载(官方渠道,无风险)
  17. 精心收集的95个超实用的JavaScript代码片段(ES6 +编写)
  18. 开启邮箱的SMTP服务获取授权码(QQ邮箱、163邮箱)
  19. 几种将将虚幻引擎内容流送到多个平台的推流方案比较
  20. 踩坑之ios手机new Date(yyyy-MM-dd hh:mm:ss).getTime()返回NaN

热门文章

  1. CSS中清除浮动的代码
  2. 【学习日记】接口安全
  3. Oracle入门(二)
  4. 37种传感器(十四)之循迹模块+Stduino NanoUNO
  5. 岗位述职报告PPT怎么做?
  6. UCINET入门案例
  7. 基于内容的电影推荐:用户画像
  8. 【布局优化】基于布谷鸟算法实现无线传感器网(WSN)覆盖优化 Matlab源码
  9. Mac 搭建本地Apache服务器
  10. 融云亮相 CDEC2021 上海站 全场景通信能力赋能企业数字升级