Rest 你能在CloudFoundry中使用节俭作为应用程序之间的通信方式吗?

Rest 你能在CloudFoundry中使用节俭作为应用程序之间的通信方式吗?,rest,thrift,cloud-foundry,Rest,Thrift,Cloud Foundry,Cloud Foundry是否支持在应用程序之间进行通话?我找不到这方面的任何信息,似乎REST/HTTP或消息传递是应用程序间通信的首选机制 是否有人试图在CF中提供使用节俭的服务?有没有什么好的理由不支持节俭;或者有什么计划来支持它?对于跨语言通信,我更喜欢Thrift而不是REST,因为在Thrift中很容易生成API调用中使用的所有客户端类。此外,它还支持二进制数据传输,因此可能比REST更快。另外,我们已经有了一个节俭API:) 我猜想——理论上——一个客户端应用程序可以直接与另一个运

Cloud Foundry是否支持在应用程序之间进行通话?我找不到这方面的任何信息,似乎REST/HTTP或消息传递是应用程序间通信的首选机制

是否有人试图在CF中提供使用节俭的服务?有没有什么好的理由不支持节俭;或者有什么计划来支持它?对于跨语言通信,我更喜欢Thrift而不是REST,因为在Thrift中很容易生成API调用中使用的所有客户端类。此外,它还支持二进制数据传输,因此可能比REST更快。另外,我们已经有了一个节俭API:)

我猜想——理论上——一个客户端应用程序可以直接与另一个运行Thrift服务的CF应用程序实例对话;但是,您将失去CF目前为HTTP或消息传递提供的负载平衡优势。

云铸造厂目前只支持HTTP/HTTPS请求的路由。目前正在努力创建一个TCP路由器,以处理到CF上运行的应用程序的非HTTP流量路由

如果您正在通过BOSH部署自己的CF,则可以预览TCP路由器将提供的一些功能,以及包括TCP路由器的

这将是一个很好的地方问更多的问题

我猜想——理论上——客户端应用程序可以直接与另一个运行Thrift服务的CF应用程序实例对话

这是正确的-在CF上运行的应用程序可以使用任何协议相互通信,只要配置的应用程序打开了正确的端口

对于通过HTTP和Thrift发送的内容是否存在重要限制?另外,我想了解更多关于客户机如何在您的服务上调用不同方法的信息。您是否有一个通用的HTTP方法,或者最终得到了一个类似REST的API,它反映了您的Thrift API的方法

下面是处理传入请求并返回结果的代码。这段代码是我不久前为一家德国开发杂志写的一篇文章的一部分。整个软件包由一些JavaScript、一些C#和一些Delphi代码组成。我要强调的是,我们也使用了在实际代码中显示的相同方法

Delphi附带了对ISAPI的内置支持。OnHandleration基本上是一个事件处理程序,可以分配给选定的URL端点,或者捕获所有请求。这也意味着,我们不需要关心线程管理,因为这是IIS为我们所做的

服务器端 我决定使用
tjson协议
有两个原因。首先,其中一个客户端是JavaScript部分,当时它只能说JSON。第二个目标是消除任何数据混乱的风险。我从未在这种情况下测试过
TBinaryProtocol
TCompactProtocol
,所以我不能对这种组合说太多

