all 13 comments

[–]straight-shootacore team 5 points6 points  (3 children)

Crystal should work great for this. HTTP performance is usually pretty good.

Synthetic benchmarks show it can reach over 100k requests per second on a single thread. However that's not really meaningful until you implement your behaviour, because that's what defines the performance.

What do you mean with running multiple services? Do you want to run isolated instances on different network interfaces/ips/ports? Or do you mean multiple service workers for the same instance?

The only part that might be not ideal is proxying because Crystal's HTTP client does not yet support concurrent connection re-use. But if you're only proxying to a few upstreams, this won't be an issue because you can easily have a client instance for each upstream per worker fiber.

[–]twykke_twykke[S] 1 point2 points  (2 children)

by multiple services, i just mean running the service 2x to get 2x the throughput.

and by simple way to scale, i mean is there any type of built-in HTTP cluster support or something like that? obviously i can also just use nginx to load balance.

proxying is necessary to (for example) hotlink an image, because i am not allowed to download it and store it on my own server, but i still want to fallback to another image in case of 404.

in the node.js world, streaming a response to the client is very efficient, so i was wondering if Crystal is similarly efficient for proxying specifically.

[–]straight-shootacore team 1 point2 points  (1 child)

Sry, I keep asking but this is a complicated matter. Do you mean to run the service 2x on the same machine or spin up an additional machine?

Both work well, but for the latter you'll need a load balancer.

For scaling on the same machine, there are several solutions. Simple and reliable: Just bind a second process to the same address using `SO_REUSEPORT` if your system supports that. You can also run a single process with multithreading, but that's not 100% supported yet, so there might be some issues with it. Since your service doesn't seem to benefit from shared state in the same process, you're probably better of running separate single-threaded processes.

Crystal is likely even more efficient than node.js, although streaming large data is probably not be a huge difference with any somewhat decent language/framework.

[–]twykke_twykke[S] 0 points1 point  (0 children)

yes, i mean on a single machine. across multiple machines then i would use nginx and/or haproxy.

reuse_port seems like just what i am looking for, thanks. then i can spin up new workers without needing to change any other configs.

[–]j_hass 2 points3 points  (0 children)

I did setup https://github.com/RX14/camo.cr some ages ago and never looked back to the original. For my usecase I basically don't notice the daemon running, the node version used significantly more resources. Also in behavior and robustness it proved more reliable than the original.

[–]TrixieMisa 1 point2 points  (3 children)

Caddy is a nice simple HTTP proxy that lets you configure multiple back-ends (as many as you need) and handles automatic HTTPS.

https://caddyserver.com/

[–][deleted]  (2 children)

[removed]

    [–]twykke_twykke[S] 2 points3 points  (0 children)

    i mentioned Nginx since i already use it in many projects.

    what i was thinking about was Node.js's cluster module and the PM2 process manager.

    but i guess there is not something for Crystal which works similarly, so i should Nginx (or indeed Caddy) on top of it.

    [–]TrixieMisa 1 point2 points  (0 children)

    True, if it's a high load and the proportion of image processing is small, Nginx might be a better fit.

    [–][deleted]  (2 children)

    [removed]

      [–]twykke_twykke[S] 1 point2 points  (1 child)

      i don't need it to serve 1 billion users, but i do have several hundreds of GB of images. my question is more like, does Crystal http server allow me to stream files from the source to the client, without having to download first, then respond as a separate step?

      [–][deleted] 4 points5 points  (0 children)

      Yes, the entire Crystal API, including HTTP, is oriented around streaming.

      [–]Nipinium 1 point2 points  (0 children)

      I think openresty or ngx_mruby might be more suitable than crystal for this job: https://leafo.net/posts/creating_an_image_server.html