[go: nahoru, domu]

Skip to content

marios-code-path/intro-to-riff

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

27 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Introduction to the Project Riff Functions-as-a-Service Platform

1. Motivation

Functions as a Service are a new paradigm for application composition and deployment. Functions are a smaller deployable unit than microservices and especially traditional monoliths. Project Riff is a new Pivotal project that runs functions in a cloud environment like Pivotal Container Services (Kubernetes). Lets get started by setting up a new Riff environment and then creating some functions.

2. Preparing the environment

minikube is the tool that we’ll use to run Kubernetes locally. In this demo, we assume a configuration containing Minikube 0.25 and Helm/tiller 2.7.2. Make sure to start Minikube:

minikube start \
  --memory=4096 \
  --cpus=2

2.1. Navigating uncharted waters with Helm

All of the steps to manually prepare the environment locally are outlined in the Riff Github Repo. Helm is a package manager for Kubernetes. Riff provides helm packages ( Helm "charts" ) to ease installation and migration. For further information on installing Helm, refer to the project’s Installation guide.

2.2. Installing the Riff Environment with Helm

Homebrew can be used to install helm in a jiffy:

brew install kubernetes-helm

Linux and Windows users may use alternative methods, or your simply want to install things manually on OSX, follow the instructions for Helm.

Then, add the Helm chart for Riff:

helm repo add riffrepo https://riff-charts.storage.googleapis.com
helm repo update

Install Riff with the release name demo:

helm install riffrepo/riff --name demo

Once this command is complete, you will have a functioning Riff environment. You can enumerate the Riff componenets using this command:

kubectl get pods --show-labels -l app=riff

You’ll notice several pods in service. The entry point to your functions is demo-riff-http-gateway. Enter the following command to enumerate Kubernetes services and ensure it is accepting connections from localhost;

kubectl get svc -l app=riff

Check that demo-riff-http-gateway has a TYPE of NodePort.

2.2.1. Choosing the right service type for your environment.

If your riff-http-gateway says that EXTERNAL-IP is Pending and fails to resolve after several minutes, then you will need to change the service type.

kubectl edit service demo-riff-http-gateway

Update the type field from LoadBalancer to NodePort, and save. This will expose your riff-http-gateway to the local network.

Additional networking configuration may be necessary as you might have subnetting/firewalls in place, especailly in a controlled environtment.

2.3. Installing the Riff Client

In order to use Riff, you’ll need the riff command line client interface (CLI). Clone the git repository and add it to your PATH. Now you can use riff in the shell.

3. Writing the Function

Riff maintains a registry of functions. These functions can optionally accept payloads as requests and optionally produce replies. Riff will forward requests to your functions and deliver replies from your functions over message channels. Messages originate from a number of different sources: HTTP, Kafka, RabbitMQ, etc. As of this writing, while message payloads are routed through Kafka topics, communication to the front-end of Riff take HTTP requests only.

At the moment, Riff supports the following languages and runtimes: Python, Node.js, /bin/bash, and Java. We will focus on Java in this example. Riff supports three standard Java 8 functional interfaces:

  • java.util.function.Supplier: returns a value but does not accept an argument

  • java.util.function.Function: returns a value and does accept an argument

  • java.util.function.Consumer: does not return a value but does accept an argument.

Let’s look at a simple Function<String,String>, which both accepts an input argument and produces a reply. This is the only one that we will deploy in this article.

DemoFunction.java
package mcp;

import java.util.function.Function;

public class DemoFunction implements Function<String, String> {
  public String apply(String s) {
    return new StringBuilder(s).reverse().toString();
  }
}

4. Executing the function

We will need to create and deploy our function in a container. We can create our own Dockerfile, service description (.yaml) configuration, and container images manually if we wanted to. There is no need to, though, as Riff 0.0.3 will do all this for us!

Deploy a function
riff create --name demofn --input reverse-in \
  --protocol pipes --artifact target/demofn-0.0.1.jar \
  --handler mcp.DemoFunction

This command creates a function. You specify the input and output topics, a fully qualified classname and method, and the artifact (the .jar) that contains the class. Your topics are logical names for pipes that conduct requests and replies between functions.

The following command will locate your riff-http-gateway’s IP and port, then create an HTTP request that will be sent to the `reverse-in topic. We tell Riff to wait for a response payload from the input topic with the --reply parameter.

Invoke the function using the riff CLI.
riff publish --input reverse-in --data GNIRPS --reply

Riff will publish 'GNIRPS' data to the 'reverse-in' topic. By specifying --reply in the riff command, we are requesting that riff await for retured data to print to the console.

5. Scaling the function

Riff uses the function-controller to replicate (or scale) your functions as request rates increase, and decrease over time. The default behavior implements replication factor equal to the number of partitions of the input topic. You can edit a topic resource by using kubectl edit topic MY_TOPIC command and change spec.partitions to your needs. Alternately, the default behavior can be modified by editing the function’s configuration, setting spec.maxReplicas to a desired value.

5.1. Next Steps

We’ve only begun to scratch the surface in this look at Project Riff. It would be worth in another installment looking at using some of the other types of functions - `Consumer`s and `Supplier`s - and look at when and how they’re used. In another installment we could look at how functions connect with each other. In another installment, we could look at how function-capable frameworks like Spring Cloud Function work in the Riff environment.

About

Introduction to Riff (FaaS)

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published