跳到主要内容

配置

许可证书

确保 licenst.txt 和 luwak.toml 在同一目录。以 /etc/luwak 目录为例。

下载用于评估的许可证

curl -o /etc/luwak/license.txt https://download.api.tech/luwak/license.txt

说明

配置文件是 Toml 格式。

自动加载 conf.d 目录下的所有 .toml 文件。

基本配置

/etc/luwak/luwak.toml
[server]
listen = ":21000"
server_id = "luwak_001"

[console]
listen = ":23000"
api_key = "h7U06y40rtdWUJYSB1n5rbtKhHxS0701"

[general]
#enable_gzip = true

#luwak_sys_path = "/var/lib/luwak/"
luwak_sys_path = "lib/"
# 脚本超时 秒
script_timeout = 60
# 时间戳误差范围 秒
timestamp_range = 0
# 是否启用验证签名功能
enable_verify_signature = false

#cors_allow_origin = ["*"]
#cors_allow_methods = ["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"]
#cors_allow_headers = ["Authorization", "Content-Type", "X-Requested-With", "X-Api-Key"]

日志

conf.d/log.toml
[log]
# megabytes It defaults to 100 megabytes
max_size = 50

# The default is to retain all old log files
max_backups = 3

# days, The default is not to remove old log files
max_age = 21

# disabled by default
compress = true

#file = "/var/log/luwak/system.log"
file = "log/system.log"
log_format = "json" # key_value or json
level = "debug"

数据库

conf.d/database.toml
# multiple database connections
# driver_name = mysql, sqlite3, postgres, sqlserver, oci8
# data_source_name = "user:password@tcp(127.0.0.1:3306)/db_name"
[[database]]
driver_name = "mysql"
data_source_name = "luwak:RpaE1aD92Yf9ITZg@tcp(localhost:3306)/smart_panda"

#[[database]]
#driver_name = "sqlite3"
#data_source_name = "/Users/zhaoyi/code/go/luwak/src/testdata/sqlite/hrm.db"

Redis

conf.d/redis.toml
[redis_session]
master_name = ""
password = "foobared"
db = 0
#addr_list = [ "cache.example.com:6379" ]
addr_list = ["127.0.0.1:6379"]

[session]
key_prefix = ""
serialization_type = "java"
ttl = 604_800

[cache]
master_name = ""
password = "foobared"
db = 1
#addr_list = ["cache.example.com:6379"]
addr_list = ["127.0.0.1:6379"]

以下方法与上述配置有关

  • luwak.setSession()
  • luwak.cache()

APP Key

APP Key 在身份验证、数据加密、访问控制、统计分析、防止滥用、第三方集成和日志记录等方面发挥重要作用,确保应用程序的安全性和可靠性。

可以同时配置 session 会话数据。

你可以使用 OpenSSL toolkit 生成 app key 和 app secret。例如:

# 生成 16 位长度密码
openssl rand -base64 12
0FM17d5wkH9BA8ln

# 生成 32 位长度密码
openssl rand -base64 24
KADMgA4fpuri4t0GSCJ4dK91BJKT2vN5

# 生成 48 位长度密码
openssl rand -base64 36
1rVXw44M94gg9N58xOEcEjzYUPNcvBKdpbxFiglZwP0B9OmK

通常建议 key 和 secret 的长度是 8 的倍数,最小 16 位。

conf.d/app.toml
[[app]]
key = "0FM17d5wkH9BA8ln"
secret = "KADMgA4fpuri4t0GSCJ4dK91BJKT2vN5"

[[app]]
key = "HcxeoktHCQNOH88O"
secret = "WQK8kBGQOmJCCmdbcjx3blkcozmwaul4"
[app.session]
user_name = "luwak"
user_id = 1
org_id = 1

定时任务

/conf.d/crontab.toml
[[crontab]]
job_name = "每天2:30初始化库存" # UTC+8 北京时间 2:30
job_cron = "0 30 18 * * *" # UTC 标准时间 18:30

api = "smartpanda.mdh.brand.sync" # API
api_params = "null" # json string # API 参数

自 luwak 3.3.4 开始将配置项 api_method 改为 api

Cron expression format

Field NameMandatoryAllowed ValuesAllowed Special Characters
SecondsYES0-59, - * /
MinutesYES0-59, - * /
HoursYES0-23, - * /
Day of monthYES1-31, - * ? / L W
MonthYES1-12 or JAN-DEC, - * /
Day of weekYES1-7 or SUN-SAT, - * ? / L #
YearNOempty, 1970-, - * /

