Skip to main content
Version: 2.15

FAQ

Why do I need a new API gateway?#

As organizations move towards cloud native microservices, there is a need for an API gateway that is performant, flexible, secure and scalable.

APISIX outperforms other API gateways in these metrics while being platform agnostic and fully dynamic delivering features like supporting multiple protocols, fine-grained routing and multi-language support.

How does Apache APISIX differ from other API gateways?#

Apache APISIX differs in the following ways:

  • It uses etcd to save and synchronize configurations rather than relational databases like PostgreSQL or MySQL. The real-time event notification system in etcd is easier to scale than in these alternatives. This allows APISIX to synchronize the configuration in real-time, makes the code concise and avoids a single point of failure.
  • Fully dynamic.
  • Supports hot loading of Plugins.

What is the performance impact of using Apache APISIX?#

Apache APISIX delivers the best performance among other API gateways with a single-core QPS of 18,000 with an average delay of 0.2 ms.

Specific results of the performance benchmarks can be found here.

Which platforms does Apache APISIX support?#

Apache APISIX is platform agnostic and avoids vendor lock-in. It is built for cloud native environments and can run on bare-metal machines to Kubernetes. It even support Apple Silicon chips.

What does it mean by "Apache APISIX is fully dynamic"?#

Apache APISIX is fully dynamic in the sense that it doesn't require restarts to change its behavior.

It does the following dynamically:

  • Reloading Plugins
  • Proxy rewrites
  • Proxy mirror
  • Response rewrites
  • Health checks
  • Traffic split

Does Apache APISIX have a user interface?#

Yes. Apache APISIX has an experimental feature called Apache APISIX Dashboard, which is independent from Apache APISIX. To work with Apache APISIX through a user interface, you can deploy the Apache APISIX Dashboard.

Can I write my own Plugins for Apache APISIX?#

Yes. Apache APISIX is flexible and extensible through the use of custom Plugins that can be specific to user needs.

You can write your own Plugins by referring to How to write your own Plugins.

Why does Apache APISIX use etcd for the configuration center?#

In addition to the basic functionality of storing the configurations, Apache APISIX also needs a storage system that supports these features:

  1. Distributed deployments in clusters.
  2. Guarded transactions by comparisons.
  3. Multi-version concurrency control.
  4. Notifications and watch streams.
  5. High performance with minimum read/write latency.

etcd provides these features and more making it ideal over other databases like PostgreSQL and MySQL.

To learn more on how etcd compares with other alternatives see this comparison chart.

When installing Apache APISIX dependencies with LuaRocks, why does it cause a timeout or result in a slow or unsuccessful installation?#

This is likely because the LuaRocks server used is blocked.

To solve this you can use https_proxy or use the --server flag to specify a faster LuaRocks server.

You can run the command below to see the available servers (needs LuaRocks 3.0+):

luarocks config rocks_servers

Mainland China users can use luarocks.cn as the LuaRocks server. You can use this wrapper with the Makefile to set this up:

make deps ENV_LUAROCKS_SERVER=https://luarocks.cn

If this does not solve your problem, you can try getting a detailed log by using the --verbose flag to diagnose the problem.

How do I build the APISIX-Base environment?#

Some functions need to introduce additional NGINX modules, which requires APISIX to run on APISIX-Base. If you need these functions, you can refer to the code in api7/apisix-build-tools to build your own APISIX-Base environment.

How can I make a gray release with Apache APISIX?#

Let's take an example query foo.com/product/index.html?id=204&page=2 and consider that you need to make a gray release based on the id in the query string with this condition:

  1. Group A: id <= 1000
  2. Group B: id > 1000

There are two different ways to achieve this in Apache APISIX:

  1. Using the vars field in a Route:
curl -i http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
"uri": "/index.html",
"vars": [
["arg_id", "<=", "1000"]
],
"plugins": {
"redirect": {
"uri": "/test?group_id=1"
}
}
}'

curl -i http://127.0.0.1:9080/apisix/admin/routes/2 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
"uri": "/index.html",
"vars": [
["arg_id", ">", "1000"]
],
"plugins": {
"redirect": {
"uri": "/test?group_id=2"
}
}
}'

