API 重建计划 #2 PHP Laravel

PHP Laravel API Rakuyo

Laravel 中文文档

升级 Composer

1
$ composer self-update --2

新建项目

1
2
3
$ composer global require laravel/installer
$ laravel new "project name"
$ php artisan serve

将代码部署到服务器后需要 composer install 安装依赖。
注意 PHP 要提前安装 fileinfo 扩展,并启用 putenvproc_open 两个函数。

然后 chmod -R 777 storage bootstrap/cache 打开日志、缓存、sessions 等等杂项的写入权限,就能在生产环境上跑了。

配置优雅链接

运行目录 设置为 /public,然后编辑 Nginx 的配置文件:

location / {
    try_files $uri $uri/ /index.php?$query_string;
}

拉取仓库配置见前文《API 重建计划 #1 Golenil》,此处不再赘述。

引入 Laravel Octane

虽然目前(2021.5.18)的 Laravel Octane 不尽如人意,但毕竟是提升,有总比没有好。

升级 PHP 8

Laravel Octane 需要 PHP 8。
升级过程参考 《Ubuntu 20.04 / 18.04 下如何安装或更新至 PHP 8?》。

更新软件源

1
$ sudo apt update && apt upgrade -y

添加 PPA

1
2
3
$ sudo apt install software-properties-common
$ sudo add-apt-repository ppa:ondrej/php
$ sudo apt update

安装 PHP 8

1
2
$ sudo apt install php8.0-fpm -y # Nginx
$ sudo apt install php8.0 -y     # Apache

安装常用扩展

1
$ sudo apt install php8.0-common php8.0-mysql php8.0-xml php8.0-curl php8.0-gd php8.0-imagick php8.0-cli php8.0-dev php8.0-imap php8.0-mbstring php8.0-opcache php8.0-soap php8.0-zip -y

安装 Laravel Octane

1
$ composer require laravel/octane

提示选引擎:

➜ php artisan octane:install

 Which application server you would like to use?:
  [0] roadrunner
  [1] swoole
 >

我选强无敌的 RoadRunner Golang 天下第一

新建配置文件 .rr.yaml

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
######################################################################################
#                       THIS IS SAMPLE OF THE CONFIGURATION                          #
# IT'S NOT A DEFAULT CONFIGURATION, IT'S JUST A REFERENCE TO ALL OPTIONS AND PLUGINS #
#       MORE DOCS CAN BE FOUND HERE: <https://roadrunner.dev/docs/intro-config>      #
######################################################################################

# Production usage guide: https://roadrunner.dev/docs/beep-beep-production

# Hint: RR will replace any config options using reference to environment variables,
# eg.: `option_key: ${ENVIRONMENT_VARIABLE_NAME}`.

# Important: TCP port numbers for each plugin (rpc, http, etc) must be unique!

# Remote Procedures Calling (docs: https://roadrunner.dev/docs/beep-beep-rpc)
# Is used for connecting to RoadRunner server from your PHP workers.
rpc:
  # TCP address:port for listening.
  #
  # Default: "tcp://127.0.0.1:6001"
  listen: tcp://127.0.0.1:6001

# Application server settings (docs: https://roadrunner.dev/docs/php-worker)
server:
  # Worker starting command, with any required arguments.
  #
  # This option is required.
  command: "php artisan octane:start --server=roadrunner --host=127.0.0.1 --port=8000"

  # User name (not UID) for the worker processes. An empty value means to use the RR process user.
  #
  # Default: ""
  user: ""

  # Group name (not GID) for the worker processes. An empty value means to use the RR process user.
  #
  # Default: ""
  group: ""

  # Environment variables for the worker processes.
  #
  # Default: <empty map>
  env:
    - SOME_KEY: "SOME_VALUE"
    - SOME_KEY2: "SOME_VALUE2"

  # Worker relay can be: "pipes", TCP (eg.: tcp://127.0.0.1:6001), or socket (eg.: unix:///var/run/rr.sock).
  #
  # Default: "pipes"
  relay: pipes

  # Timeout for relay connection establishing (only for socket and TCP port relay).
  #
  # Default: 60s
  relay_timeout: 60s

