<CharlieDigital/> Programming, Politics, and uhh…pineapples

17Apr/09Off

WCF Load Balancing : An End To End Example For NetTcpBinding

Posted by Charles Chen

Recently, I worked on prototyping WCF load balancing for our product, FirstPoint. I built a simple example to test the configuration and behavior of load balancing. Since there aren't many end-to-end examples of WCF load balancing on the web, I'm hoping this will be useful (since the Microsoft documentation on this is basically non-existent...well, for NetTcpBindings at least).

I will assume that you are already familiar with network load balancing and configuring the NLB on Windows Server 2003.

Here's a screenshot of how I've configured my network load balancer:

You'll notice that I've configured a specific port range for my service. Also, take note of the cluster address: 192.168.1.220. The two servers that make up the cluster are FPDEV1 (192.168.1.222) and FPDEV2 (192.168.1.223).

I've defined a simple service interface which simply echoes the message with a server name:

using System.ServiceModel;
 

namespace WcfLoadBalancingSample.Server.Contracts {
    /// <summary>
    /// A simple service contract definition which defines an echo operation.
    /// </summary>
    [ServiceContract(SessionMode = SessionMode.Allowed)]
    public interface IEchoService {

        /// <summary>
        /// Echoes the specified message.
        /// </summary>
        /// <param name="message">The message.</param>
        /// <returns>The input message with a server identifier attached.</returns>
        [OperationContract]
        string Echo(string message);
    }
}

And here is the implementation:

using System;
using WcfLoadBalancingSample.Server.Contracts;
 

namespace WcfLoadBalancingSample.Server.Services {
    /// <summary>
    /// Implements the <c>IEchoService</c>.
    /// </summary>
    public class EchoService : IEchoService {
        #region IEchoService Members

        /// <summary>
        /// Echoes the specified message.
        /// </summary>
        /// <param name="message">The message.</param>
        /// <returns>
        /// The input message with a server identifier attached.
        /// </returns>
        public string Echo(string message) {
            return string.Format("[{0}] {1}", Environment.MachineName, message);
        }

        #endregion
    }
}  

As you can see, I've simply prepended the machine name to each response so that we can track which server we are connecting to. Here is the main program which hosts the service:

using System;
using System.ServiceModel;
using WcfLoadBalancingSample.Server.Services;
 

namespace WcfLoadBalancingSample.Server {
    internal class Program {
        private static void Main(string[] args) {
            var program = new Program();
            program.Run();
        }

        public void Run() {           
            ServiceHost serviceHost = null;

            try {
                serviceHost = new ServiceHost(typeof (EchoService));
                serviceHost.Open();

                Console.Out.WriteLine("Service ready.");
                Console.Out.WriteLine("Press any key to terminate.");
                Console.Out.WriteLine("============================");
                Console.ReadKey();
            }
            catch (Exception exception) {
                Console.Out.WriteLine(exception);
                Console.ReadKey();
            }
            finally {
                if (serviceHost != null) {
                    serviceHost.Abort();
                }
            }
        }
    }
}  

This should be deployed on your each of your two (or more) servers in your cluster. The magic comes next in the configuration file:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.serviceModel>
        <services>
            <service name="WcfLoadBalancingSample.Server.Services.EchoService"
                     behaviorConfiguration="WcfLoadBalancingSample.Server.Services.EchoServiceBehavior">
                <!-- Service Endpoints -->
                <!--///
                    The configured endpoint address is the IP address of the load balanced
                    cluster.  The port number has been mapped to the cluster.
                ///-->
                <endpoint
                    address ="net.tcp://192.168.1.220:12345/lb/EchoService"
                    binding="customBinding"
                    bindingConfiguration="DefaultCustomBinding"
                    contract="WcfLoadBalancingSample.Server.Contracts.IEchoService">
                </endpoint>
            </service>
        </services>
        <bindings>
            <!--///
                A simple custom binding.  Note the leaseTimeout setting.
                This is referenced in the SDK documentation, but not described
                in any way as to how you're supposed to configure it.
            ///-->
            <customBinding>
                <binding name="DefaultCustomBinding">
                    <windowsStreamSecurity protectionLevel="None"/>
                    <binaryMessageEncoding/>
                    <tcpTransport>
                        <connectionPoolSettings leaseTimeout="00:00:01"/>
                    </tcpTransport>
                </binding>
            </customBinding>
        </bindings>
        <behaviors>
            <serviceBehaviors>
                <behavior name="WcfLoadBalancingSample.Server.Services.EchoServiceBehavior">
                    <serviceMetadata httpGetEnabled="True"
                                     httpGetUrl="http://192.168.1.220/lb/EchoService/MEX"/>
                    <serviceDebug includeExceptionDetailInFaults="True" />
                </behavior>
            </serviceBehaviors>
        </behaviors>
    </system.serviceModel>
