Base microservice constructor

We now need to create our BaseMicroService constructor. Inside our constructor, we will create and configure our Heartbeat timer to trigger every 60 seconds, and our worker ID:

public BaseMicroService()
{
double interval = 60000;
_timer = new Timer(interval);
Assumes.True(_timer != null, "_timer is null");
_timer.Elapsed += OnTick;
_timer.AutoReset = true;
_workerId = Guid.NewGuid().ToString();
_name = nameof(T);
}

The timer will trigger an event every minute, and that event will be our indication that we need to send our Heartbeat message to let everyone know that we are alive and operational. If our service has degraded such, an indication of our circuit breaker pattern coming up, we could send an Unhealthy message back saying we are alive but impaired. This Heartbeat is aside from what any other microservice may do in regard to health monitoring. Since all microservices will inherit from this base class, the functionality in each method may or may not meet the needs of any one particular situation, so feel free to enhance as required.

I have highlighted the main portion of this code that I want you to pay attention to. I'll be harping about DateTime for many chapters to come, so let's just say it again. Consistent timing through the microservice ecosystem is of utmost importance. Notice that the highlighted code is calling the SystemClock of Noda Time, and getting us a time relative to our local time zone on the machine we are running from. I use Noda Time religiously, and every major and minor enterprise ecosystem I have built has Noda Time as part of its foundation.

Let's look at our OnTick event method:

protected virtual void OnTick([NotNull] object sender, [NotNull] ElapsedEventArgs e)
{
Console.WriteLine(string.Intern("Heartbeat"));
Requires.NotNull<ILog>(_log, string.Intern("log is null"));
_log?.Debug(_name + " (" + _workerId.ToString() + string.Intern("): ") +
SystemClock.Instance.GetCurrentInstant().ToDateTimeUtc().ToLocalTime().ToLongTimeString() + string.Intern(": Heartbeat"));
HealthStatusMessage h = new HealthStatusMessage
{
ID = _workerId,
memoryUsed = Environment.WorkingSet,
CPU = Convert.ToDouble(getCPUCounter()),
date = SystemClock.Instance.GetCurrentInstant().ToDateTimeUtc().ToLocalTime(),
serviceName = Name,
message = "OK",
status = (int)MSStatus.Healthy
};
Bus.Publish(h, "HealthStatus");
}
}

As you can see, we create a HealthStatus message and then publish it for any consumer out there interested in it.

Now, one more time, so we both know we got this. We do not use DateTime. Now (highlighted areas) to keep track of our time, we use the SystemClock of Noda Time and get the current instant. From there we convert that to a UTC DateTime, and then to a local time. As we mentioned, this ensures that every microservice is using the same reference point for the start of time. With the amount of logging we are doing, we really don't want to be relying on the system clocks of individual machines to all be in sync. Once you encounter daylight savings time with an entire ecosystem built and running with Noda Time, you will thank me heavily for this one tip. No more losing messages or doubling them up (more on that in the Appendix ABest Practices section at the end of the book).

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset