Top Related Projects
Build highly concurrent, distributed, and resilient message-driven applications on the JVM
Netty project - an event-driven asynchronous network application framework
The Java gRPC implementation. HTTP/2 based RPC
Spring Framework
Apache Thrift
ZeroMQ core engine in C++, implements ZMTP/3.1
Quick Overview
Finagle is a fault-tolerant, protocol-agnostic RPC system for the JVM (Java Virtual Machine). It is designed to make building concurrent network applications easier and more robust. Finagle provides a set of abstractions and tools that simplify the process of creating and consuming network services, handling failures, and managing resources.
Pros
- Fault Tolerance: Finagle is designed to be fault-tolerant, automatically handling network failures, retrying requests, and load-balancing across multiple servers.
- Protocol Agnostic: Finagle supports a wide range of protocols, including HTTP, Thrift, Mux, and more, allowing developers to build services that can communicate using different protocols.
- Scalability: Finagle is built to handle high-concurrency workloads, with support for features like connection pooling, circuit breakers, and load balancing.
- Extensibility: Finagle provides a modular and extensible architecture, allowing developers to customize and extend its functionality to fit their specific needs.
Cons
- Complexity: Finagle has a steep learning curve, with a large number of concepts and configurations to understand, which can make it challenging for new users to get started.
- Java/Scala-Centric: Finagle is primarily designed for the JVM ecosystem, which may limit its adoption in other language communities.
- Performance Overhead: Finagle's abstractions and fault-tolerance features can introduce some performance overhead, which may be a concern for latency-sensitive applications.
- Limited Documentation: While Finagle has a large and active community, the documentation can be sparse in some areas, making it harder for developers to find solutions to specific problems.
Code Examples
Here are a few examples of how to use Finagle in your code:
Creating a Simple HTTP Server
import com.twitter.finagle.Http
import com.twitter.finagle.http.{Request, Response}
import com.twitter.util.Future
object HttpServer {
def main(args: Array[String]): Unit = {
val server = Http.server
.withLabel("my-http-server")
.serve(":8080", (request: Request) => {
val response = Response()
response.setContentString("Hello, Finagle!")
Future.value(response)
})
println("Server started on port 8080")
server.join()
}
}
This code creates a simple HTTP server that listens on port 8080 and responds with the message "Hello, Finagle!".
Consuming a Thrift Service
import com.twitter.finagle.Thrift
import com.twitter.finagle.thrift.ClientId
import com.twitter.util.Await
import example.thrift.ExampleService
object ThriftClient {
def main(args: Array[String]): Unit = {
val client = Thrift.client
.withLabel("my-thrift-client")
.newIface[ExampleService.FutureIface]("localhost:9090")
val response = client.doSomething("Hello, Finagle!")
println(Await.result(response))
}
}
This code creates a Thrift client that connects to a Thrift service running on localhost:9090
and calls the doSomething
method, printing the response.
Customizing a Finagle Service
import com.twitter.finagle.Http
import com.twitter.finagle.http.{Request, Response}
import com.twitter.finagle.stats.NullStatsReceiver
import com.twitter.finagle.tracing.NullTracer
import com.twitter.util.Future
object CustomizedHttpServer {
def main(args: Array[String]): Unit = {
val server = Http.server
.withLabel("my-customized-http-server")
.withStatsReceiver(NullStatsReceiver)
.withTracer(NullTracer)
.serve(":8080", (request: Request) => {
val response = Response()
response.
Competitor Comparisons
Build highly concurrent, distributed, and resilient message-driven applications on the JVM
Pros of Akka
- More comprehensive actor-based concurrency model
- Supports multiple programming paradigms (actors, streams, HTTP)
- Larger ecosystem with additional modules and extensions
Cons of Akka
- Steeper learning curve due to its broader scope
- Can be overkill for simpler use cases
- Requires more boilerplate code for basic setups
Code Comparison
Akka (Actor creation):
class MyActor extends Actor {
def receive = {
case "hello" => println("Hello, world!")
}
}
val system = ActorSystem("MySystem")
val myActor = system.actorOf(Props[MyActor], "myactor")
Finagle (Service creation):
val service = new Service[HttpRequest, HttpResponse] {
def apply(request: HttpRequest): Future[HttpResponse] =
Future.value(HttpResponse(status = Status.Ok))
}
Both Akka and Finagle are powerful frameworks for building distributed systems, but they have different focuses. Akka provides a comprehensive toolkit for building concurrent and distributed applications using the actor model, while Finagle is more specialized for building high-performance RPC systems and microservices.
Finagle offers a simpler API for specific use cases, making it easier to get started with for certain types of projects. However, Akka's broader scope and extensive ecosystem make it more versatile for a wide range of applications, from small services to large-scale distributed systems.
Netty project - an event-driven asynchronous network application framework
Pros of Netty
- More flexible and general-purpose, suitable for a wider range of network applications
- Lower-level API, offering finer control over network operations
- Larger community and ecosystem, with more third-party extensions and integrations
Cons of Netty
- Steeper learning curve due to its lower-level nature
- Requires more boilerplate code for common use cases
- Less opinionated, which can lead to inconsistencies in implementation across projects
Code Comparison
Netty example:
public class EchoServerHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
ctx.write(msg);
ctx.flush();
}
}
Finagle example:
val server = Http.server
.serve(":8080", Service.mk { req: Request =>
Future.value(Response(req.version, Status.Ok))
})
Summary
Netty is a more versatile and lower-level networking framework, offering greater flexibility but requiring more setup. Finagle, built on top of Netty, provides a higher-level abstraction with built-in features for distributed systems, making it easier to use for specific use cases but potentially less flexible for others. The choice between the two depends on the specific requirements of the project and the desired level of abstraction.
The Java gRPC implementation. HTTP/2 based RPC
Pros of gRPC-Java
- Built on HTTP/2, offering better performance and features like bidirectional streaming
- Strong focus on cross-platform compatibility and language-agnostic design
- Extensive documentation and wide community adoption
Cons of gRPC-Java
- Steeper learning curve compared to Finagle's simpler API
- Less flexible for non-RPC communication patterns
- Requires more boilerplate code for basic setup
Code Comparison
Finagle (Scala):
val server = Http.serve(":8080", service)
val client = Http.newService("localhost:8080")
gRPC-Java:
Server server = ServerBuilder.forPort(8080)
.addService(new GreeterImpl())
.build()
.start();
ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 8080)
.usePlaintext()
.build();
Key Differences
- Finagle is primarily designed for Scala, while gRPC-Java is Java-centric but supports multiple languages
- Finagle offers a more flexible, general-purpose networking stack, whereas gRPC-Java is specifically tailored for RPC
- gRPC-Java has stronger built-in support for protocol buffers and code generation
- Finagle provides more fine-grained control over network protocols and configurations
Both libraries are powerful tools for building distributed systems, with gRPC-Java excelling in cross-platform RPC scenarios and Finagle offering more flexibility for diverse networking needs.
Spring Framework
Pros of Spring Framework
- Comprehensive ecosystem with extensive documentation and community support
- Modular architecture allowing developers to use only needed components
- Seamless integration with various Java EE technologies and third-party libraries
Cons of Spring Framework
- Steeper learning curve due to its vast feature set and complexity
- Can be considered "heavyweight" for smaller applications
- Configuration can be verbose, especially in XML-based setups
Code Comparison
Spring Framework:
@RestController
public class HelloController {
@GetMapping("/hello")
public String hello() {
return "Hello, World!";
}
}
Finagle:
val server = Http.serve(":8080", new Service[Request, Response] {
def apply(request: Request): Future[Response] =
Future.value(Response(Status.Ok, "Hello, World!"))
})
Spring Framework offers a more declarative approach with annotations, while Finagle uses a more functional programming style. Spring's code is more concise for simple use cases, but Finagle provides finer-grained control over request handling and response creation.
Apache Thrift
Pros of Thrift
- Multi-language support: Thrift supports a wide range of programming languages, making it more versatile for cross-language development
- Simpler learning curve: Thrift has a more straightforward API and is generally easier to get started with
- Compact binary protocol: Thrift's binary protocol is more efficient for data serialization and deserialization
Cons of Thrift
- Less advanced features: Thrift lacks some of the more sophisticated features found in Finagle, such as advanced load balancing and circuit breaking
- Limited runtime flexibility: Thrift's generated code is less flexible at runtime compared to Finagle's dynamic approach
Code Comparison
Thrift (IDL definition):
service Calculator {
i32 add(1: i32 num1, 2: i32 num2)
}
Finagle (Scala):
val server = Http.serve(":8080", new Service[Request, Response] {
def apply(request: Request): Future[Response] = ???
})
Both frameworks provide ways to define services, but Thrift uses an Interface Definition Language (IDL) while Finagle allows for more direct service implementation in the target language.
ZeroMQ core engine in C++, implements ZMTP/3.1
Pros of libzmq
- Lightweight and low-latency messaging library
- Supports multiple transport protocols (TCP, IPC, inproc)
- Language-agnostic with bindings for many programming languages
Cons of libzmq
- Less built-in support for high-level patterns and abstractions
- Requires more manual configuration for complex networking scenarios
- Limited built-in support for service discovery and load balancing
Code Comparison
libzmq:
void *context = zmq_ctx_new();
void *socket = zmq_socket(context, ZMQ_REQ);
zmq_connect(socket, "tcp://localhost:5555");
zmq_send(socket, "Hello", 5, 0);
zmq_close(socket);
zmq_ctx_destroy(context);
Finagle:
val client: Service[Request, Response] = Http.client
.withTls(("example.com", 443))
.newService("example.com:443")
val request = Request(Method.Get, "/")
val response: Future[Response] = client(request)
Key Differences
- libzmq focuses on low-level messaging primitives, while Finagle provides higher-level abstractions for building distributed systems
- Finagle is primarily designed for JVM languages, whereas libzmq has broader language support
- Finagle includes built-in support for service discovery, load balancing, and circuit breaking, which are not natively provided by libzmq
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
Finagle
Status
This project is used in production at Twitter (and many other organizations), and is being actively developed and maintained.
Releases
Releases are done on an approximately monthly schedule. While semver is not followed, the changelogs are detailed and include sections on public API breaks and changes in runtime behavior.
Getting involved
- Website: https://twitter.github.io/finagle/
- Source: https://github.com/twitter/finagle/
- Mailing List: finaglers@googlegroups.com
- Chat: https://gitter.im/twitter/finagle
- Blog: https://finagle.github.io/blog/
Finagle is an extensible RPC system for the JVM, used to construct high-concurrency servers. Finagle implements uniform client and server APIs for several protocols, and is designed for high performance and concurrency. Most of Finagleâs code is protocol agnostic, simplifying the implementation of new protocols.
For extensive documentation, please see the user guide and API documentation websites. Documentation improvements are always welcome, so please send patches our way.
Adopters
The following are a few of the companies that are using Finagle:
For a more complete list, please see our adopter page. If your organization is using Finagle, consider adding a link there and sending us a pull request!
Contributing
We feel that a welcoming community is important and we ask that you follow Twitter's Open Source Code of Conduct in all interactions with the community.
The release
branch of this repository contains the latest stable release of
Finagle, and weekly snapshots are published to the develop
branch. In general
pull requests should be submitted against develop
. See
CONTRIBUTING.md
for more details about how to contribute.
License
Copyright 2010 Twitter, Inc.
Licensed under the Apache License, Version 2.0: https://www.apache.org/licenses/LICENSE-2.0
Top Related Projects
Build highly concurrent, distributed, and resilient message-driven applications on the JVM
Netty project - an event-driven asynchronous network application framework
The Java gRPC implementation. HTTP/2 based RPC
Spring Framework
Apache Thrift
ZeroMQ core engine in C++, implements ZMTP/3.1
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot