• Stars
    star
    244
  • Rank 165,885 (Top 4 %)
  • Language
    Go
  • License
    MIT License
  • Created about 7 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Reverse proxy for STDIO and HTTP microservices

of-watchdog

Reverse proxy for HTTP microservices and STDIO

Go Report Card build License: MIT OpenFaaS

The of-watchdog implements an HTTP server listening on port 8080, and acts as a reverse proxy for running functions and microservices. It can be used independently, or as the entrypoint for a container with OpenFaaS.

This version of the OpenFaaS watchdog adds support for HTTP proxying as well as STDIO, which enables reuse of memory and very fast serving of requests. It does not aim to replace the Classic Watchdog, but offers another option for those who need these features.

A download is made via GitHub releases, but the watchdog is meant to be copied from the container image published to ghcr.io in a multi-stage build:

FROM --platform=${TARGETPLATFORM:-linux/amd64} ghcr.io/openfaas/of-watchdog:0.9.11 as watchdog
FROM --platform=${TARGETPLATFORM:-linux/amd64} node:18-alpine as ship

COPY --from=watchdog /fwatchdog /usr/bin/fwatchdog

See example templates

Goals

  • Keep function process warm for lower latency / caching / persistent connections through using HTTP
  • Enable streaming of large responses from functions, beyond the RAM or disk capacity of the container
  • Cleaner abstractions for each "mode"

Modes

There are several modes available for the of-watchdog which changes how it interacts with your microservice or function code.

Modes for of-watchdog

A comparison of three watchdog modes. Top left - Classic Watchdog, top right: afterburn (deprecated), bottom left HTTP mode from of-watchdog.

  1. HTTP mode - the default and most efficient option all template authors should consider this option if the target language has a HTTP server implementation.
  2. Serializing mode - for when a HTTP server implementation doesn't exist, STDIO is read into memory then sent into a forked process.
  3. Streaming mode - as per serializing mode, however the request and response are both streamed instead of being buffered completely into memory before the function starts running.

API

Private endpoints, served by watchdog:

  • /_/health - returns true when the process is started, or if a lock file is in use, when that file exists.
  • /_/ready - as per /_/health, but if max_inflight is configured to a non-zero value, and the maximum number of connections is met, it will return a 429 status

