Page 34 - MSDN Magazine, April 2017
P. 34
variables. The SQL Server image uses these values to confirm that the license agreement has been accepted, and to set the password for the sa user.
To run a container, Docker needs to have a copy of the image locally. Distribution is built into the Docker platform, so if you don’t have the SQL Server Express image locally when you run this command, Docker will download it from the Hub. There are more than half a million images on Docker Hub, which have been downloaded more than 9 billion times. Docker started in the Linux world and the majority of those images are Linux apps, but there are a growing number of high-quality Windows apps you can down- load and drop straight into your solution.
SQL Server is running in a Docker con- tainer now, and my Web app uses sql-server as the hostname in the connection string so it will connect to the database running in Docker. I can start the WebForms applica- tion in the background and publish port 80 to make the Web site accessible:
docker run --detach ` --publish 80:80 ` sixeyed/msdn-web-app:v1
If an external machine sends a request on port 80 to my host, Docker receives the request and transparently forwards it to the ASP.NET app running in the container. If I’m working on the host, I need to use “docker inspect” to get the container’s IP address and browse to the container to see the site, which is a simple product launch microsite. You can see the data capture page from the site running in Docker in Figure 1.
Run “docker ps” and you’ll see a list of all running containers. One is a database and one is a Web application, but you manage them both in the same way—“docker top” shows you the processes running in the container; “docker logs” shows you the log output from the app; and “docker inspect” shows you which ports are open and a host of other information about the container. Consistency is a major benefit of the Docker platform. Apps are packaged, distributed and managed in the same way, no matter what tech- nology they use.
GET
Figure 2 The Modernized Application Has Many Working Parts 22 msdn magazine
Splitting Features from
Monolithic Apps
Now that the application is running on a modern platform, I can start to modernize the application itself. Breaking a monolithic application down into smaller services can be a significant project of work, but you can take a more targeted approach by working on key features, such as those that change regu- larly, so you can deploy updates to a changed feature without regression testing the whole application. Features with non-functional requirements that can benefit from a different design without needing a full re-architecture of the app can also be a good choice.
I’m going to start here by fixing a perfor- mance issue. In the existing code, the application makes a synchronous connection to the data- base to save the user’s data. That approach doesn’t scale well—lots of concurrent users would make a bottleneck of SQL Server. Asyn- chronous communication with a message queue is a much more scalable design. For this feature, I can publish an event from the Web app to a
message queue and move the data-persistence code into a new com- ponent that handles that event message.
Consistency is a major benefit of Docker. Apps are packaged, distributed and managed in the same way, no matter what technology they use.
This design does scale well. If I have a spike of traffic to the Web site I can run more containers on more hosts to cope with the incoming requests. Event messages will be held in the queue until the message handler consumes them. For features that don’t have a specific SLA, you can have one message handler running in a single container and rely on the guarantees of the message queue that all the events will get handled eventually. For SLA-driven features you can scale out the persistence layer by running more message-handler containers.
The source code that accompanies this article has folders for version 1, version 2 and version 3 of the application. In version 2, the SignUp.aspx page publishes an event when the user submits the details form:
Figure 1 A Signup Page for a Site Running in Docker
var eventMessage = new ProspectSignedUpEvent {
Prospect = prospect,
SignedUpAt = DateTime.UtcNow };
MessageQueue.Publish(eventMessage);
Containers