Hi,
Hope you all are fine. I was facing a issue with Service Fabric that some of you might have faced as well. Right now, the project that I'm working on is structured so that all the micro-services are in there own solutions. Working with Service Fabric, that doesn't seem possible since all AppTypes should be in the same solution as the App.
Any ideas if this can be done? I'm wanting this because if all the projects are in a single solution, that means more loading time for the solution, more build time, larger repo download and etc.
Looking forward to your help.
I am dealing with similar scenario by creating multiple separate Service Fabric Applications and deploying them separately. This solution works very well for me. Do you really need to have a single Service Fabric Application?
That is what I'm doing for now as well but looking at how Service Fabric is designed, it makes more sense to have different AppTypes under a single App instead of using App as AppTypes :-)
I don't know if I understand your situation. When you say that that all the micro services are in their own solutions, you mean as they are structured in VS, right? That's fine. You are free to combine the resulting service packages that you end up with into a single application type when you actually go do a deployment. This would normally be done as a part of your CI/CD pipeline - all the different service packages get built as a part of building those solutions, and then are combined into the actual application type/package. This is why the application package is mainly just a bunch of references to the underlying service packages (and types). That way you have the application type as a combination of the service types that makes sense to you, rather than arbitrarily having 1 app type per service type.
@masnider This way that your described with CI/CD... is there some documentation on it? Anything that you can reference me to so that I can have a better look at it and see if it solves my problem.
Right now, my solutions are:
ContextA Solution -> ContextA.Library, ContextA.Models, ContextA.Api
ContextB Solution -> ContextB.Library, ContextB.Models, ContextB.Api
When going with Service Fabric, I would not want it to be:
ContextA Solution -> ContextA.Library, ContextA.Models, ContextA.SFApp, ContextA.SFAppType
ContextB Solution -> ContextB.Library, ContextB.Models, ContextB.SFApp, ContextB.SFAppType
I'd rather have it as:
SF Solution -> ContextA.Library, ContextA.Models, ContextA.SFAppType + ContextB.Library, ContextB.Models, ContextB.SFApp, ContextB.SFAppType + SFApp
But the problem with this is that I don't want all that in a single solution. Different teams will be working on Context A and B so I'd want them to be different solutions but with the same SFApp at the root of all the other Context specific AppTypes.
Hope I made myself clear. :-)
@MikkelHegn do we have anything published here yet? Alternatively can we find some resources to help these folks out?
Here's the basics: https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-set-up-continuous-integration
@masnider I also updated my comment if you can have another look at it to maybe have a clearer picture.
@haseeb-ahmed-tkxel The general recommendation, and what works well for many customers, it to have your context scope to one Application Type and one VS Solution. Application Type is your unit of deployment and application instances the unit of upgrade, there is little you can do in terms of application lifecycle management, which falls outside the scope of an Application Type, hence the recommendation.
@masnider recommends that you set-up your build pipeline to merge the two application packages that are output of the two solutions. We have done some experimentation around this, but have no collateral to share. The basics of the concept is to merge the app manifests and the two package structures into a valid Service Fabric application package. You will however end up in situation where you need to figure out how to get compatible versions of dependent applications onto your local dev cluster (same concept as above can apply, by extending the Deploy-FabricApplication.ps1 script, which is used on debug / local deployment).
Any update on this?
@gramidt What kind of update are you looking for? We haven't gone further with the experimentation I've mentioned.
@MikkelHegn Was hoping to hear that the experimentation led to a feature being developed to help solve this common issue. It still seems weird to me that this isn't a first class citizen in Service Fabric, since a major benefit of a micro-service approach is to allow your teams to work in a more independent fashion without stepping on each others toes. For example, in many docker environments I've worked on, we had a separate repository for each service, then had a single repository with the docker-compose file and use git submodules to pull in all of the services when developing locally. I have no issue writing a script to do this, but just feel that there must be others feeling this way too.
@MikkelHegn Could you outline a scenario how you would support Application A and Application B both using a version of the same ServiceType, without using 1 single solution due to multiple teams working on A, B and the ServiceType. We are currently working on a platform where there will be applications that will reuse certains ServiceTypes and we are unsure on how to reference the same ServiceType (or rather a specific version of a ServiceType) in multiple ApplicationTypes without having 1 big solution file.
@gramidt How would that feature look like? Is it a Visual Studio feature? If so, what's the relationship between solutions, application (projects), services (projects) and repositories in that setup?
Today a VS solution maps to one repository, and can have multiple applications and services (projects) that are tied together. Is your ask to be able to pull in services (projects) from other
repositories as source or just binaries?
The comparison with compose I understand, but there is a difference in the sense that compose is an after-the-fact thing (you don't need it to run containers, as it simply creates one instance of a definition), whereas an Application manifest is always needed in Service Fabric, to support the type based deployment.
Sorry for all the questions, but the multitude of how you could set this up are many, which is part of the reason we are hesitant to create features that support some of these.
One of my colleagues created a project for importing service binaries via NuGet, which enables you to share services across solutions in a binary format. Take a look here: https://www.nuget.org/packages/SFNuGet and http://haishibai.blogspot.com.tr/2016/08/sfnuget-031-release-multi-service.html
@bartbovendeerdt I guess for your question the scenario would be SFNuget.
Another point - remember that services in applications are still just types. VS puts you on a path where all service types are created as default services on application instance creation. You can control this and you can have application types with service types that are simply not instantiated upon application creation.
+1 to this issue. I raised a similar one a while back: https://github.com/Azure-Samples/service-fabric-dotnet-web-reference-app/issues/30
I think the missing piece here is some well documented guidance. A sample solution would be ideal, but even a blog post would be helpful, at the least to clear up some confusion on what I believe is a pretty common situation.
Also, if you do some googling on microservices in .net, especially comparing service fabric to say azure container services, you'll run across people having the same issue (or again, confusion?)
To me, this issue is the main reason why I'm looking at Azure Container Services for my .NET microservices, which is a shame, because I totally dig what the Service Fabric platform offers.
@RPM1984 - What is it the ACS container orchestrator support in this case? That you can have the services (containers) in individual repos? Can you help me understand.
And yes - we need to find time to write a blog post on this.
@masnider did this for inspiration: https://github.com/masnider/SFAppPackageGenerator - and feel free to contribute to this for your scenarios :-)
@MikkelHegn - although I haven't done much in this area, and am still learning about Containers/Docker, I envisioned a setup in ACS similar to @gramidt 's approach.
That is, a seperate repository on GitHub for each microservice, packaged up via NuGet (or maybe just repo cloned), then a host repository pulling them in and deploying them to the ACS cluster.
The key point here is _autonomous_ teams. They should be able to work on their microservice, then just publish their work to their repository.
CI/CD on the host repository should then kick in and pull all the services in before deploying.
The package looks interesting, but I think we really need a blog post. I believe this topic is way too complicated to just tinker around and ship this kind of thing to production workloads without proper guidance from the experts.
So IOW - please please, blog post. We would be eternally grateful :)
@RPM1984 If I may add to that, it might also be valuable to be able to compose the services as you like actually reusing services built by other teams into your own solution. I believe that "CI/CD on the host repository should then kick in and pull all the services in before deploying." is a step to late, you want to be able to test and run the setup locally. I believe that a great benefit of microservices is in the reuse, but then the development environment should allow for this.
+1 on the blog about sharing services across the scenario described by @gramidt.
I am on investigation if Service Fabric would fill all requirements of my building from the scratch enterprise project and I can't believe you are forcing developers to keep all micro-services across one Visual Studio solution. Moreover you are trying to convince them this is the best approach.
Hear people voice, there are situations where it will not work well. Be flexible, or competitive projects will take your customers.
@jarzynam You're free to use the VS Solution concept the way it fits to your needs. You are not forced to use one solution, these are all compose-able components you put together for your needs. There is a default path in VS, which makes it easy to get started and puts you on a good path. But as with any real production system, you'll have to make decisions down the road on how the structure and workflow fits your setup.
Is there one specific scenario which doesn't work for you?
What's difficult for me to understand about the single VS Solution idea is that it seems to be a monolithic code base, which is kind of the opposite of a microservices architecture.
I've seen in Nuget a package that installs a service into your application, as if it was just another library. See here.
That would be a way of teams working on a service independently, and multiple applications using the published service. You can see the source and Nuget pkg setup here
Does this help with the scenarios people have mentioned above?
I'm in the same boat here. I have a large-ish SF solution that I'd like to split up. I guess I don't fully understand how to take this out-of-the-box VS solution and convert it to multiple solutions that somehow get stitched together through DevOps. We are using DevOps and I see there are build pipelines, but I am really more interested in focusing on my business objectives rather than having to do a deep dive into a bunch of docs, blog posts and examples that don't actually do what I'm trying to do to figure out how to achieve this - what has to be - common scenario. I can't imagine people out there using SF with 50+ projects haven't split up what they're doing. And yet - I can't find anything I can just "grab and go".
I'll do it if I have to, but if anybody has any decent resources surrounding this, I'd love a link.
Without knowing more about your project this sounds more like an architecture issue than an SF issue. You should aim to have multiple applications that can be built and deployed independently.
We're far from that as well. We currently have a solution with 120+ projects in them, but it contains 7 different SF applications. I've split it up into 7 solutions, but everybody uses the slow big one out of laziness.
But during the build and deployment process, the solutions don't even get used. It is the applications that get built and deployed. No solutions involved. We wrote a simple PowerShell script that builds all the projects referenced in the .sfproj file (basically the applications dependencies), and the next build steps then build and package the application itself.
Edit: Here's the script we use. It's hacked together quickly but works for us, not claiming it's the best.
You would need to update the path to the sfproj file to your structure.
param(
$sfproject = "example",
$projectConfiguration = "Release",
$projectRuntime = "win7-x64"
)
[xml]$XmlDocument = Get-Content -Path Applications\$sfproject\$sfproject.sfproj
$projects = $xmlDocument.Project.ItemGroup.ProjectReference.include
foreach ($project in $projects) {
$projectPath = $project -replace "\`.\`.\`\"
"Building: $projectPath"
dotnet restore $projectPath
dotnet build $projectPath --no-restore --configuration $projectConfiguration -r $projectRuntime
}
Our application files are two folders deep from the root (Applications/App1/App1.sfproj) that's why the .\.\ gets removed from the project path, because the build run's from the root.
@tuhland - Thank you for the quick response. This is surely where I have a blind spot. I have a good sense of how I'll be splitting the solution, and I even have a notion of how we might have multiple SF applications, but I don't yet have a level of comfort regarding how SF apps might communicate with each other (if there's some special something required) and I don't have a good handle on what makes an SF app an SF app. Now that I hear you're not even using the solution file but doing it all through scripts, it's changed my focus a bit and I'm beginning to catch on at least with respect to deployment.
Time for a proof-of-concept project or two to see how this all plays out - hoping to stitch it all together in an Azure pipeline.
Thanks again. :)
Most helpful comment
@MikkelHegn Was hoping to hear that the experimentation led to a feature being developed to help solve this common issue. It still seems weird to me that this isn't a first class citizen in Service Fabric, since a major benefit of a micro-service approach is to allow your teams to work in a more independent fashion without stepping on each others toes. For example, in many docker environments I've worked on, we had a separate repository for each service, then had a single repository with the docker-compose file and use git submodules to pull in all of the services when developing locally. I have no issue writing a script to do this, but just feel that there must be others feeling this way too.