Any other HTTP requests:

  • /* any other Path and HTTP verbs are sent to the function

1. HTTP (mode=http)

1.1 Status

HTTP mode is recommend for all templates where the target language has a HTTP server implementation available.

See a few different examples of templates, more are available via faas-cli template store list

Template HTTP framework Repo
Node.js 12 (LTS) Express.js https://github.com/openfaas/templates/
Python 3 & 2.7 Flask https://github.com/openfaas-incubator/python-flask-template
Golang Go HTTP (stdlib) https://github.com/openfaas-incubator/golang-http-template
Golang (http.HandlerFunc) https://github.com/openfaas-incubator/golang-http-template
Ruby Sinatra https://github.com/openfaas-incubator/ruby-http
Java 11 Sun HTTP / Gradle https://github.com/openfaas/templates/

Unofficial: .NET Core / C# and Kestrel

1.2 Description

A process is forked when the watchdog starts, we then forward any request incoming to the watchdog to a HTTP port within the container.

Pros:

  • Fastest option for high concurrency and throughput
  • More efficient concurrency and RAM usage vs. forking model
  • Database connections can be persisted for the lifetime of the container
  • Files or models can be fetched and stored in /tmp/ as a one-off initialization task and used for all requests after that
  • Does not require new/custom client libraries like afterburn but makes use of a long-running daemon such as Express.js for Node or Flask for Python

Example usage for testing:

  • Forward to an Nginx container:
$ go build ; mode=http port=8081 fprocess="docker run -p 80:80 --name nginx -t nginx" upstream_url=http://127.0.0.1:80 ./of-watchdog
  • Forward to a Node.js / Express.js hello-world app:
$ go build ; mode=http port=8081 fprocess="node expressjs-hello-world.js" upstream_url=http://127.0.0.1:3000 ./of-watchdog

Cons:

  • One more HTTP hop in the chain between the client and the function
  • Daemons such as express/flask/sinatra can be unpredictable when used in this way so many need additional configuration
  • Additional memory may be occupied between invocations vs. forking model

2. Serializing fork (mode=serializing)

2.1 Status

This mode is designed to replicate the behaviour of the original watchdog for backwards compatibility.

2.2 Description

Forks one process per request. Multi-threaded. Ideal for retro-fitting a CGI application handler i.e. for Flask.

Limited to processing files sized as per available memory.

Reads entire request into memory from the HTTP request. At this point we serialize or modify if required. That is then written into the stdin pipe.

  • Stdout pipe is read into memory and then serialized or modified if necessary before being written back to the HTTP response.
  • A static Content-type can be set ahead of time.
  • HTTP headers can be set even after executing the function (not implemented).
  • Exec timeout: supported.

3. Streaming fork (mode=streaming) - default.

Forks a process per request and can deal with a request body larger than memory capacity - i.e. 512mb VM can process multiple GB of video.

HTTP headers cannot be sent after function starts executing due to input/output being hooked-up directly to response for streaming efficiencies. Response code is always 200 unless there is an issue forking the process. An error mid-flight will have to be picked up on the client. Multi-threaded.

  • Input is sent back to client as soon as it's printed to stdout by the executing process.
  • A static Content-type can be set ahead of time.
  • Exec timeout: supported.

4. Static (mode=static)

This mode starts an HTTP file server for serving static content found at the directory specified by static_path.

See an example in the Hugo blog post.

Metrics

Name Description Type
http_requests_total Total number of requests Counter
http_request_duration_seconds Duration of requests Histogram
http_requests_in_flight Number of requests in-flight Gauge

Configuration

Environmental variables:

Note: timeouts should be specified as Golang durations i.e. 1m or 20s.

Option Usage
fprocess / function_process Process to execute a server in http mode or to be executed for each request in the other modes. For non http mode the process must accept input via STDIN and print output via STDOUT. Also known as "function process".
mode The mode which of-watchdog operates in, Default streaming see doc. Options are http, serialising fork, streaming fork, static
read_timeout HTTP timeout for reading the payload from the client caller (in seconds)
write_timeout HTTP timeout for writing a response body from your function (in seconds)
exec_timeout Exec timeout for process exec'd for each incoming request (in seconds). Disabled if set to 0.
max_inflight Limit the maximum number of requests in flight, and return a HTTP status 429 when exceeded
prefix_logs When set to true the watchdog will add a prefix of "Date Time" + "stderr/stdout" to every line read from the function process. Default true
log_buffer_size The amount of bytes to read from stderr/stdout for log lines. When exceeded, the user will see an "bufio.Scanner: token too long" error. The default value is bufio.MaxScanTokenSize
healthcheck_interval Interval (in seconds) for HTTP healthcheck by container orchestrator i.e. kubelet. Used for graceful shutdowns.
port Specify an alternative TCP port for testing. Default: 8080
content_type Force a specific Content-Type response for all responses - only in forking/serializing modes.
suppress_lock When set to false the watchdog will attempt to write a lockfile to /tmp/.lock for healthchecks. Default false
http_upstream_url http mode only - where to forward requests i.e. 127.0.0.1:5000
upstream_url alias for http_upstream_url
http_buffer_req_body http mode only - buffers request body in memory before forwarding upstream to your template's upstream_url. Use if your upstream HTTP server does not accept Transfer-Encoding: chunked, for example WSGI tends to require this setting. Default: false
buffer_http deprecated alias for http_buffer_req_body, will be removed in future version
static_path Absolute or relative path to the directory that will be served if mode="static"
ready_path When non-empty, requests to /_/ready will invoke the function handler with this path. This can be used to provide custom readiness logic. When max_inflight is set, the concurrency limit is checked first before proxying the request to the function.

Unsupported options from the Classic Watchdog:

Option Usage
write_debug In the classic watchdog, this prints the response body out to the console
read_debug In the classic watchdog, this prints the request body out to the console
combined_output In the classic watchdog, this returns STDOUT and STDERR in the function's HTTP response, when off it only returns STDOUT and prints STDERR to the logs of the watchdog

More Repositories

1

faas

OpenFaaS - Serverless Functions Made Simple
Go
24,942
star
2

faasd

A lightweight & portable faas engine
Go
2,550
star
3

faas-netes

Serverless Functions For Kubernetes
Go
2,122
star
4

workshop

Learn Serverless for Kubernetes with OpenFaaS
Python
955
star
5

faas-cli

Official CLI for OpenFaaS
Go
794
star
6

openfaas-cloud

The Multi-user OpenFaaS Platform
Go
767
star
7

templates

OpenFaaS Classic templates
Dockerfile
261
star
8

ofc-bootstrap

Bootstrap OpenFaaS Cloud for your team
Go
181
star
9

store

Official Function and Template Store for OpenFaaS
Shell
162
star
10

faas-provider

A backend provider interface for OpenFaaS
Go
123
star
11

nats-queue-worker

Queue-worker for OpenFaaS with NATS Streaming
Go
122
star
12

golang-http-template

Golang templates for OpenFaaS using HTTP extensions
Shell
100
star
13

openfaas-linkerd-workshop

Lightweight Serverless on Kubernetes with mTLS and traffic-splitting with Linkerd2
98
star
14

python-flask-template

HTTP and Flask-based OpenFaaS templates for Python 3
Python
82
star
15

faas-swarm

OpenFaaS provider for Docker Swarm
Go
79
star
16

ingress-operator

Custom domains, paths and TLS for your OpenFaaS Functions
Go
68
star
17

docs

Official Docs for OpenFaaS
65
star
18

community-cluster

OpenFaaS Cloud Cluster for Community
60
star
19

connector-sdk

SDK for connecting events to functions
Go
56
star
20

openfaas.github.io

Primary website / landing-page for the project
HTML
53
star
21

store-functions

Common CLIs packaged in containers with a HTTP interface
Dockerfile
51
star
22

media

Press kit / Media pack for OpenFaaS
44
star
23

cron-connector

Invoke functions on a schedule.
Go
39
star
24

nats-connector

An OpenFaaS event-connector to trigger functions from NATS
Go
38
star
25

mqtt-connector

MQTT connector for OpenFaaS
Go
32
star
26

cloud-functions

OpenFaaS social functions
Python
28
star
27

classic-watchdog

Classic Watchdog for OpenFaaS
Go
25
star
28

certifier

OpenFaaS Compliance testing
Go
25
star
29

license-check

Check your code for Copyright header compliance
Go
19
star
30

ruby-http

A Ruby HTTP template for OpenFaaS
Ruby
12
star
31

faas-middleware

HTTP middleware for OpenFaaS
Go
12
star
32

templates-sdk

SDK resources for templates such as models and entrypoints
Java
10
star
33

function-builder-examples

OpenFaaS Pro function builder API examples
PHP
10
star
34

social-functions

Enabling social media for OpenFaaS
Go
9
star
35

cli.openfaas.com

The installation script for the OpenFaaS CLI served by Netlify
Shell
9
star
36

python-fan-in-example

Python code example for implementing a fan-out/fan-in pattern with OpenFaaS functions.
Python
8
star
37

config-checker

Check your OpenFaaS Configuration
Go
7
star
38

astradb-openfaas

Connect to Astra DB using Node.js and OpenFaaS
JavaScript
3
star
39

go-sdk

An SDK for use within OpenFaaS functions
Go
3
star
40

openfaas-autoscaler-tests

JavaScript
2
star
41

derek-test-repo

Testing compliance
1
star
42

.github

README for organisation
1
star
43

multi-tenant-tests

Basic multi-tenant-tests
JavaScript
1
star