All the available operators of the current lua-resty-radixtree are listed here.

  1. Using the traffic-split Plugin.

How do I redirect HTTP traffic to HTTPS with Apache APISIX?#

For example, you need to redirect traffic from http://foo.com to https://foo.com.

Apache APISIX provides several different ways to achieve this:

  1. Setting http_to_https to true in the redirect Plugin:
curl http://127.0.0.1:9080/apisix/admin/routes/1  -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
"uri": "/hello",
"host": "foo.com",
"plugins": {
"redirect": {
"http_to_https": true
}
}
}'
  1. Advanced routing with vars in the redirect Plugin:
curl -i http://127.0.0.1:9080/apisix/admin/routes/1  -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
"uri": "/hello",
"host": "foo.com",
"vars": [
[
"scheme",
"==",
"http"
]
],
"plugins": {
"redirect": {
"uri": "https://$host$request_uri",
"ret_code": 301
}
}
}'
  1. Using the serverless Plugin:
curl -i http://127.0.0.1:9080/apisix/admin/routes/1  -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
"uri": "/hello",
"plugins": {
"serverless-pre-function": {
"phase": "rewrite",
"functions": ["return function() if ngx.var.scheme == \"http\" and ngx.var.host == \"foo.com\" then ngx.header[\"Location\"] = \"https://foo.com\" .. ngx.var.request_uri; ngx.exit(ngx.HTTP_MOVED_PERMANENTLY); end; end"]
}
}
}'

To test this serverless Plugin:

curl -i -H 'Host: foo.com' http://127.0.0.1:9080/hello

The response should be:

HTTP/1.1 301 Moved Permanently
Date: Mon, 18 May 2020 02:56:04 GMT
Content-Type: text/html
Content-Length: 166
Connection: keep-alive
Location: https://foo.com/hello
Server: APISIX web server

<html>
<head><title>301 Moved Permanently</title></head>
<body>
<center><h1>301 Moved Permanently</h1></center>
<hr><center>openresty</center>
</body>
</html>

How do I change Apache APISIX's log level?#

By default the log level of Apache APISIX is set to warn. You can set this to info to trace the messages printed by core.log.info.

For this, you can set the error_log_level parameter in your configuration file (conf/config.yaml) as shown below and reload Apache APISIX.

nginx_config:
error_log_level: "info"

How do I reload my custom Plugins for Apache APISIX?#

All Plugins in Apache APISIX are hot reloaded.

You can learn more about hot reloading of Plugins here.

How do I configure Apache APISIX to listen on multiple ports when handling HTTP or HTTPS requests?#

By default, Apache APISIX listens only on port 9080 when handling HTTP requests.

To configure Apache APISIX to listen on multiple ports, you can:

  1. Modify the parameter node_listen in conf/config.yaml:

     apisix:
    node_listen:
    - 9080
    - 9081
    - 9082

    Similarly for HTTPS requests, modify the parameter ssl.listen_port in conf/config.yaml:

    apisix:
    ssl:
    listen_port:
    - 9443
    - 9444
    - 9445
  2. Reload or restart Apache APISIX.

How does Apache APISIX achieve millisecond-level configuration synchronization?#

Apache APISIX uses etcd for its configuration center. etcd provides subscription functions like watch and watchdir that can monitor changes to specific keywords or directories.

In Apache APISIX, we use etcd.watchdir to monitor changes in a directory.

If there is no change in the directory being monitored, the process will be blocked until it times out or run into any errors.

If there are changes in the directory being monitored, etcd will return this new data within milliseconds and Apache APISIX will update the cache memory.

How do I customize the Apache APISIX instance id?#

By default, Apache APISIX reads the instance id from conf/apisix.uid. If this is not found and no id is configured, Apache APISIX will generate a uuid for the instance id.

To specify a meaningful id to bind Apache APISIX to your internal system, set the id in your conf/config.yaml file:

apisix:
id: "your-id"