</configuration>

The most important part of this configuration file is the setting for the lease timeout. The SDK documentation references this setting, but does not go into detail on how it's configured. Note that it seems that you can only set the least timeout value in configuration using a custom binding.

There is one particularly important thing to note here: I've set the timeout to 1 second for demonstration purposes only. The SDK documentation mentions that this value should be set to 30 seconds. As we'll see later, I have the client creating a new connection every 2.5 seconds (on purpose so we can test connectivity). What I found was that with the default setting (5 minutes, according to the SDK), if you initially connect to server A and server A goes down, it will not automatically connect to server B. I assume this is because of the lease timeout value (it throws an exception).

Also note that the endpoint is configured using the IP address of the node balancing cluster and not the individual servers.

The client side of it is pretty straight forward as well:

using System;
using System.Runtime.Remoting.Messaging;
using System.Threading;
using WcfLoadBalancingSample.Client.LoadBalancedService;
 

namespace WcfLoadBalancingSample.Client {
    public delegate void EchoDelegate();

    public class EchoEventArgs : EventArgs {
        public EchoEventArgs(string message) {
            Message = message;
        }

        public string Message { get; set; }
    }

    internal class Program {
        private static void Main(string[] args) {
            var program = new Program();
            program.Run();
        }

        public void Run() {
            // Start the server.
            Console.Out.WriteLine("Starting client...(press any key to exit)");

            // Start second thread to ping the server.
            EchoDelegate echoDelegate = EchoAsync;
            echoDelegate.BeginInvoke(EchoAsycCompleted, null);

            Console.Read();
        }

        /// <summary>
        /// Asynchronous execution of the call to the server.
        /// </summary>
        private void EchoAsync() {
            try {
                int count = 0;
                while (true) {
                    using (var serviceClient = new EchoServiceClient()) {
                        // Call the echo service.
                        string result = serviceClient.Echo(
                            count.ToString());

                        Console.Out.WriteLine(result);

                        count++;                        
                    }

                    Thread.Sleep(2500);
                }
            }
            catch (Exception exception) {
                Console.Out.WriteLine(exception);
            }
        }

        /// <summary>
        /// Handles the completion of the thread.
        /// </summary>
        /// <param name="result">The result.</param>
        private void EchoAsycCompleted(IAsyncResult result) {
            var r = (AsyncResult) result;
            var e = (EchoDelegate) r.AsyncDelegate;

            e.EndInvoke(r);
        }
    }
}

The only thing to note is that I used a delegate to spin off a second thread to make the call to the server. Adding a reference to the server generates the following configuration file:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.serviceModel>
        <bindings>
            <netTcpBinding>
                <binding name="CustomBinding_IEchoService">
                    <security mode="Transport">
                        <transport clientCredentialType="Windows" 
                                   protectionLevel="None" />
                        <message clientCredentialType="Windows" />
                    </security>
                </binding>
            </netTcpBinding>
        </bindings>
        <client>
            <endpoint 
                address="net.tcp://192.168.1.220:12345/lb/EchoService"
                binding="netTcpBinding" 
                bindingConfiguration="CustomBinding_IEchoService"
                contract="LoadBalancedService.IEchoService" 
                name="CustomBinding_IEchoService">
                <identity>
                    <userPrincipalName value="Administrator@fpdev.com" />
                    <servicePrincipalName value="" />
                    <dns value="192.168.1.220" />
                </identity>
            </endpoint>
        </client>
    </system.serviceModel>
