読者です 読者をやめる 読者になる 読者になる

ブログのしゅーくりーむ

技術的なメモとかライフログとか。

ts_mruby, Apache Traffic Server mruby extension version 0.1 released.

(日本語版は こちら)

I released ts_mruby version 0.1, Apache Traffic Server(ATS) plugin that enables you write simple logic and configuration by mruby. In this entry, I write ts_mruby-0.1's features.

ts_mruby-0.1

ts_mruby-0.1 supports features of large part of ngx_mruby.

What can ts_mruby-0.1 do?

I show some example what ts_mruby-0.1 can do. See GitHub Wiki about full examples.

Load balancing

Below example works load balancing by simply randomizing a target host of ATS origin server.

backends = [
  "127.0.0.1:8001",
  "127.0.0.1:8002",
  "127.0.0.1:8003",
]
upstream = ATS::Upstream.new
upstream.server = backends[rand(backends.length)]

Override TSHttpOverridableConfig variables

ATS has various overridable configs.

ts_mruby supports overriding them by ATS::Records class.

Below example enables ATS memory/disk cache in a HTTP transaction. ts_mruby also enables you write more complex overriding logic by mruby control syntax.

records = ATS::Records.new
records.set ATS::Records::TS_CONFIG_HTTP_CACHE_HTTP, 1

The conf_remap plugin managed in ATS core repo provides simply overriding, but it doesn't support complex control syntax.

Switch maintenance mode based on Redis value

Its similar to ngx_mruby' Redis maintenance mode example. Below example enables switching logic by Redis.

redis = Redis.new '127.0.0.1', 6789

if redis['ts_maint']
  body = <<'EOS'
<html>
  <head>
    <title>Message from your proxy ...</title>
  </head>
  <body>
    <p>Sorry, maintainance mode now ...</p>
  </body>
</html>
EOS
  ATS::echo body
end

Redis class is provided by mruby-redis. You must write below build_config.rb and build mruby to use it simply. (mruby power is awesome!)

MRuby::Build.new do |conf|
  toolchain :gcc

  conf.gembox 'default'
  conf.gem :mgem => 'mruby-redis'
end

Quickstart

ts_mruby provide 2 methods for starters.

using Docker

Example docker image has already published to Docker Hub.

$ docker pull syucream/ts_mruby:0.1
$ docker run docker run -it syucream/ts_mruby /bin/bash

The image contains a test script(simply responds by ATS::echo), so you can test ts_mruby quickly:

root@ad7a82be8a65:/opt# trafficserver start
root@ad7a82be8a65:/opt# curl http://localhost:8080/
ts_mruby test

using Homebrew

If you're a Mac OS X user, you can use Homebrew to install ts_mruby:

$ brew install https://raw.githubusercontent.com/syucream/ts_mruby/master/Formula/trafficserver-atscppapi.rb
$ brew install --HEAD https://raw.githubusercontent.com/syucream/ts_mruby/master/Formula/ts_mruby.rb

ts_mruby-0.1's design

API/Library stacks

ts_mruby calls atscppapi, wrapped TS API by C++ classes basically.

https://github.com/syucream/ts_mruby/wiki/images/stack.png

ATS server hooks

Apache Traffic Server supports various hooks. But current ts_mruby is supporting a fews because:

  • I think mruby scripts will become complex if various hooks users can use.
  • handling these hooks is difficult. Users can't understand relationship between hooks and ATS's behaviors intuitively.

So ts_mruby uses READ_REQUEST_HDR_HOOK, early hook mainly and response body transform if necessary(ATS::Headers_out#[]= and ATS::Filter#transform! needs this control). Other hooks are unsupported yet.

https://github.com/syucream/ts_mruby/wiki/images/hooks.png

Thread shared/local Data

ATS process model is multi-thread and event-driven I/O. Therefore ts_mruby (and other ATS plugins) must ensure thread-safety. Current ts_mruby resolve the issue by below ways:

  • All of thread share mruby scirpts as string.
  • Each thread has own mruby VM(mrb_state) and RProc's poinging to compiled code.
    • To get/set thread specific data, using pthread(get|set)specific because ATS worker thread's impl is pthread. :D

https://github.com/syucream/ts_mruby/wiki/images/threads_and_data.png