Rack相关知识梳理(二)

简介: 一、Rack中间件 1、什么是中间件 中间件其实就是Ruby应用服务器和Rack应用程序之间执行的代码 2、一个简单的例子 $LOAD_PATH.unshift(File.dirname(__FILE__)) require 'rack' require 'decorator' my_app = l

一、Rack中间件


1、什么是中间件


中间件其实就是Ruby应用服务器和Rack应用程序之间执行的代码


2、一个简单的例子


$LOAD_PATH.unshift(File.dirname(__FILE__)) 
require 'rack'
require 'decorator'
my_app = lambda { |env|
  request = Rack::Request.new(env)
  response = Rack::Response.new 
  response["Content-Type"] = "text/html"
  if request.path_info == "/hello"
    response.write("you say hello")
  else
    response.write("you need say something") 
  end
  response.finish 
}
Rack::Handler::WEBrick.run Decorator.new(my_app), :Port => 3000


这段代码中我们的rack应用程序是一个lambda(lambda具有call方法的) 前面几行没什么好说的,大家看最后一句:


Rack::Handler::WEBrick.run Decorator.new(my_app), :Port => 3000


我们最后传给run的是Decorator对象,这个对象在构造时接受一个rack应用为参数,这个实例既然能被Handler调用,可想而知,我们Decorator必然具备call方法,所以我们也就清楚这个类的结构如下:


class Decorator 
  def initialize(app) 
    ......
  end
  def call(env)
    ......
  end
end


ok,接下来我们编写Decorator


class Decorator 
  def initialize(app)
    @app = app
  end
  def call(env)
    status, headers, body = @app.call(env)
    new_body = "=======beader=========<br/>" 
    body.each { |str| new_body << str }
    new_body << "<br/>======footer=========" 
    headers["Content-Length"] = new_body.bytesize.to_s
    [status, headers, [new_body]]
  end 
end


启动应用,在浏览器上看看效果:


=======beader=========

you say hello

======footer=========


由上可知,Decorator运行在Ruby应用服务器和Rack应用程序之间,因此Decorator就是一个中间件,而且我们可以知道,任何Rack中间件必然是一个合法的Rack应用程序。


3、为什么要用中间件


中间件可以实现通用逻辑和业务逻辑分离,并且这些通用逻辑可以应用到各种各样的业务逻辑中。

 

二、装配中间件


前面我看到一个Rack中间件必然是一个合法的Rack应用程序,那么我们不难想到,一个中间件 外面可以在包装一个中间件,每一个中间件都是独立的,只关心自己的逻辑实现,这样我们就 可以对整个框架或系统中的中间件进行替换,我们还可以用不同的方式去组合多个中间件,从 而满足我们的需求。


1、如何装配中间件


我们往往会在一个应用程序中使用多个中间件,最直接的办法就是new出我们需要的中间件,


例如我们要用middleware1和middleware2两个中间件,那我们可以这样编写代码:


Rack::Handler::WEBrick.run middleware1.new(middleware2.new(rack_app)), :Port => 3000


当然这并不是一个好办法,如果我们要用的中间件非常多,那这段代码就会非常冗⻓,好在Rack已经想到这一点,并且提供了一个非常好的办法:


Rack::Builder


我们利用Builder修改我们之前的代码:


app = lambda { |env|
  request = Rack::Request.new(env) 
  response = Rack::Response.new 
  response["Content-Type"] = "text/html"
  if request.path_info == "/hello"
    response.write("you say hello") 
  else
    response.write("you need say something") 
  end
  response.finish 
}
my_app = Rack::Builder.new { 
  use Decorator
  run app
}.to_app
Rack::Handler::WEBrick.run my_app, :Port => 3000


如果要用多个中间件,那就写成这样:


use middleware1


use middleware2


user middleware3


......


PS:前面大家可能注意到,中间件采用了装饰器的设计模式,所以当使用多个中间件时,各个中间件之间顺序是需要注意的


我们来看看Builder中几个重要的方法


initialize


def initialize(default_app = nil,&block)
  @use, @map, @run, @warmup = [], nil, default_app, nil 
  instance_eval(&block) if block_given?
end


initialize:构造方法,能够接受语句块

 

use


def use(middleware, *args, &block) 
  if @map
    mapping, @map = @map, nil
    @use << proc { |app| generate_map app, mapping } 
  end
  @use << proc { |app| middleware.new(app, *args, &block) } 
end


use:记录要创建的中间件及其顺序。

 

run


def run(app) 
  @run = app
end


run:记录原始的应用程序

 

to_app