</configuration>

Note that on this side, the binding is generated as a netTcpBinding.

And that's it! Deploy the service to your clustered servers and start the services and then start the client. If your cluster has a bias towards one server, you will see that the messages will come from that server. To test that it actually is load balancing, simply stop the service on that server and you should see that the output will be coming from the other server. Here's an example:

You can see that after I stop the service on FPDEV1 at the third echo message, it flips over to FPDEV2! Awesome!

Here's the full project (VS2008): WcfLoadBalancingSample.zip (16.89 KB)

Filed under: .Net, WCF 3 Comments
17Apr/09Off

Obama Says No To The Assault Weapons Ban

Posted by Charles Chen

So can we stop the bitter tears for a bit?  Just a little?


http://www.msnbc.msn.com/id/30232095



U.S. president signals he won't seek reinstatement of assault weapons ban


MEXICO CITY - Acknowledging a Mexican drug war that is "sowing chaos in our communities," President Barack Obama signaled Thursday he will not seek the reinstatement of a U.S. assault weapons ban but instead step up enforcement of existing laws against taking such weapons across the border.
Despite a campaign promise to see the lapsed ban renewed, Obama was bowing to the reality that to do so would be unpopular in politically key U.S. states and among Republicans as well as some conservative Democrats.

Filed under: News, Rants No Comments
16Apr/09Off

CharlieDigital’s Guide to “Teabaggin”

Posted by Charles Chen

This recent phenomenon of "teabaggin" (lol) amongst conservatives has been humorous on many fronts.  But it's gotten me thinking: are there people really this stupid?  I mean, that's a lot of stupid.  Some of the signs I've seen are pretty creative (creatively wrong).  Let's address some of them and see what we come up with.



I find this one quite humorous myself, as it shows: 1) a total lack of perspective and 2) it's amazing how easily you can get someone to protest against their own self interest.  If this protester didn't know, the highest marginal tax bracket under Reagan was 50%. Then clearly, Ronald Reagan meant 50% slavery right?  So 39% slavery should be an improvement.  Aside from that, what in the right mind of Vishnu are these people thinking?  Do they have any clue on what slavery was really like?  I mean, wow, get some perspective.  On the second point, Obama has already enacted a tax cut (look at your paycheck and you should see it) for 95% of Americans.  Who are the poor, unlucky 5% that have been excluded?  I'm pretty sure its not this guy holding the sign; instead, they're folks making well into 6 figure territory.



There is great amusement to be found in this picture as well.  "ZERO TAXES"?  I wonder how this old lady thinks the roads she is sitting next to were built?  How were the side walks built?  Who paid for those signals?  Who paid for that sign?  I shudder at the thought of living in a country with zero taxes.  Why?  Because it would be a shithole for all but the super wealthy.  Education and literacy rates would drop dramatically.  Commerce would slowly wither as roads and infrastructure weathered and fell into disrepair.  The old would flood homeless shelters and emergency rooms.  Crime would increase as there would be no publicly funded police...only privately funded militia (no better than paying protection to the mafia).  Zero taxes?  Why not relocate to Somalia instead.


Taxation is a necessary price to pay for living under the protection of the federal government.  It is a necessary price to pay for the services and infrastructure which service us all and enable commerce.  It funds education and improves the quality of life of all Americans (after all, the more children we educate and transform into productive members of society, the better off we are tomorrow).  Paul Begala gets it right:



Happy Patriots' Day. April 15 is the one day a year when our country asks something of us -- or at least the vast majority of us.


For those who wear a military uniform, those who serve the rest of us as policemen and firefighters and teachers and other public servants, every day is patriots' day. They work hard for our country; many risk their lives -- and some lose their lives.


