Avrete bisogno in qualche modo di partizionare il vostro servizio.
Ci sono diversi opzioni, ma i due che si allinea bene qui (e anche con il SO domanda si è collegato sono):
dispone di un'applicazione SF dove ogni inquilino riceve un'istanza del vostro servizio. Sarà quindi necessario disporre di un servizio condiviso di fronte per indirizzare le richieste al servizio corretto. Dovrebbe assomigliare a qualcosa di simile a questo.
MyAwesomeApp
SharedStatelessApi <- External API points here
MyTenantService_Tenant1 <- ServiceType: MyTenantService
MyTenantService_Tenant2 <- ServiceType: MyTenantService
...
L'altra soluzione è quella di avere una (o più) di servizi applicativi tessuto al locatario, e apparirebbe qualcosa sulla falsariga di:
MySharedApp
SharedStatelessApi <- External API points here
Tenant1 <- ApplicationType: MyTenantApp
MyTenantService <- ServiceType: MyTenantService
Tenant2 <- ApplicationType: MyTenantApp
MyTenantService <- ServiceType: MyTenantService
E 'lo stesso concetto come il primo esempio, ma la partizione viene eseguita su una leva più alta.
Personalmente, preferisco il secondo caso. Sembra più giusto. In entrambi i casi, dovrai creare manualmente i servizi/l'applicazione quando un nuovo cliente si iscrive o lo fa in codice. Se vuoi farlo in codice, dovresti dare un'occhiata a FabricClient. Se hai bisogno di un esempio, fammi sapere.
Inoltre, come si può vedere, è necessario disporre di un endpoint pubblico condiviso e in tale endpoint indirizzare la richiesta al servizio corretto in base a qualcosa (intestazione, token di autenticazione, uri, qualsiasi cosa sia in linea con l'app).
Esempio di utilizzo FabricClient per creare un servizio:
In primo luogo è necessario un FabricClient.Per un cluster non garantito (cluster dev locale), il seguente è sufficiente:
var fabricClient = new FabricClient("localhost:19000");
Quando è stato distribuito a un cluster protetta (per esempio in Azure), è necessario autenticare il FabricClient, in questo modo:
var creds = new X509Credentials
{
FindType = X509FindType.FindByThumbprint,
FindValue = clientCertThumbprint,
RemoteCertThumbprints = {clientCertThumbprint},
StoreLocation = StoreLocation.LocalMachine,
StoreName = "My"
};
var clusterEndpoint = "CLUSTERNAME.LOCATION.cloudapp.azure.com:19000"
// or whatever your cluster endpoint is
var fabricClient = new FabricClient(creds, clusterEndpoint);
Poi, quando si ha un FabricClient, è possibile creare un servizio senza stato come questo:
var statelessDescriptor = new StatelessServiceDescription
{
ApplicationName = new Uri("fabric:/MYAPP"),
InstanceCount = 1, // How many instances.
PartitionSchemeDescription = new SingletonPartitionSchemeDescription(),
ServiceName = new Uri("fabric:/MYAPP/TenantA"),
ServiceTypeName = "YourServiceTypeName",
InitializationData = DATA_TO_PASS_TO_SERVICE_BYTE[] // Only if needed.
};
await _client.ServiceManager.CreateServiceAsync(statelessDescriptor)
Se avete passato tutti i dati nella prop "InitializationData", sarà dispo lable in servizio come ServiceInitializationParameters.InitializationData
Grazie per il tempo dedicato a fornire un feedback. Forse ho bisogno di fare ulteriori ricerche su FabricClient e sulla soluzione che stai proponendo di capire se è parte della risposta che sto cercando. Tieni presente che il nostro servizio multi-tenant è in realtà solo un processo per l'apertura di una connessione HTTP a polling lungo e lo streaming di dati dai clienti, nessun endpoint pubblico. Il problema è che abbiamo bisogno di eseguire più istanze, vale la pena di questi tenant su ciascun nodo poiché sono molto leggeri e non ha senso utilizzarne uno per nodo, il che non sfrutterebbe completamente la potenza del nodo. – cwiederspan
Ho riformulato parte della mia domanda per chiarire meglio il carico di lavoro sottostante nella speranza che ciò renderà il problema meglio definito. Fondamentalmente cercando di costruire un esercito di connessioni HTTP a lungo polling che possono essere eseguite per lunghi periodi di tempo e failover, bilanciamento del carico, ecc. Usando Service Fabric. – cwiederspan
Ok, supponendo che tu abbia un modo interno di attivare l'avvio della connessione, il mio post qui sopra rimane valido. Ad esempio, invece di attivare una connessione al Tenant A, ruoti un'istanza del tuo servizio stateless per il Tenant A e quel servizio apre la sua connessione nel suo metodo RunAsync. Ha senso ? – anderso