Special characters

  • *: All values in a field (e.g., * in minutes = "every minute").
  • ?: No specific value; use when specifying one of two related fields (e.g., "10" in day-of- month, ? in day-of-week).
  • -: Range of values (e.g., 10-12 in hour = "hours 10, 11, and 12").
  • ,: List of values (e.g., MON,WED,FRI in day-of-week = "Monday, Wednesday, Friday").
  • /: Increments (e.g., 0/15 in seconds = "0, 15, 30, 45"; 1/3 in day-of-month = "every 3 days from the 1st").
  • L: Last day; meaning varies by field. Ranges or lists are not allowed with L.
    • Day-of-month: Last day of the month (e.g, L-3 is the third to last day of the month).
    • Day-of-week: Last day of the week (7 or SAT) when alone; "last xxx day" when used after another value (e.g., 6L = "last Friday").
  • W: Nearest weekday in the month to the given day (e.g., 15W = "nearest weekday to the 15th"). If 1W on Saturday, it fires Monday the 3rd. W only applies to a single day, not ranges or lists.
  • #: Nth weekday of the month (e.g., 6#3 = "third Friday"; 2#1 = "first Monday"). Firing does not occur if that nth weekday does not exist in the month.

1 The L and W characters can also be combined in the day-of-month field to yield LW, which translates to "last weekday of the month".

2 The names of months and days of the week are not case-sensitive. MON is the same as mon.

环境变量

预定义环境变量,供脚本使用。

conf.d/env.toml
[env]

shopId = "$session.shopId"
userId = "$session.userId"

CreatedBy = "$session.userId"
LastModifiedBy = "$session.userId"

smsKeyPrefix = "sp:sms:"

脚本引用,以 JavaScript 为例

const userId = globalThis.metas.env.userId;

消息队列

使用 Redis 做消息队列,也支持rabbitmq 和 kafka。

conf.d/message_queue.toml
[[mq_topic]]
mq_dirver = "redis"
mq_instance = "my_redis_0"
name = "hrm.employee.created"
description = "新员工加入组织"

[[mq_topic]]
mq_dirver = "redis"
mq_instance = "my_redis_0"
name = "smartPanda.ecs.purchaser.signup.sms"
description = "采购商注册手机短信验证"

#[[mq_topic]]
#mq_dirver = "rabbitmq"
#mq_instance = "my_rabbitmq_1"
#name = "hrm.employee.created"
#description = "新员工加入组织"

#[[mq_topic]]
#mq_dirver = "rabbitmq"
#mq_instance = "my_rabbitmq_1"
#name = "hrm.salary.processed"
#description = "完成员工工资发放"

#[[mq_topic]]
#mq_dirver = "kafka"
#mq_instance = "my_kafka_1"
#name = "hrm.payroll.processed"
#description = "工资处理完成"

# 只有被 topic 引用的才会被初始化
[[mq_redis]]
mq_instance = "my_redis_0"
[mq_redis.option]
master_name = ""
password = "foobared"
db = 0
addr_list = ["127.0.0.1:6379"]

#[[mq_redis]]
#mq_instance = "my_redis_1"
# [mq_redis.option]
# master_name = ""
# password = "foobared"
# db = 1
# addr_list = ["127.0.0.1:6379"]
#
#[[mq_rabbitmq]]
#mq_instance = "my_rabbitmq_1"
#
# [mq_rabbitmq.option]
# url = "amqp://guest:guest@localhost:5672/"
# timeout = 5
#
# [mq_rabbitmq.option.publish]
# exchange = ""
# immediate = false
# mandatory = false
# routingKey = "hello"
# contentType = "application/json"
#
# [mq_rabbitmq.option.queueDeclare]
# name = "hello"
# noWait = false
# durable = false
# exclusive = false
# autoDelete = false
#
#[[mq_kafka]]
#mq_instance = "my_kafka_1"
# [mq_kafka.option]
# addressList = ["localhost:29092"]

脚本调用示例

// javascript example
// luwak.sendMessage('业务主题', '业务 ID', '业务附加数据');
luwak.sendMessage('hrm.employee.created', '8612345678900', 'Verification Code: 123456');

payload

{
"mqName": "",
"messageId": "",
"createdAt": "",
"status": "",
"numberOfTrials": 0,
"topicName": "业务主题",
"bizId": "业务 ID",
"bizData": "业务附加数据"
}

全局脚本

全局脚本配置

conf.d/hooks.toml
[hooks]
before = [
# "/var/lib/hooks/authentication.js", # 认证
# "/var/lib/hooks/authorization.js" # 鉴权
]

after = [
# "/var/lib/luwak/hooks/postscript.js"
]

列映射

conf.d/column_mapping.toml
[column_mapping]
# 转换请求参数
# true (默认值) 请求参数对象的字段名自动映射数据库表的字段名
# false 请求参数对象的字段名直接对应数据库表的字段名
convert_request = true

# 转换响应结果
# true (默认值) 查询结果中的字段名自动转为 lowerCamelCase 风格
# false 查询结果中的字段名保持原样
convert_response = true

数据库抽象层

conf.d/dal.toml
[dal]
# 是否自动解析 JSON 数据类型的列
# true (默认值) 自动解析 json 类型的列,返回解析后的对象
# false 返回原始 json 字符串
parse_json_columns = false