简体   繁体   中英

How to browse application on service fabric?

How do I find out what endpoint I should be requesting in order to trigger GetAccounts?

I've got two applications running on my local cluster: 在此处输入图像描述

在此处输入图像描述

The fabric/Service is a web api application with the following configuration:

internal sealed class Web : StatelessService
    {
        public Web(StatelessServiceContext context)
            : base(context)
        {
        }

        /// <summary>
        ///     Optional override to create listeners (like tcp, http) for this service instance.
        /// </summary>
        /// <returns>The collection of listeners.</returns>
        protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
        {
            return new[]
            {
                new ServiceInstanceListener(serviceContext => new OwinCommunicationListener(Startup.ConfigureApp,
                    serviceContext, ServiceEventSource.Current, "ServiceEndpoint"))
            };
        }
    }

The startup is configured like so:

public static class Startup
{
    // This code configures Web API. The Startup class is specified as a type
    // parameter in the WebApp.Start method.

    public static void ConfigureApp(IAppBuilder appBuilder)
    {
        // Configure Web API for self-host. 
        var config = new HttpConfiguration();
        //config.Routes.MapHttpRoute(
        //    name: "DefaultApi",
        //    routeTemplate: "api/{controller}/{id}",
        //    defaults: new { id = RouteParameter.Optional }
        //);
        config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
        config.MapHttpAttributeRoutes();
        var container = new UnityContainer();
        container.RegisterType<IAccountService, AccountService>(new HierarchicalLifetimeManager());
        config.DependencyResolver = new UnityResolver(container);

        appBuilder.UseWebApi(config);
    }
}

And finally the service manifest:

<?xml version="1.0" encoding="utf-8"?>

<ServiceManifest Name="WebPkg"
                 Version="1.0.0"
                 xmlns="http://schemas.microsoft.com/2011/01/fabric"
                 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <ServiceTypes>
    <!-- This is the name of your ServiceType. 
         This name must match the string used in RegisterServiceType call in Program.cs. -->
    <StatelessServiceType ServiceTypeName="WebType" />
  </ServiceTypes>

  <!-- Code package is your service executable. -->
  <CodePackage Name="Code" Version="1.0.0">
    <EntryPoint>
      <ExeHost>
        <Program>removed...........Accounts.Web.exe</Program>
        <WorkingFolder>CodePackage</WorkingFolder>
      </ExeHost>
    </EntryPoint>
  </CodePackage>

  <!-- Config package is the contents of the Config directoy under PackageRoot that contains an 
       independently-updateable and versioned set of custom configuration settings for your service. -->
  <ConfigPackage Name="Config" Version="1.0.0" />

  <Resources>
    <Endpoints>
      <!-- This endpoint is used by the communication listener to obtain the port on which to 
           listen. Please note that if your service is partitioned, this port is shared with 
           replicas of different partitions that are placed in your code. -->
      <Endpoint Protocol="http" Name="ServiceEndpoint" Type="Input" />
    </Endpoints>
  </Resources>
</ServiceManifest>

And my controller:

    [HttpGet]
    [Route("accounts", Name = "GetAccounts")]
    public async Task<IHttpActionResult> GetAccounts(){//dostuff}

How do I find out what endpoint I should be requesting in order to trigger GetAccounts?

Service Fabric provides a built-in reverse proxy . It is enabled by default in your local development cluster. A reverse proxy allows you to use dynamic ports (as shown in your .gif). When using a reverse proxy you can call your service with the port number of your reverse proxy (19081 by default). The address format in your use case, a stateless service with a singleton partition, is: protocol://clusterAddress:reverseProxyPort/applicationName/serviceName

In your example the service would be called with: http://clusterAddress:19081/Service/Web/api/controller/accounts/GetAccounts

I suppose this Web Api is exposed to the outside world? The stateless service you are using to host it in has dynamic port enabled. For external facing services it is best to give it a fixed port.

In the service manifest file you can add the port number in the endpoint definition:

<Endpoint Protocol="http" Name="ServiceEndpoint" Type="Input" Port="80">

See See this link for more info.

Once you have the portnumber you can access the web api at http://localhost:80/api/[controller]/accounts

You can then lookup the actual port number in the explorer, whether you are using dynamic ports or not.

To see the endpoint port number browse to a node beneath your service like this: 在此处输入图像描述

(See the endpoint at the right side?)

Note that if the endpoint contains the ip of a specific node, you need the ip or FQDN of the cluster. But for now it seems ok since you are using localhost.

In Service Fabric, a service runs somewhere in a Service Fabric cluster, typically distributed across multiple VMs. It can be moved from one place to another, either by the service owner, or automatically by Service Fabric. Services are not statically tied to a particular machine or address.

A Service Fabric application is generally composed of many different services, where each service performs a specialized task. These services may communicate with each other to form a complete function, such as rendering different parts of a web application. There are also client applications that connect to and communicate with services.

For example, in order to accept external traffic on port 80, the following things must be configured: Write a service that listens on port 80. Configure port 80 in the service's ServiceManifest.xml and open a listener in the service, for example, a self-hosted web server.

XML

<Resources>
    <Endpoints>
        <Endpoint Name="WebEndpoint" Protocol="http" Port="80" />
    </Endpoints>
</Resources>

C#

class HttpCommunicationListener : ICommunicationListener
    {
        ...

        public Task<string> OpenAsync(CancellationToken cancellationToken)
        {
            EndpointResourceDescription endpoint =
                serviceContext.CodePackageActivationContext.GetEndpoint("WebEndpoint");

            string uriPrefix = $"{endpoint.Protocol}://+:{endpoint.Port}/myapp/";

            this.httpListener = new HttpListener();
            this.httpListener.Prefixes.Add(uriPrefix);
            this.httpListener.Start();

            string publishUri = uriPrefix.Replace("+", FabricRuntime.GetNodeContext().IPAddressOrFQDN);
            return Task.FromResult(publishUri);
        }

        ...
    }

class WebService : StatelessService
    {
        ...

        protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
        {
            return new[] { new ServiceInstanceListener(context => new HttpCommunicationListener(context))};
        }

        ...
    }

This document discusses how to set up communication with and between services in Service Fabric:

Connect and communicate with services in Service Fabric

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM