The Java Plugin and Go Plugin languages have been supported in the community before the Apache Python Runner, and today Python Runner is now available, giving the community another option for developing plugins for Apache .
Introduction
Apache
Apache
is a high-performance cloud-native open-source API gateway that provides unified request interception and governance (e.g., authentication, caching, versioning, fusing, auditing, etc.) to help developers easily provide secure and reliable services to the outside world, while developers only need to focus on business implementation with Apache
, which saves a lot of time in developing and maintaining generic capabilities and reduces the complexity of the overall business architecture.
Python
Python is an interpreted high-level programming language with a simple syntax, good code readability, cross-platform, portability, and development efficiency.
As a high-level programming language, it has a high degree of abstraction and shields a lot of underlying details (e.g., GC
).
) allows us to focus more on the development of application logic in the development process. As a 30-year old development language, Python has a well-developed ecology and various modules, and most of our development and application scenarios can be found in mature modules or solutions from the community. Python
We won't go into all the other advantages. The disadvantages of Python
are also obvious: Python
, as an interpreted language, has a relatively large performance gap compared to compiled languages like C++
and Go
.
Apache Python Runner
apache--python-runner This project can be interpreted as Apache
and Python
.
The most important thing is to let more Python developers
who are interested in Apache
and API gateways
to learn more about the use of Apache
and API gateways
through this project.
The following is a diagram of the architecture of Apache
multi-language support.
The above diagram shows the workflow of Apache
on the left, and the Plugin Runner
on the right is the plug-in runner for each language, the -python-plugin-runner
introduced in this article is the one that supports Python
.
language.
When you configure a Plugin Runner
in Apache
, Apache
will start a child process to run the Plugin Runner
that belongs to the same user as the Apache
process belongs to the same user, and when we restart or reload Apache
, Plugin Runner
will also be restarted.
If you configure the ext-plugin-*
plugin for a given route, a request to hit that route will trigger an Apache
RPC
call to the Plugin Runner
via the Unix Socket
. The call is split into two phases.
- ext-plugin-pre-req: Before executing the
Apache
built-in plugin (Lua language plugin). - ext-plugin-post-req: after executing the
Apache
plug-in (Lua language plug-in).
You can choose and configure the execution timing of Plugin Runner
as needed.
The Plugin Runner
handles the RPC
call, creates a simulated request inside it, and then runs the multilingual plugin and returns the result to Apache .
The execution order of multilingual plugins is defined in the ext-plugin-*
plugin configuration entry, and like other plugins, they can be enabled and redefined on the fly.
Deploy test
Base runtime environment
- Apache 2.7
- Python 3.6+
To deploy Apache , please refer to the Apache official documentation: How to build Apache for details.
Download and install Python Runner
$ git clone https://github.com/apache/-python-plugin-runner.git$ cd -python-plugin-runner$ make install
Configuring Python Runner
development mode
Run Python Runner
$ cd /path/to/-python-plugin-runner$ _LISTEN_ADDRESS=unix:/tmp/runner.sock python3 /main.py start
Modify configuration file
$ vim /path/to//conf/config.yaml: admin_key: - name: "admin" key: edd1c9f034335f136f87ad84b625c8f1 role: adminext-plugin: path_for_test: /tmp/runner.sock
Production mode
Modify configuration file
$ vim /path/to//conf/config.yaml: admin_key: - name: "admin" key: edd1c9f034335f136f87ad84b625c8f1 role: adminext-plugin: cmd: [ "python3", "/path/to/-python-plugin-runner//main.py", "start" ]
Python Runner configuration (optional)
If you need to adjust the Log Level
or Unix Domain Socket
environment variables, you can modify the Runner
configuration file
$ vim /path/to/-python-plugin-runner//config.yamlsocket: file: $env._LISTEN_ADDRESS # Environment variable or absolute pathlogging: level: debug # error warn info debugdebug
Start Python Runner
$ cd /path/to/# Start or Restart$ ./bin/ [ start | restart ]
Start or restart , when
and
Python Runner
have been configured and started.
Testing Python Runner
Configuring Apache Routing and Plugin Information
# Test with the default demo plugin$ curl http://127.0.0.1:9080//admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '{ "uri": "/get", "plugins": { "ext-plugin-pre-req": { "conf": [ { "name": "stop", "value":"{\"body\":\"hello\"}"} ] } }, "upstream": { "type": "roundrobin", "nodes": { "127.0.0.1:1980": 1 } }}'
plugins.ext-plugin-pre-req.conf
is theRunner
plugin configuration,conf
is an array format to set multiple plugins at the same time.- The
name
in the plugin configuration object is the name of the plugin, which should be the same as the plugin code file and object name. value
in the plugin configuration object is the plugin configuration, which can be aJSON
string.
access verification
$ curl http://127.0.0.1:9080/get -iHTTP/1.1 200 OKDate: Fri, 13 Aug 2021 13:39:18 GMTContent-Type: text/plain; charset=utf-8Transfer-Encoding: chunkedConnection: keep-alivehost: 127.0.0.1:9080accept: */*user-agent: curl/7.64.1X-Resp-A6-Runner: PythonServer: /2.7Hello, Python Runner of
Plugin Development
Plugin directory
/path/to/-python-plugin-runner//plugins
The .py
files in this directory will be loaded automatically.
Plugin example
/path/to/-python-plugin-runner//plugins/stop.py/path/to/-python-plugin-runner//plugins/rewrite.py
Plugin format
from .runner.plugin.base import Basefrom .runner.http.request import Requestfrom .runner.http.response import Responseclass Stop(Base): def __init__(self): """ Example of `stop` type plugin, features: This type of plugin can customize response `body`, `header`, `http_code` This type of plugin will interrupt the request """ super(Stop, self). __init__(self.__class__. __name__) def filter(self, request: Request, response: Response): """ The plugin executes the main function :param request: request parameters and information :param response: response parameters and information :return: """ # In the plugin you can get the configuration information through `self.config`,</