Why are there errors saying "failed to fetch data from etcd, failed to read etcd dir, etcd key: xxxxxx" in the error.log?#

Please follow the troubleshooting steps described below:

  1. Make sure that there aren't any networking issues between Apache APISIX and your etcd deployment in your cluster.

  2. If your network is healthy, check whether you have enabled the gRPC gateway for etcd. The default state depends on whether you used command line options or a configuration file to start the etcd server.

    • If you used command line options, gRPC gateway is enabled by default. You can enable it manually as shown below:
    etcd --enable-grpc-gateway --data-dir=/path/to/data

    Note: This flag is not shown while running etcd --help.

    • If you used a configuration file, gRPC gateway is disabled by default. You can manually enable it as shown below:

    In etcd.json:

    {
    "enable-grpc-gateway": true,
    "data-dir": "/path/to/data"
    }

    In etcd.conf.yml:

    enable-grpc-gateway: true

Note: This distinction was eliminated by etcd in their latest master branch but wasn't backported to previous versions.

How do I setup high availability Apache APISIX clusters?#

Apache APISIX can be made highly available by adding a load balancer in front of it as APISIX's data plane is stateless and can be scaled when needed.

The control plane of Apache APISIX is highly available as it relies only on an etcd cluster.

Why does the make deps command fail when installing Apache APISIX from source?#

When executing make deps to install Apache APISIX from source, you can get an error as shown below:

$ make deps
......
Error: Failed installing dependency: https://luarocks.org/luasec-0.9-1.src.rock - Could not find header file for OPENSSL
No file openssl/ssl.h in /usr/local/include
You may have to install OPENSSL in your system and/or pass OPENSSL_DIR or OPENSSL_INCDIR to the luarocks command.
Example: luarocks install luasec OPENSSL_DIR=/usr/local
make: *** [deps] Error 1

This is caused by the missing OpenResty openssl development kit. To install it, refer installing dependencies.

How do I access the APISIX Dashboard through Apache APISIX proxy?#

You can follow the steps below to configure this:

  1. Configure different ports for Apache APISIX proxy and Admin API. Or, disable the Admin API.
apisix:
port_admin: 9180 # use a separate port
  1. Add a proxy Route for the Apache APISIX dashboard:
curl -i http://127.0.0.1:9180/apisix/admin/routes/1  -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
"uris":[ "/*" ],
"name":"apisix_proxy_dashboard",
"upstream":{
"nodes":[
{
"host":"127.0.0.1",
"port":9000,
"weight":1
}
],
"type":"roundrobin"
}
}'

Note: The Apache APISIX Dashboard is listening on 127.0.0.1:9000.

How do I use regular expressions (regex) for matching uri in a Route?#

You can use the vars field in a Route for matching regular expressions:

curl -i http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
"uri": "/*",
"vars": [
["uri", "~~", "^/[a-z]+$"]
],
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:1980": 1
}
}
}'

And to test this request:

# uri matched
$ curl http://127.0.0.1:9080/hello -i
HTTP/1.1 200 OK
...

# uri didn't match
$ curl http://127.0.0.1:9080/12ab -i
HTTP/1.1 404 Not Found
...

For more info on using vars refer to lua-resty-expr.

Does the Upstream node support configuring a FQDN address?#

Yes. The example below shows configuring the FQDN httpbin.default.svc.cluster.local (a Kubernetes service):

curl http://127.0.0.1:9080/apisix/admin/routes/1  -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
"uri": "/ip",
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.default.svc.cluster.local": 1
}
}
}'

To test this Route:

$ curl http://127.0.0.1:9080/ip -i
HTTP/1.1 200 OK
...

What is the X-API-KEY of the Admin API? Can it be modified?#

X-API-KEY of the Admin API refers to the apisix.admin_key.key in your conf/config.yaml file. It is the access token for the Admin API.

By default, it is set to edd1c9f034335f136f87ad84b625c8f1 and can be modified by changing the parameter in your conf/config.yaml file:

apisix:
admin_key
-
name: "admin"
key: newkey
role: admin