But for the rest of us, the civilian majority, our government asks very little. Except for April 15. On this day, our government asks that we pay our fair share of taxes to keep our beloved country strong and safe.


He's right: aside from paying my taxes, the government does ask very little of me.  I'm neither forced to serve in our armed forces, forced to do any work on behalf of the government, nor am I oppressed.  In exchange for 20% of my income (my effective federal tax rate this year), I get to live in a relatively stable and safe society with some of the greatest degrees of freedoms of any first world country.


Of course, let's not forget that silly lady on the left either.  Excuse me miss, but you can't have defense without taxes (lol).



This one is great, too.  On the contrary, Obama's whole platform is aimed a middle class gains.  His tax policy, cuts for middle class Americans while reverting to the top marginal tax rate under Clinton (bear in mind, this is still lower than the top marginal tax rate under Reagan), seems like it's designed specifically to help working, white collar, middle class Americans.  So either this guy makes more than $200,000 or he's just stupid.  I think it's the latter.



lol. Where do I begin with this one?  I mean, what does Christianity have anything to do with this at all?  First of all, we're not a Christian nation.  Second of all, I love the guy's shirt: "Stupidity Offsets for Sale".  I think he needs to buy crate loads of them.



lol.  Still on this ACORN thing?



This one is particularly funny as Wall Street is the epitome of unfettered capitalism. Somehow, our government has been hijacked by both capitalists and socialists...AT THE SAME TIME! Amusing.