# Logging settings (docs: https://roadrunner.dev/docs/beep-beep-logging)
logs:
  # Logging mode can be "development", "production" or "raw". Do not forget to change this value for production environment.
  #
  # Development mode (which makes DPanicLevel logs panic), uses a console encoder, writes to standard error, and
  # disables sampling. Stacktraces are automatically included on logs of WarnLevel and above.
  #
  # Default: "development"
  mode: development

  # Logging level can be "panic", "error", "warn", "info", "debug".
  #
  # Default: "debug"
  level: debug

  # Encoding format can be "console" or "json" (last is preferred for production usage).
  #
  # Default: "console"
  encoding: console

  # Output can be file (eg.: "/var/log/rr_errors.log"), "stderr" or "stdout".
  #
  # Default: "stderr"
  output: stderr

  # Errors only output can be file (eg.: "/var/log/rr_errors.log"), "stderr" or "stdout".
  #
  # Default: "stderr"
  err_output: stderr

  # You can configure each plugin log messages individually (key is plugin name, and value is logging options in same
  # format as above).
  #
  # Default: <empty map>
  channels:
    http:
      mode: development
      level: panic
      encoding: console
      output: stdout
      err_output: stderr
    server:
      mode: production
      level: info
      encoding: json
      output: stdout
      err_output: stdout
    rpc:
      mode: raw
      level: debug
      encoding: console
      output: stderr
      err_output: stdout

# KV plugin settings. Available drivers: boltdb, redis, memcached, memory.
# Any number of sections can be defined here.
kv:
  # User defined name of the section
  #
  # Default: none
  boltdb-south:
    # Driver which should be used for the storage
    #
    # This option is required.
    driver: boltdb
    # Driver specific options. Dir - directory where to store db file.
    #
    # Default: "."
    dir: "tests/rr-bolt"
    # File name for the DB
    #
    # Default: "rr.db"
    file: "rr.db"
    # BoltDB bucket name
    #
    # Default: "rr"
    bucket: "rr"
    # Access permission for the DB file.
    #
    # Default: "0777"
    permissions: 0666
    # TTL keys check interval in seconds. It's safe to use 1 second here, but can be a little costly to performance.
    #
    # Default: "60" seconds
    interval: 40

  # User defined name of the section
  #
  # Default: none
  us-central-kv:
    # Driver which should be used for the storage
    #
    # Default: none
    driver: memcached
    # Driver specific section. Address of the memcached node.
    #
    # Default: "localhost:11211"
    addr: [ "localhost:11211" ]

  # User defined name of the section
  #
  # Default: none
  fast-kv-fr:
    # Driver which should be used for the storage.
    #
    # Default: none
    driver: redis
    # Redis specific section. If one address provided - single node client will be used.
    #
    #
    # UniversalClient is an abstract client which - based on the provided options -
    # can connect to either clusters, or sentinel-backed failover instances
    # or simple single-instance servers. This can be useful for testing
    # cluster-specific applications locally.
    # if the number of addrs is 1 and master_name is empty, a single-node redis Client will be returned
    # if the number of addrs is two or more, a ClusterClient will be returned
    addrs:
      - "localhost:6379"
      # if a MasterName is passed a sentinel-backed FailoverClient will be returned
    master_name: ""
    username: ""
    password: ""
    db: 0
    sentinel_password: ""
    route_by_latency: false
    route_randomly: false
    dial_timeout: 0 # accepted values [1s, 5m, 3h]
    max_retries: 1
    min_retry_backoff: 0 # accepted values [1s, 5m, 3h]
    max_retry_backoff: 0 # accepted values [1s, 5m, 3h]
    pool_size: 0
    min_idle_conns: 0
    max_conn_age: 0 # accepted values [1s, 5m, 3h]
    read_timeout: 0 # accepted values [1s, 5m, 3h]
    write_timeout: 0 # accepted values [1s, 5m, 3h]
    pool_timeout: 0 # accepted values [1s, 5m, 3h]
    idle_timeout: 0 # accepted values [1s, 5m, 3h]
    idle_check_freq: 0 # accepted values [1s, 5m, 3h]
    read_only: false


  # User defined name of the section
  #
  # Default: none
  local-memory:
    # In memory driver specific section
    #
    # Default: none
    driver: memory
    # TTL check interval in seconds
    #
    # Default: 60 seconds
    interval: 1