procedure TSample.OnHandlerAction( Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
const GENERIC_ERROR_JSON = '[1,"TextToolIsapi",2,0,{"2":{"rec":{"1":{"str":"Internal error: %s"}}}}]';
var b : TBytes;
    s : string;
begin
  try
    Response.Content := TTextToolJsonServer.Process( Request.Content);
  except
    on e:Exception do begin
      b := ( SysUtils.TEncoding.UTF8.GetBytes(e.message));
      SetString( s, PAnsiChar(@b[0]), Length(b));
      Response.Content := Format( GENERIC_ERROR_JSON, [s]);
    end;
  end;
end;
剩下的部分是进行(反)序列化并向处理器提供数据的部分。在这个示例代码中,为每个调用创建一个处理器实例。如果这不合适,可以考虑处理器实例池等。在我们的例子中,特定于会话的数据保存在其他地方,因此处理器实际上非常轻量级

class function TTextToolJsonServer.Process( const aRequest : string) : string;
var handler   : Samples.TTextTool.Iface;
    processor : IProcessor;
    protIn, protOut : IProtocol;
    stmIn, stmOut : TStringStream;
begin
  stmIn  := nil;
  stmOut := nil;
  try
    stmIn  := TStringStream.Create( aRequest);
    stmOut := TStringStream.Create;

    protIn  := TJSONProtocolImpl.Create(
                 TStreamTransportImpl.Create(
                   TThriftStreamAdapterDelphi.Create( stmIn, FALSE), nil));

    protOut := TJSONProtocolImpl.Create(
                 TStreamTransportImpl.Create(
                   nil, TThriftStreamAdapterDelphi.Create( stmOut, FALSE)));

    handler   := TTextToolHandler.Create;
    processor := Samples.TTextTool.TProcessorImpl.Create( handler);
    processor.Process( protIn, protOut);

    result := stmOut.DataString;

  finally
    stmIn.Free;
    stmOut.Free;
  end;
end;
仅此而已,其余部分是标准处理器/处理程序实现

样本客户机 客户端对应项可以像这段JavaScript一样简单。不幸的是,我手头没有Java示例,但它看起来非常相似

  function MakeClient()
  {
    var transport = new Thrift.Transport("bin/TextToolSample.dll"); 
    var protocol  = new Thrift.Protocol(transport);
    var client = new Samples.TextToolClient(protocol);
    return client;
  }

  function CountWords() 
  {
    try
    {
      var client = MakeClient();
      var nCount = client.CountWords( document.EDITOR.textinput.value);
      alert("Text contains "+nCount.toString()+" words.");
    }
    catch (error) 
    {
      HandleError( error) 
    }
  }

根据@JensG建议的解决方案,我想找到一个使用Thrift/HTTP的解决方案。如果您的CF管理员不想支持Thrift/TCP,例如,如果您的CF部署中没有.Net buildpack意味着Thrift服务必须托管在CF之外,那么这是一个后备方案。我在这里分享它,因为我不清楚如何让Thrift/HTTP为C#服务实现工作。节俭0.9.3贯穿始终

节俭IDL文件示例 使用Thrift编译器正常生成C#存根。然后实施服务:

示例服务实现(C#) (博客上给出了一个类似的例子。)将此处理程序放在ASP.Net web应用程序的
App\u code
文件夹中。在web.config中注册处理程序。我在集成模式下使用IIS 7.5,因此我执行了以下操作:

  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
    <handlers>
      <remove name="WebDAV" />
      <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
      <add name="AuthServiceHandler"
           path="*."
           verb="*"
           type="AuthServiceHTTPHandler.App_Code.AuthServiceHandler"
           preCondition="integratedMode,runtimeVersionv4.0" />
    </handlers>
  </system.webServer>

当C#ASP.NET应用程序从Visual Studio 2010发布到IIS 7.5,Java客户端指向它时,HTTP响应主体中的Thrift响应是:

[1,"AskPermission",2,1,{"0":{"rec":{"1":{"str":"Hello Fred"},"2":{"tf":1}}}}]
以及Java日志输出:

Response in JSON format: {"reply":"Hello Fred","permissionGranted":true,"setPermissionGranted":true,"setReply":true}

我最初尝试实现一个新的。但是,尽管HTTP响应中返回了正确的Thrift响应,但HTTP头始终是
405:Method Not Allowed
(Thrift客户端使用POST发送其请求)。关于这件事,我有点担心。但是,从长远来看,使用HTTP处理程序可能比使用模块要好,因为您可以选择为长期运行的请求创建一个HTTP处理程序。

我不了解Cloud Foundry,但可能会有所帮助。我们使用现有的HTTP(S)服务器构建了一个解决方案。只有请求数据的反序列化是通过Thrift完成的,服务器本身是插入扩展模块的标准产品。这样,我们就不需要运行自己的服务器,获得所有产品功能,只需处理反序列化,向Thrift处理器提供请求,并以相同的方式返回结果。最重要的是,这方面的基础设施非常简单,实际上只有几行代码。适用于所有Thrift HTTP客户端。我想说的是:仅使用Thrift的序列化部分对非标准通信通道很有帮助。根据通道的功能,序列化为一种二进制格式,或者,如果二进制不是选项,则序列化为JSON。通过任何方式传输数据,并在另一端反序列化数据。这允许使用节俭,即使是松散耦合的系统
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
    <handlers>
      <remove name="WebDAV" />
      <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
      <add name="AuthServiceHandler"
           path="*."
           verb="*"
           type="AuthServiceHTTPHandler.App_Code.AuthServiceHandler"
           preCondition="integratedMode,runtimeVersionv4.0" />
    </handlers>
  </system.webServer>
import org.apache.thrift.TException;
import org.apache.thrift.protocol.TJSONProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.THttpClient;
import org.apache.thrift.transport.TTransport;
import org.apache.thrift.transport.TTransportException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import AuthServiceGenCSharp.thrift.AuthorizationService.Client;
import AuthServiceGenCSharp.thrift.Request;
import AuthServiceGenCSharp.thrift.Result;
TTransport transport = null;
try {
    transport = new THttpClient("http://localhost:9999");
} catch (TTransportException e) {
    e.printStackTrace();
}
TProtocol protocol = new TJSONProtocol(transport);
Client client = new Client(protocol);

try {
    transport.open();
    Request request = new Request("Fred", 32);
    Result result = client.AskPermission(request);
    ObjectMapper mapper = new ObjectMapper();
    String json = mapper.writeValueAsString(result);
    log.info("Response in JSON format: " + json);
    return json;
} catch (TException e) {
    e.printStackTrace();                
} catch (JsonProcessingException e) {                               
    e.printStackTrace();
} finally {
    if (transport != null && transport.isOpen()) {
        transport.close();
    }
}
[1,"AskPermission",2,1,{"0":{"rec":{"1":{"str":"Hello Fred"},"2":{"tf":1}}}}]
Response in JSON format: {"reply":"Hello Fred","permissionGranted":true,"setPermissionGranted":true,"setReply":true}