Issues 写博客挺不错。
新的博客地址(已运行一年,应该不会再动了):https://memos.ecss.dev
个人博客
Issues 写博客挺不错。
新的博客地址(已运行一年,应该不会再动了):https://memos.ecss.dev
在安全和和开发领域,日志可以反映出持续可能存在的安全隐患,性能问题,以及各种事件,有利于程序的改进和测试。
通过日志,事后我们可以很轻松的发现问题的原因,并快速对问题源做出修改。
log4js 的官方文档:https://log4js-node.github.io/log4js-node/
基本使用方法,使用 logger 打印出一段字符串,调用 getLogger 获取 logger 的实例:
const log4js = require('log4js')
const logger = log4js.getLogger()
logger.debug('这是一个测试信息')
日志有不同的等级,每个等级又有不同的比重, 从低到高为:
1: TRACE
2: DEBUG
3: INFO
4: WARN
5: ERROR
6: FATAL
7: MARK
在 log4js 中有一个概念是 category(类型),通过类型可以查看日志来源哪个模块,或者自定义类型的配置。
const log4js = require('log4js')
const logger = log4js.getLogger('abc')
logger.debug('此时 logger 的类型是 abc')
如果你希望将日志输出到一个文件,或者自定义一些配置,你可以配置 Appender 完成。
下面是 log4js 默认的 Appender 配置,在默认的情况下,所有的日志都会输出到控制台:
defaultConfig = {
appenders: [{
type: "console"
}]
}
你也可以创建自己的 Appender 配置,通过 log4js 的 configuration 方法:
log4js.configure({
appenders: {
out: {
type: 'stdout'
},
info: {
type: 'file',
filename: 'logs/info.log',
maxLogSize: 52428800
}
}
})
施工中。。。
据需求不同,这里主要介绍通过 requests 库的 get 返回的状态代码,判断请求成功。
假设有一个 url,需要使用测试检查 url 请求是否成功。
def test1():
url = 'http://localhost:5000/'
response = requests.get(url=url)
# 请求是否成功,200 状态码(OK)
self.assertEqual(200, response.status_code)
什么是 Firewalld:它是 Centos 或类似系统下默认的防火墙系统,类似于 Ubuntu 的 ufw 系统。
使用 Firewalld 添加的出入站规则可以直接在运行环境中启用,不需要重启服务本身。
使用 Firewalld 提供的接口可以为服务,应用,和用户轻松的配置任何规则。
通过分离永久和内存中的规则,可以使用户实时对添加的规则进行评估。任何非永久添加的规则都会在下一次的热加载或服务重启时消失。而任何永久的规则会在重载后得以保留。通过这种方式,用户可以添加一些临时的设置。而如果配置已被评估完毕,并且成功运行,那么这项规则便可以添加至永久的设置中。
下载并安装 firewalld 包:
sudo yum update && sudo yum install firewalld
查看区域:获取当前激活的区域,区域在大部分情况默认为 public
firewall-cmd --get-active-zones
列出规则:获取当前区域已配置的规则
firewall-cmd --zone=public --list-all
开放端口:在 public 区域永久允许 5000 端口的 TCP 流量传输
firewall-cmd --zone=public --add-port=5000/tcp --permanent
firewalld 服务也支持开放一个地址段,比如
--add-port=5000-5500/tcp
即开放从 5000 到 5500 的所有 TCP 端口。
关闭端口:在 public 区域永久关闭 5000 的 TCP 端口
firewall-cmd --zone=public --remove-port=5000/tcp --permanent
你可以使用防火墙内置的服务,也可以在添加端口时,自定义服务名使用
--service=
选项,查看这个 文档 了解更多。
获取服务:使用 --get-services
获取所有可开放的服务规则。
firewall-cmd --get-services
添加服务:使用 --add-service
添加一个内置的服务。
firewall-cmd --zone=public --add-service=http
热加载:使用 reload 热加载规则
firewall-cmd --reload
冷加载:使用 complete-reload 冷加载规则
firewall-cmd --complete-reload
在某些情况下,如需要部署一个可持久运行的服务时,可以创建 systemctl 实现自动登录,和便捷的启动和关闭。
首先找到服务文件的存储路径,并创建一个服务文件 [服务名称].service
。
systemd 服务文件可以保存到多个不同的目录,我个人偏向保存在 /usr/lib/systemd/system/ 目录中。
5/3/2022 修改:现在默认写到 /etc/systemmd/system/ 目录
[Unit]
Description=A simple program
[Service]
ExecStart=/PATH_TO_PROGRAM/example
待施工。。。
今天在 Linux 做定时任务的时候突然想起来可以使用 Crontab 快速配置。
在正式开始前先安装一些需要的程序,包括 Crontab 主体和编辑器选择。
首先我们需要安装 Crontab,在 Ubuntu,Debian 下输入:
sudo apt install cron
对于 Fedora,Red Hat,或 CentOS 输入:
sudo yum install cronie
还需要一个可用的文本编辑器,这里为了方便使用 Nano。
使用 Debian, Ubuntu 安装:
sudo apt install nano
使用 Fedora,Red Hat,CentOS 安装:
sudo yum install nano
下文是如何使用 Crontab 添加定时任务,以及给懒人推荐的工具。
在命令行中输入如下指令:
EDITOR=nano crontab -e
打开 Crontab 的配置页面,此时便可以在最后一行添加需要定时执行的命令。
下方是 Crontab 的配置格式,此时的 * * * * * 对应每分钟执行一次命令。
# ┌───────────── minute (0 - 59)
# │ ┌───────────── hour (0 - 23)
# │ │ ┌───────────── day of the month (1 - 31)
# │ │ │ ┌───────────── month (1 - 12)
# │ │ │ │ ┌───────────── day of the week (0 - 6) (Sunday to Saturday;
# │ │ │ │ │ 7 is also Sunday on some systems)
# │ │ │ │ │
# │ │ │ │ │
# * * * * * <command to execute>
来自:https://en.wikipedia.org/wiki/Cron
一些提供自动生成定时任务配置的网站:
中文网站
英文网站
在生成好相应的配置后参考人工配置步骤插入至 Crontab 配置文件中即可。
Q1. 如何在特定目录下执行命令?
A1. 切换路径后执行命令:cd /你/的/目录/ && [命令]
这前端开发可真有意思 - Ecss 11
大概在 4 月份左右,我突然恍然大悟,决定换个正常点的方法写网站,所以我就随便找了个能用的框架,也就是 NodeJS。
在经过了长达 10 分钟的学习后,我开始逐步实践 NodeJS 的代码,途中也遇到了些许问题,不过影响不大。
首先我需要知道,我需要哪些功能,并把功能再分解到不同的小功能,最后实现这个项目的目标。
基本:在我正在做的项目目前只有需要一个功能,那就是读取数据库并直接返回数据,十分的简单,没有任何难度。
首先需要告诉程序如何创建地址监听,这里我使用了 Express 开发网页。
const express = require('express')
...
// 实例化
const server = express()
...
server.listen(PORT, () => {
console.log(`${pkg.name} listening on port ${PORT}`)
})
这段代码表示在指定的端口监听接收的请求,虽然目前并没有任何的数据()
既然有了入口,并实现了最基本的端口监听,那么是时候开始创建不同地址的路由了。
通过创建路由,我们可以指定不同的路径应该返回什么数据,当然别忘了在服务入口处引用。
碎碎念:初始化到底要不要放在服务入口啊,太纠结了,我决定暂时不管,能 run 起来就是好代码。
module.exports = (server) => {
server.use('/api', require('./api'))
}
这段代码在入口实现后,等同于在入口写了一个 server.use('/api', require('./api'))
。
与此同时,server.use()
参数中的 require 又引用了另一个路由(路由地狱,路由套娃)
在?为什么不写控制器?为什么不写控制器!- Ecss 11
在有了路由帮助我们处理用户的请求后,我们需要有一个模型来处理这些请求的数据。
在这个案例中,用户通过 GET 请求,传入一或者两个 query 参数。
所以我们的模型将会使用用户传入的参数,并对数据库进行读取。
首先要读取数据库我们需要建立一个数据库连接,所以我又又又创建了 lib 文件夹。
const config = require('config')
const {MongoClient} = require("mongodb")
const url = config.get('mongodb.url')
const client = new MongoClient(url)
有了这个文件夹后,在其中创建 mongo.js 并实现数据库的连接方法,顺便实现了 query 方法。
module.exports = {
/**
* Connect and query the database
* @param agg - aggregate pipeline statement
* @returns {Promise<Document[]>} - a list of documents include query result
*/
query: async (agg) => {
...
}
}
之后在模型中我们只需要给 query 方法传入查询条件,query 方法就返回我们需要的资料。
然后再将 query 返回的数据作为模型的数据返回,再由路由更新视图。
由此,我们成功的创建了一个完整的 GET 请求处理(好耶!)
所以这个模型理论上应该是控制器,而这个 lib 理论上应该是才是真正的模型?(雾)
文件浏览功能使用 ngx_http_autoindex_module
模块实现,可选配置项不多。
location / {
root /path/to/folder/;
autoindex on | off; #开启nginx目录浏览功能
autoindex_exact_size on | off; #文件大小的大小格式
autoindex_localtime on | off; #服务器是否使用本地时间
}
在实际使用中,建议使用 location 搭配路由访问。
SpringBoot 可以直接创建一个轻量的,可部署于生产环境的应用,并可以直接运行。
它在原 Spring 的基础上优化的配置的步骤,使开发者可以更专注程序的开发。
可以通过访问 https://start.spring.io/ 快速生成一个 SpringBoot 的项目,也可以选择第三方 IDE 工具如 IntelliJ 创建。
假设您已经创建好了一个 SpringBoot 的项目,并已经安装了 Spring Web 的依赖,那么您可以通过以下代码创建你的第一个控制器。
SpringbootApplication:
package com.learn.springboot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringbootApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootApplication.class, args);
}
}
HelloController:
package com.learn.springboot.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@RequestMapping("/hello")
public String hello() {
return "Hello Spring!";
}
}
运行 SpringbootApplication 启动应用,并访问 http://localhost:8080/hello 查看你的代码是否成功。
在传统的依赖关系中,依赖导入是一件十分繁琐且复杂的事,但在 SpringBoot 中可以通过依赖关系解决。
SpringBoot 使用了一个类似于材料清单的方式,将不同的依赖整合,提供了一个稳定,测试,有效的依赖方案。
SpringBoot 在初始构建的时候已经有了默认配置,但是开发者依旧可以通过修改 application.properties
覆盖这些设置。
application.properties 的后缀也可以是 yaml 或 yml,如果这些文件同时存在,配置将会通过优先级选择:properties > yml > yaml
Ymal 是一种容易被人类阅读,和电脑识别的配置类型,并被多种编程语言支持,可选的后缀有 yml 和 yaml。
相比于 properties 或者 xml,yml 的数据结构更简洁,同时带有缩进,直观的显示了配置的关系。
people:
leader: xiaoming
# 行类写法
people: {leader: xiaoming}
people:
- me
- you
# 行类写法
people: [me, you]
msg1: '来做任务吗?\n' # 单引号忽略转义符号
msg2: '真的不来吗?\n' # 双引号识别转义符号
name: xiaoming
var: ${name} # ${ } 中的 name 表示引用 name 的值
在 SpringBoot 中,提供了三种读取配置文件的方式。
使用 Value 注入变量 var
到字符串 name
中。
@Value("${var}")
private String name;
相比于使用 @Value
,Environment 的好处是只需要注入一个对象。
@Autowired // 启动时自动初始化变量
private Environment var; // 注意是 spring 的 Environment
System.out.println(var.getProperty("name"))
使用教程,访问 https://www.baeldung.com/configuration-properties-in-spring-boot 查看
在 Spring 的开发过程中,通常会遇到对多种不同的环境如:开发,测试,和生产。如果每次打包的时候都要进行一次配置无疑会增加开发过程中的繁琐程度,而档案则通过动态地切换配置文件解决了这个问题。
首先在 resources 文件中创建不同环境的配置文件,如 application-dev.yml 或 application-pro.yml。
在默认的配置文件中,使用以下代码激活档案:
# 激活开发环境
spring.profiles.active=dev
除了将不同环境分为不同的文件,Spring 也可以在同一个文件中使用分割的方式配置不同的环境。
# 使用 --- 包括代表一段配置
---
spring:
profiles: dev
---
spring:
profiles: pro
---
spring.profiles.active: dev
除了修改配置外,还可以通过虚拟机配置参数切换配置。(IDE 自带)
与虚拟机参数相似,开发者还可以通过命令行参数切换配置。(IDE 自带,但也可以在命令行中输入参数)
在实际生产环境中,一般通过打包后的 jar 包运行。
SpringBoot 程序启动时,会从以下几个目录读取文件:
file/config/
:当前项目下的 config 目录下file
:当前项目的根目录下classpath/config/
:classpath 的 config 目录下classpath
:classpath 的根目录下加载顺序从上到下,低优先不会覆盖高优先配置,但会补充未存在的配置。
以下为搭建步骤:
以下为搭建步骤:
Condition 是 Spring 在 4.0 版本后添加的一个条件判断功能,并通过它选择性的执行 Bean 操作。
满足则创建,不满足则不创建,识别配置文件并创建。
BBR 是一个新的 TCP 拥塞控制算法,常用于改善网络连接如代理。
在 Linux Kernal 4.9 以及往上,BBR 会自动集成在系统中,无需用户手动安装。
输入以下命令查看可用的 TCP 控制算法:
sysctl net.ipv4.tcp_available_congestion_control
使用任意编辑器打开 /etc/sysctl.conf
文件,添加以下两行:
net.core.default_qdisc=fq
net.ipv4.tcp_congestion_control=bbr
部分云服务商,如 DMIT 在初始化服务器时以及配置好了 BBR 算法,可以使用以下指令查看:
sysctl net.ipv4.tcp_congestion_control
最后配上成功后的结果:
root@vmi819506:~# sysctl net.ipv4.tcp_congestion_control
net.ipv4.tcp_congestion_control = bbr
首先我们需要知道 rsync 的基本使用方法,可以通过 man rsync
简单的了解一下。
本地:rsync [选项...] 源... [目标]
通过 SSH 远程连接:
拉取: rsync [选项...] [用户@]地址:源... [目标]
推送: rsync [选项...] 源... [用户@]地址:目标
通过 rsync 监听服务:
拉取:
rsync [选项...] [用户@]地址::源... [目标]
rsync [选项...] rsync://[用户@]地址[:端口]/源... [目标]
推送:
rsync [选项...] 源... [用户@]地址::目标
rsync [选项...] 源... rsync://[用户@]地址[:端口]/目标
只有提供 SRC 参数,而没有 DEST 参数将列出源文件而不是复制。
使用平台:ubuntu 20
如何实现:通过在服务端配置 rsync 监听服务,并在客户端主动推送,并设置 crontab 定时任务。
在远程服务器,也就是希望同步文件保存的服务器中,依次执行命令进行判断:
root@ubuntu:~# sudo apt update
root@ubuntu:~# sudo apt install rsync
检查 rsync 环境是否已安装。
root@ubuntu:~# service rsync status
查看 rsync 服务信息。
● rsync.service - fast remote file copy program daemon
Loaded: loaded (/lib/systemd/system/rsync.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2022-05-09 00:19:13 MSK; 29min ago
Docs: man:rsync(1)
man:rsyncd.conf(5)
Main PID: 6216 (rsync)
Tasks: 1 (limit: 2279)
Memory: 13.0M
CGroup: /system.slice/rsync.service
└─6216 /usr/bin/rsync --daemon --no-detach
使用任意编辑器,或者 cat 打开 rsync.service
服务文件。
[Unit]
Description=fast remote file copy program daemon
Documentation=man:rsync(1) man:rsyncd.conf(5)
ConditionPathExists=/etc/rsyncd.conf
After=network.target
[Service]
ExecStart=/usr/bin/rsync --daemon --no-detach
[Install]
WantedBy=multi-user.target
通过 ConditionPathExists=/etc/rsyncd.conf 我们可以得知 rsync 读取 rsyncd.conf 读取配置文件。
root@ubuntu:~# vim /etc/rsyncd.conf
使用任意编辑器打开配置文件,如果不存在就创建一个,别问怎么创建,建议自行百度。
[custom1]
pid file = /var/run/rsyncd1.pid
...
[custom2]
pid file = /var/run/rsyncd2.pid
...
[custom3]
pid file = /var/run/rsyncd3.pid
...
必须:创建自定义模块,之后连接时会用到。
uid = user1
gid = group1
必须:rsync 模块的用户,不推荐 root,建议使用 adduser --disabled-login [username]
创建一个。
path = /path/to/backup
use chroot = yes
必须:使用 path 定义这个模块的路径,并使用 use chroot 加强安全性。
read only = no
write only = no
可选:是否启用读取或写入,可自行按需求配置。
hosts allow = 154.53.59.237
# 最大连接数
max connections = 4
# 启用传输日志
transfer logging = yes
# 指定日志格式
log format = %t %a %m %f %b
list = no
额外:通过 hosts allow 限制 IP 访问,以及 list 隐藏使用的模块。
在客户端,同样下载 rsync,使用以下指令测试是否配置成功。
root@vmi819506:~# rsync -avzrn /tmp/test/ rsync://[用户]@[地址][:端口]/[模块]
Q1:无法连接到服务端。
A1:可能是服务端的端口未开放,rsync 默认使用 873 端口监听。
使用 crontab,时间到后自动运行,下面是一个例子(每 5 分钟运行一次 rsync):
5 * * * * [指令]
那么这篇文章到这里就结束了,之后可能会对本文的一些内容进行补充或修改。
rsync 的配置写起来总感觉不够优雅,也没有 md 的高亮支持,寄
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.