# HTTP plugin settings.
http:
  # Host and port to listen on (eg.: `127.0.0.1:8080`).
  #
  # This option is required.
  address: 127.0.0.1:8080

  # Maximal incoming request size in megabytes. Zero means no limit.
  #
  # Default: 0
  max_request_size: 256

  # Middlewares for the http plugin, order is important. Allowed values is: "headers", "gzip".
  #
  # Default value: []
  middleware: [ "headers", "gzip" ]

  # Allow incoming requests only from the following subnets (https://en.wikipedia.org/wiki/Reserved_IP_addresses).
  #
  # Default: ["10.0.0.0/8", "127.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16",  "::1/128", "fc00::/7", "fe80::/10"]
  trusted_subnets: [
      "10.0.0.0/8",
      "127.0.0.0/8",
      "172.16.0.0/12",
      "192.168.0.0/16",
      "::1/128",
      "fc00::/7",
      "fe80::/10",
  ]

  # File uploading settings.
  uploads:
    # Directory for file uploads. Empty value means to use $TEMP based on your OS.
    #
    # Default: ""
    dir: "/tmp"

    # Deny files with the following extensions to upload.
    #
    # Default: [".php", ".exe", ".bat"]
    forbid: [ ".php", ".exe", ".bat", ".sh" ]

  # Settings for "headers" middleware (docs: https://roadrunner.dev/docs/http-headers).
  headers:
    # Allows to control CORS headers. Additional headers "Vary: Origin", "Vary: Access-Control-Request-Method",
    # "Vary: Access-Control-Request-Headers" will be added to the server responses. Drop this section for this
    # feature disabling.
    cors:
      # Controls "Access-Control-Allow-Origin" header value (docs: https://mzl.la/2OgD4Qf).
      #
      # Default: ""
      allowed_origin: "*"

      # Controls "Access-Control-Allow-Headers" header value (docs: https://mzl.la/2OzDVvk).
      #
      # Default: ""
      allowed_headers: "*"

      # Controls "Access-Control-Allow-Methods" header value (docs: https://mzl.la/3lbwyXf).
      #
      # Default: ""
      allowed_methods: "GET,POST,PUT,DELETE"

      # Controls "Access-Control-Allow-Credentials" header value (docs: https://mzl.la/3ekJGaY).
      #
      # Default: false
      allow_credentials: true

      # Controls "Access-Control-Expose-Headers" header value (docs: https://mzl.la/3qAqgkF).
      #
      # Default: ""
      exposed_headers: "Cache-Control,Content-Language,Content-Type,Expires,Last-Modified,Pragma"

      # Controls "Access-Control-Max-Age" header value in seconds (docs: https://mzl.la/2PCSdvt).
      #
      # Default: 0
      max_age: 600

    # Automatically add headers to every request passed to PHP.
    #
    # Default: <empty map>
    request:
      input: "custom-header"

    # Automatically add headers to every response.
    #
    # Default: <empty map>
    response:
      X-Powered-By: "RoadRunner"

  # Settings for "static" middleware (docs: https://roadrunner.dev/docs/http-static).
  static:
    dir: "."
    forbid: [""]
    allow: [".txt", ".php"]
    request:
      input: "custom-header"
    response:
      output: "output-header"

  # Workers pool settings.
  pool:
    # How many worker processes will be started. Zero (or nothing) means the number of logical CPUs.
    #
    # Default: 0
    num_workers: 0

    # Maximal count of worker executions. Zero (or nothing) means no limit.
    #
    # Default: 0
    max_jobs: 64

    # Timeout for worker allocation. Zero means no limit.
    #
    # Default: 60s
    allocate_timeout: 60s

    # Timeout for worker destroying before process killing. Zero means no limit.
    #
    # Default: 60s
    destroy_timeout: 60s

    # Supervisor is used to control http workers (previous name was "limit", docs:
    # https://roadrunner.dev/docs/php-limit). "Soft" limits will not interrupt current request processing. "Hard"
    # limit on the contrary - interrupts the execution of the request.
    supervisor:
      # How often to check the state of the workers.
      #
      # Default: 1s
      watch_tick: 1s

      # Maximum time worker is allowed to live (soft limit). Zero means no limit.
      #
      # Default: 0s
      ttl: 0s

      # How long worker can spend in IDLE mode after first using (soft limit). Zero means no limit.
      #
      # Default: 0s
      idle_ttl: 10s

      # Maximal worker memory usage in megabytes (soft limit). Zero means no limit.
      #
      # Default: 0
      max_worker_memory: 128

      # Maximal job lifetime (hard limit). Zero means no limit.
      #
      # Default: 0s
      exec_ttl: 60s

  # FastCGI frontend support.
  fcgi:
    # FastCGI connection DSN. Supported TCP and Unix sockets. An empty value disables this.
    #
    # Default: ""
    address: tcp://0.0.0.0:7921

  # HTTP/2 settings.
  http2:
    # HTTP/2 over non-encrypted TCP connection using H2C.
    #
    # Default: false
    h2c: false

    # Maximal concurrent streams count.
    #
    # Default: 128
    max_concurrent_streams: 128