Oh, and apparently facists, too. (I rather think that this quote applies more to these teabaggin' protestors than it does to the rest of the public.)  Also: quoting Hitler on your t-shirt?  Always classy.



This one is ironic because this person has conveniently forgotten that we had this thing called an "election" on November 4, 2008.  Yeah, you know, this thing where millions of people from all across the country come out and select the people whom they choose to represent their interests.  Oh yeah, that's right, your guy lost...silly me.


But more importantly, this sign is patently ridiculous simply because it ignores the reality of how government works.  As if "THE GOV'NT" is some entity of the elite, assembled with individuals from some higher class seeking to oppress the people.  Well, I've got news for you: "THE GOV'NT" is of the people, by the people, and for the people.


I think what gets me even more are the cries of socialism, communism, and facism.  Do these people even know what these terms mean?  I mean, do they? I think these people need to have a talk with this guy:



Of course, another fun game to play with all of these tea party pictures is "Spot the Minority".  There's just something really weird that I can't put my finger on...almost every picture of these crowds is 100% white.  What's the deal with that?


What's that you say? You have more questions. Well, let's hear them.


Where's MY bailout?


Well, that's simple: you're already getting tax cut from the Obama administration.  Aside from this, check out his mortgage rescue plan.



NEW YORK (CNNMoney.com) -- The Obama administration's loan modification program is finally underway.


The Treasury Department announced Wednesday the first six participants to sign up for President Obama's plan. They include three of the nation's largest banks: JPMorgan Chase (JPM, Fortune 500), which will get up to $3.6 billion in subsidy and incentive payments; Wells Fargo (WFC, Fortune 500), $2.9 billion; and Citigroup (C, Fortune 500), $2 billion. The others are GMAC Mortgage, $633 million; Saxon Mortgage Services, $407 million; and Select Portfolio Servicing, $376 million.


Additional loan servicers will be added to the list over time, a Treasury spokesman said.


Billed as helping up to 9 million borrowers stay in their homes, the two-part plan calls for servicers to reduce monthly payments to no more than 31% of eligible borrowers' pre-tax income or to refinance eligible mortgages even if the homeowner has little or no equity. The government is allocating $75 billion to subsidize part of payment reduction, as well as provide thousands of dollars in incentives for servicers and borrowers to participate.


This is a huge bailout of the American Dream; it aims to keep homeowners (or should I say mortgage payers?) in their homes by modifying mortgages to the realities of the current market and economic environment.  Taking advantage of historically low mortgage rates, I've already refinanced and ended up saving some $400/month.  So there's your bailout.


But the national debt is skyrocketing!  Think of the children!


There are a few points to make here.  First, I must direct your attention to the Treasury Department's helpful website on this topic.  Please browse through every date range on the site.  Notice a pattern?  That's right, every generation since 1791 has left a debt. Every.  Single.  One. 


Of course, one of the fun facts is looking at the national debt between 9/30/2001 and 9/30/2008, roughly President Bush's two terms.  Let's see, it started at 5.8 trillion, and, well, looky here, ended at 10 trillion.  Whoa, I thought, like, Republicans were supposed to be all conservative-like.  Guess that's just a myth!  Let's look at another time period.  How about Reagan's presidency, the period between 9/30/1982 and 9/30/1988.  Let's see, it started at 1.1 trillion and it ended at 2.6 trillion. Will you look at that?  Ronald Reagan more than doubled the national debt. 


But let's move on from the numbers; I'm sure you protested when Bush and Reagan were in charge, too, right? 


There's another point to be made that can't be made with numbers and that's the fact that not all debt is created equally.  There are multiple parts to this.  The first is the interest rate on debt.  It has never been cheaper to create debt than it is right now since intrest rates are so depressed. Secondly, consider this question: is borrowing $40,000 to spend on a sports car the same as spending $40,000  on a graduate degree?  If your jobless sibling came to you tomorrow and asked to borrow $10,000 to buy a new motorcycle, would you react the same way as if he came and borrowed $10,000 to go back to school?


Of course there is a big difference.  One is a depreciating asset from which you are not likely to ever see any returns on and the other, an education, has a great potential to generate a high return on investment.  Likewise, spending on education, healthcare, infrastructure, basic scientific research, and developing energy solutions is an investment that is likely to yield a high return on investment.  It is spending that increases our overall capacity for commerce.  You need an educated population for high paying jobs, you need working roads to facilitate commerce, you need a new energy grid for efficiency (cost savings) and security, you need to fund basic research to drive innovation, you need to fix healthcare because it is one of the biggest factors depressing wages in the US.


If there is something that we should spend our tax dollars on, it's things like these, things that willl someday help generate commerce and thus employment and tax revenues.  And of course, keep in mind, our kids will utilize these same roads and infrastructure decades down the line.  The will go to these new schools.  They will be the beneficiaries of increased grants for scientific research.  It is precisely the next generation that will benefit the most from our investment today.

Filed under: News, Rants 1 Comment
3Apr/09Off

Why Do You Play?

Posted by Charles Chen




One of my favorite all time sports quotes:



You PLAY to win the game. -- Herm Edwards


It's so simple and so obvious, and yet, so easy to lose sight of.  Herm is right, but it doesn't just apply to sports, it applies to product development as well.  You play to win, otherwise, get off the team...you're just dead weight taking up budget.


One of my pet peeves is lack of passion.  It seems that many folks just don't get it; they're not playing to win.  They're playing for their next paycheck.


In product development, like sports, sometimes, you have to take risks.  Get too conservative, and you may see your lead evaporate.  Like sports, you play to win...always.  No team is perfect and no product is perfect, but that simply means that you play to your strengths.  In product development, this means selling to your strengths.  There's no such thing as a perfect team (as the Patriots proved) and there is no such thing as a perfect product. 


The question for product managers and coaches is how you can work with what you have and maximize your resources and work around your weaknesses.  Fail to do this, and you have failed your team as a leader.  If your running game is weak, don't force your team to rely on running plays as a primary option.  If your corners are weak, don't force them to have to cover deep.  If your defense is weak, run your offense to maximize posession time.  Work to the strengths of your team or your product; don't try to play a style that doesn't fit your personnel (analogously, don't use methodologies that don't fit your resources).


You PLAY to win the game.  So simple and yet so easy to get into a mindset where you play for that paycheck instead of playing to win.

Filed under: DevLife, Rants No Comments