def to_app
  app = @map ? generate_map(@run, @map) : @run 
  fail "missing run or map statement" unless app
  app = @use.reverse.inject(app) { |a,e| e[a] } 
  @warmup.call(app) if @warmup
  app
end


to_app:根据use和run中的纪录组合最终的应用程序

相关文章
|
1月前
|
存储 负载均衡
高可用集群相关术语扫盲篇
关于高可用集群相关术语的扫盲篇,涵盖了集群类型、系统可用性、系统故障、提升系统高可用性的解决方案、高可用服务的组件、共享存储、网络分区、双节点集群、HA Cluster实现方案和高可用集群后端存储等多个方面的内容。
37 1
高可用集群相关术语扫盲篇
|
2月前
|
资源调度 分布式计算 算法
【揭秘Yarn调度秘籍】打破资源分配的枷锁,Hadoop Yarn权重调度全攻略!
【8月更文挑战第24天】在大数据处理领域,Hadoop Yarn 是一种关键的作业调度与集群资源管理工具。它支持多种调度器以适应不同需求,默认采用FIFO调度器,但可通过引入基于权重的调度算法来提高资源利用率。该算法根据作业或用户的权重值决定资源分配比例,权重高的可获得更多计算资源,特别适合多用户共享环境。管理员需在Yarn配置文件中启用特定调度器(如CapacityScheduler),并通过设置队列权重来实现资源的动态调整。合理配置权重有助于避免资源浪费,确保集群高效运行,满足不同用户需求。
41 3
|
4月前
|
Kubernetes 关系型数据库 网络架构
ray集群部署vllm的折磨
概括如下: 在构建一个兼容多种LLM推理框架的平台时,开发者选择了Ray分布式框架,以解决资源管理和适配问题。然而,在尝试集成vllm时遇到挑战,因为vllm内部自管理Ray集群,与原有设计冲突。经过一系列尝试,包括调整资源分配、修改vllm源码和利用Ray部署的`placement_group_bundles`特性,最终实现了兼容,但依赖于非官方支持的解决方案。在面对vllm新版本和Ray部署的`reconfigure`方法问题时,又需权衡和调整实现方式。尽管面临困难,开发者认为使用Ray作为统一底层仍具有潜力。
|
并行计算 算法 NoSQL
基于ray 多进程调度管理能力优化networks节点最短路径的并行计算
原生的networkx实现的只能在节点介数度量性任务上达到单核心100的cpu利用率。通过对源码的几行改造我们可以实现多核心的100的利用率。接下来要我们来一起看看是如何实现的多核心100的利用率。
150 0
基于ray 多进程调度管理能力优化networks节点最短路径的并行计算
ES脑裂问题解决方案
ES脑裂问题解决方案
166 0
|
资源调度
每日积累【Day 5】Yarn高可用架构重温
每日积累【Day 5】Yarn高可用架构重温
每日积累【Day 5】Yarn高可用架构重温
|
中间件 应用服务中间件 API
Rack相关知识梳理(一)
一、什么是Rack Rack是ruby应用服务器和Rack应用程序之间的接口, 这里面Ruby应用服务器可以是Webrick、thin等,Rack应用程序可以是rails、Sinatra等(其实 现在主流的ruby的Web框架都是基于Rack的)。在上图中,当用户的请求到达应用服务器时,应用服务器会
549 0
|
中间件
Rack相关知识梳理(三)
Rack为编写Web应用以及Web框架提供了很多便利的工具,那么这一节,我们实现一个最简单的Web框架。 一、Web框架应该具备什么功能 对request和response的存取 路由:根据不同URL执行不同程序 能够处理cookies 能够存取session 能够生成日志 ...... 看上去挺麻
313 0
|
安全 程序员 项目管理
如何做好技术 Team Leader?
作为一个技术TL(Team Leader),除了自身技能,还会面临诸多团队管理上的困难和挑战。如何定义和明确团队的目标?怎样建立优秀的工程文化?让团队长期发挥战斗力和创新能力的核心是什么?本文作者基于四年的团队管理经验,分享他在招聘、目标管理、团队沟通和工程文化等方面的思考与总结,介绍相关的经验方法,并推荐几本关于体验、思考的书籍。希望对同学们有所启发。
如何做好技术 Team Leader?
|
Cloud Native 安全 Java
阿里四年技术 TL 的得失总结:如何做好技术 Team Leader
子曰:吾日三省吾身,反思是人类进化出来的一项异常宝贵的能力。我在阿里带团队也有四年多的时间,有必要总结一下此间得失;另外,前几天和一个刚开始带团队的同学聊天,他觉得角色转变对于他有不小的挑战,因此我想做一点不算成熟的总结并分享出来。
阿里四年技术 TL 的得失总结:如何做好技术 Team Leader