# Application metrics in Prometheus format (docs: https://roadrunner.dev/docs/beep-beep-metrics). Drop this section
# for this feature disabling.
metrics:
  # Prometheus client address (path /metrics added automatically).
  #
  # Default: "127.0.0.1:2112"
  address: "127.0.0.1:2112"

  # Application-specific metrics (published using an RPC connection to the server).
  collect:
    app_metric:
      type: histogram
      help: "Custom application metric"
      labels: [ "type" ]
      buckets: [ 0.1, 0.2, 0.3, 1.0 ]
      # Objectives defines the quantile rank estimates with their respective absolute error (for summary only).
      objectives:
        - 1.4: 2.3
        - 2.0: 1.4

# Health check endpoint (docs: https://roadrunner.dev/docs/beep-beep-health). If response code is 200 - it means at
# least one worker ready to serve requests. 500 - there are no workers ready to service requests.
# Drop this section for this feature disabling.
status:
  # Host and port to listen on (eg.: `127.0.0.1:2114`). Use the following URL: http://127.0.0.1:2114/health?plugin=http
  # Multiple plugins must be separated using "&" - http://127.0.0.1:2114/health?plugin=http&plugin=rpc where "http" and
  # "rpc" are active (connected) plugins.
  #
  # This option is required.
  address: 127.0.0.1:2114

  # Response status code if a requested plugin not ready to handle requests
  # Valid for both /health and /ready endpoints
  #
  # Default: 503
  unavailable_status_code: 503

# Automatically detect PHP file changes and reload connected services (docs:
# https://roadrunner.dev/docs/beep-beep-reload). Drop this section for this feature disabling.
reload:
  # Sync interval.
  #
  # Default: "1s"
  interval: 1s

  # Global patterns to sync.
  #
  # Default: [".php"]
  patterns: [ ".php" ]

  # List of included for sync services (this is a map, where key name is a plugin name).
  #
  # Default: <empty map>
  services:
    http:
      # Directories to sync. If recursive is set to true, recursive sync will be applied only to the directories in
      # "dirs" section. Dot (.) means "current working directory".
      #
      # Default: []
      dirs: [ "." ]

      # Recursive search for file patterns to add.
      #
      # Default: false
      recursive: true

      # Ignored folders.
      #
      # Default: []
      ignore: [ "vendor" ]

      # Service specific file pattens to sync.
      #
      # Default: []
      patterns: [ ".php", ".go", ".md" ]

## RoadRunner internal container configuration (docs: https://github.com/spiral/endure).
endure:
  # How long to wait for stopping.
  #
  # Default: 30s
  grace_period: 30s

  # Print graph in the graphviz format to the stdout (paste here to visualize https://dreampuf.github.io)
  #
  # Default: false
  print_graph: false

  # Logging level. Possible values: "debug", "info", "warn", "error", "panic", "fatal".
  #
  # Default: "error"
  log_level: error
1
2
$ chmod +x ./rr
$ ./rr serve
updatedupdated2022-05-012022-05-01