Now, to access the Admin API:

$ curl -i http://127.0.0.1:9080/apisix/admin/routes/1  -H 'X-API-KEY: newkey' -X PUT -d '
{
"uris":[ "/*" ],
"name":"admin-token-test",
"upstream":{
"nodes":[
{
"host":"127.0.0.1",
"port":1980,
"weight":1
}
],
"type":"roundrobin"
}
}'

HTTP/1.1 200 OK
......

Note: By using the default token, you could be exposed to security risks. It is required to update it when deploying to a production environment.

How do I allow all IPs to access Apache APISIX's Admin API?#

By default, Apache APISIX only allows IPs in the range 127.0.0.0/24 to access the Admin API.

To allow IPs in all ranges, you can update your configuration file as show below and restart or reload Apache APISIX.

apisix:
allow_admin:
- 0.0.0.0/0

Note: This should only be used in non-production environments to allow all clients to access Apache APISIX and is not safe for production environments. Always authorize specific IP addresses or address ranges for production environments.

How do I auto renew SSL certificates with acme.sh?#

You can run the commands below to achieve this:

curl --output /root/.acme.sh/renew-hook-update-apisix.sh --silent https://gist.githubusercontent.com/anjia0532/9ebf8011322f43e3f5037bc2af3aeaa6/raw/65b359a4eed0ae990f9188c2afa22bacd8471652/renew-hook-update-apisix.sh
chmod +x /root/.acme.sh/renew-hook-update-apisix.sh
acme.sh  --issue  --staging  -d demo.domain --renew-hook "/root/.acme.sh/renew-hook-update-apisix.sh  -h http://apisix-admin:port -p /root/.acme.sh/demo.domain/demo.domain.cer -k /root/.acme.sh/demo.domain/demo.domain.key -a xxxxxxxxxxxxx"
acme.sh --renew --domain demo.domain

You can check this post for a more detailed instruction on setting this up.

How do I strip a prefix from a path before forwarding to Upstream in Apache APISIX?#

To strip a prefix from a path in your route, like to take /foo/get and strip it to /get, you can use the proxy-rewrite Plugin:

curl -i http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
"uri": "/foo/*",
"plugins": {
"proxy-rewrite": {
"regex_uri": ["^/foo/(.*)","/$1"]
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org:80": 1
}
}
}'

And to test this configuration:

curl http://127.0.0.1:9080/foo/get -i
HTTP/1.1 200 OK
...
{
...
"url": "http://127.0.0.1/get"
}

How do I fix the error unable to get local issuer certificate in Apache APISIX?#

You can manually set the path to your certificate by adding it to your conf/config.yaml file as shown below:

apisix:
ssl:
ssl_trusted_certificate: /path/to/certs/ca-certificates.crt

Note: When you are trying to connect TLS services with cosocket and if APISIX does not trust the peer's TLS certificate, you should set the parameter apisix.ssl.ssl_trusted_certificate.

For example, if you are using Nacos for service discovery in APISIX, and Nacos has TLS enabled (configured host starts with https://), you should set apisix.ssl.ssl_trusted_certificate and use the same CA certificate as Nacos.

How do I fix the error module 'resty.worker.events' not found in Apache APISIX?#

This error is caused by installing Apache APISIX in the /root directory. The worker process would by run by the user "nobody" and it would not have enough permissions to access the files in the /root directory.

To fix this, you can change the APISIX installation directory to the recommended directory: /usr/local.

What is the difference between plugin-metadata and plugin-configs in Apache APISIX?#

The differences between the two are described in the table below:

plugin-metadataplugin-config
Metadata of a Plugin shared by all configuration instances of the Plugin.Collection of configuration instances of multiple different Plugins.
Used when there are property changes that needs to be propagated across all configuration instances of a Plugin.Used when you need to reuse a common set of configuration instances so that it can be extracted to a plugin-config and bound to different Routes.
Takes effect on all the entities bound to the configuration instances of the Plugin.Takes effect on Routes bound to the plugin-config.

Where can I find more answers?#

You can find more answers on: