Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
malcomio committed May 19, 2024
1 parent 15e94f4 commit de35cdf
Show file tree
Hide file tree
Showing 7 changed files with 14 additions and 14 deletions.
2 changes: 1 addition & 1 deletion _posts/2014-10-06-estimation.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ giving the estimate to have the same definition of done and therefore share the

We've covered this a little bit when saying not to estimate any sub-task at less than half a day, in order to factor in
all the things we forget about when estimating. However, even when you add up all your sub-tasks (or put them into groups for
adding up) we should pad our larger estimates to reflect the inherant uncertainty in the longer term estimate.
adding up) we should pad our larger estimates to reflect the inherent uncertainty in the longer term estimate.

For example, if your estimate is around 3-4 days, call it a week. If it's 3 weeks, then its a month, and so on. Using
larger values of time helps set expectations with your stakeholders and also lets you have contingency for the
Expand Down
6 changes: 3 additions & 3 deletions _posts/2014-10-17-microservices-reality-check.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,16 @@ Despite all this we're persisting. Despite always questioning every decision we
### The Un-Good
And yet its not all #winning. Perhaps it's the lack of balanced opinion in the general chatter that makes me feel the fear I mentioned earlier. Most posts I read are just so sycophantic on the topic, and the world *really* doesn't need another one of them. So, deep breaths, lets dig into that a bit more and present some of the reasons Microservices might not be for you.

1. First up, some honesty. We're finding that despite all the noise in this space very few folks out there are actually _doing_ this, and even fewer doing it in a public manner. We however are. Finding that very few others are with you can be a little scary at times. It means you actually have to *do research* and *make your own decisions* which for most of us in the safe world of Jave Enterprise Development is a new experience. Consequently, we've staked our professional reputations on this, and we've got a lot less to hide behind - we're on the front line of all this challenging of accepted wisdom
1. First up, some honesty. We're finding that despite all the noise in this space very few folks out there are actually _doing_ this, and even fewer doing it in a public manner. We however are. Finding that very few others are with you can be a little scary at times. It means you actually have to *do research* and *make your own decisions* which for most of us in the safe world of Java Enterprise Development is a new experience. Consequently, we've staked our professional reputations on this, and we've got a lot less to hide behind - we're on the front line of all this challenging of accepted wisdom
2. Things won't "just work" when you glue them together; and things which do work might not have the greatest documentation in the world. Many many decks on [slideshare](http://www.slideshare.net/) refer to all the bits you'll need to get up and running in seconds - but there is a impedance mismatch between many of them, and as an early adopter *you* need to fix that. Having said this, the other thing all these projects have in common is a vibrant community. In most things in this area the code is under active development, and so is the documentation. If you want to get involved and help, folks are very pleased to have you along for the ride. That's great, but it does slow things down a bit. It also means you might be [ahead of the curve](https://issues.apache.org/jira/browse/CAMEL-5539) on the major libraries you rely heavily on - for example we plugged Hystrix into Camel for our own Circuit-Breaking purposes before they added a CB of their own in the [latest (2.14.0) version](http://camel.apache.org/camel-2140-release.html). We also chose [CXF](http://cxf.apache.org/) for our REST APIs (when the rest of the world was going [Jersey](https://jersey.java.net/)) because it was a first-class citizen in Camel, only to find the exposure of Camel Routes as REST wasn't at that point incredibly mature. ([Note: It now is](http://camel.apache.org/rest-dsl.html), it's even got [Swagger support](http://camel.apache.org/swagger.html))
3. Related to the point above, you need to remember you might make wrong bets. I already mentioned that we went CXF when the rest of the world seemed to be going Jersey. To be honest that's not hurt us too much - we have what we need. We've also been right in adopting Hystrix, Archaius, and looking at [Eureka](https://github.com/Netflix/eureka), [Ribbon](https://github.com/Netflix/ribbon) and [Zuul](https://github.com/Netflix/zuul) as they have only just been announced as being supported by the new ["Spring Cloud"](https://github.com/spring-cloud/spring-cloud-netflix). It might however have been a mistake to go for [Spring Boot](http://projects.spring.io/spring-boot/) - [Fabric8](http://fabric8.io/) is getting more and more mature by the day, and solves a lot of problems we might face at some point in the future, or have had to code around ourselves (i.e. by building our continuous deployment pipeline with [Jenkins](http://jenkins-ci.org/), [Puppet](http://puppetlabs.com/) and [Capistrano](http://capistranorb.com/))
4. You end up with a _lot_ of moving parts. You're confronting the [Fallacies of Distributed Computing](https://en.wikipedia.org/wiki/Fallacies_of_distributed_computing) head on, and tackling them each in turn, in everything you build. You end up leaning more heavily on tools like [Maven](http://maven.apache.org/) (in our case) or [Gradle](http://www.gradle.org/) (we're evaluating) , and thinking about versioning, and running concurrent versions from the beginning is key. You also end up needing to be able to "boot-up" a component with a load of stubs for all their dependencies so that you can run individual bits on their own
5. This is a new way of thinking. This is INTEGRATION at EVERY LEVEL. In the JavaEE world we never thought of threads because we weren't allowed to. We've found that models like [Scala's Akka](http://akka.io/) are a great mental tool for thinking about these problems, even if we're not using the frameworks, but we had to get there the hard way
6. Following on from the two points above you end up having to make some concessions in order to be able to cope with all this - the biggest one is that you need to embrace immutability (in code and deployables, and environments) and [discard state](http://joesondow.blogspot.com/2012/11/state-is-bug.html). This makes a lot of things easier, and, if you invest the time in proper Continuous Deployment and [elastic scalability enablement](https://en.wikipedia.org/wiki/Elasticity_(cloud_computing))
7. You end up a lot closer to the metal, and the network. We're working with [HTTPClient](http://hc.apache.org/httpcomponents-client-ga/) directly, and are looking at [Protobuf](https://code.google.com/p/protobuf/) / [Thrift](https://thrift.apache.org/) / [Avro](http://avro.apache.org/) for inter-machine comms (Camel lets us do inter-process, intra-machine comms quite nicely). Latency also hits you front and centre. Again, having to deal with this head on is no bad thing, but it's not the usual state of being for a traditional Java developer.
8. Inter-team comms - because you easily gain the benefits of small teams (2-3 dev) working on individual "services" hidden behind a clean API you end up hitting the many patterns finely articulated by Eric Evans in Chapter 14 and beyond of his [Domain Driven Design: Tackling the Complexity in the Heart of Software](http://www.amazon.co.uk/Domain-driven-Design-Tackling-Complexity-Software/dp/0321125215) (perhaps the best part of that fine volume). If you know to expect them then this isn't too bad, but it will happen. This has meant that we've been looking at [Swagger](https://helloreverb.com/developers/swagger) as a nice way of documenting all our APIs, internal and external, to reduce the interruptions when team A needs to consume component from team B
9. You end up with variation. Yes, we've componentized, have created some common components, and had various pull-reqest submissions back to the community accepted, but you still end up with various ways of doing the same thing. Now this isn't always a bad thing, but it means that you need to rely much more on keeping a [clean code(base)](http://www.amazon.co.uk/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882). We review every pull request, with approval being required from >= 2 developers. Typically we aim for these approvers to be from outside the team. We've also instituted an internal RFC mechanism (stolen from [Carl Quinn](https://twitter.com/cquinn) who I believe has used it at both Netflix and Riot Games to manage changes required by the dev teams he leads)
10. You end up flooded by data. Everyone says that you need a lot of monitoring. They're right. Its easy to add too. So easy in fact that we ended up submiting a [pull request](https://github.com/Netflix/Hystrix/pull/281) to Hystrix which allows you to filter what is produced because we were flooding the UDP port of our monitoring servers. We're lucky in that we have a great DevOps team who put all the supporting infrastructure in place for us to take advantage of all this too. But we've needed to become expert in setting up just-the-right-amount Grafana dashboards. Its another skill to learn.
9. You end up with variation. Yes, we've componentized, have created some common components, and had various pull-request submissions back to the community accepted, but you still end up with various ways of doing the same thing. Now this isn't always a bad thing, but it means that you need to rely much more on keeping a [clean code(base)](http://www.amazon.co.uk/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882). We review every pull request, with approval being required from >= 2 developers. Typically we aim for these approvers to be from outside the team. We've also instituted an internal RFC mechanism (stolen from [Carl Quinn](https://twitter.com/cquinn) who I believe has used it at both Netflix and Riot Games to manage changes required by the dev teams he leads)
10. You end up flooded by data. Everyone says that you need a lot of monitoring. They're right. Its easy to add too. So easy in fact that we ended up submitting a [pull request](https://github.com/Netflix/Hystrix/pull/281) to Hystrix which allows you to filter what is produced because we were flooding the UDP port of our monitoring servers. We're lucky in that we have a great DevOps team who put all the supporting infrastructure in place for us to take advantage of all this too. But we've needed to become expert in setting up just-the-right-amount Grafana dashboards. Its another skill to learn.
11. Dev becomes support and Support becomes dev. this one relates back to Number 5. Folks who are in Support because they want to support things that look like other things will get a shock. We've been lucky - our support guys have been very keen to learn something new. We're getting them to work on new features with us as a means of teaching them how things work. Additionally, because things are so new, we have to get a lot more involved in support. So much so that we're trying to get a big TV for our dev area to put our [Hystrix](https://github.com/Netflix/Hystrix/wiki/Dashboard) / [Grafana](http://grafana.org/) Dashboards on permanently so we know how things are looking

And that's it. I'd like to point out again that so far, we've been _very pleased_ with our decision to adopt this architectural approach. But we're still keeping our eyes open. Remember, there's [No Silver Bullet](https://en.wikipedia.org/wiki/No_Silver_Bullet).
Expand Down
2 changes: 1 addition & 1 deletion _posts/2015-05-06-apollo.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ For further documentation on Apollo components see the docs on GitHub [https://g

We think Apollo fits nicely into the following use cases -

* Build your own internal Plaform as a service (PAAS) leveraging Docker container runtimes
* Build your own internal platform as a service (PAAS) leveraging Docker container runtimes
* Large scale Continuous Integration using the Jenkins Mesos framework. The folks at [Ebay have already done this in production](http://www.ebaytechblog.com/2014/04/04/delivering-ebays-ci-solution-with-apache-mesos-part-i/) and we're looking to provide the Jenkins framework as a Docker container plugin to Apollo soon.
* Manage and distribute your big data workloads. There are a number of big data processing frameworks built on Mesos, such as [Spark](http://spark.incubator.apache.org/) and [Storm](https://github.com/mesosphere/storm-mesos). Again we're looking to provide these pluggable to Apollo in the future.

Expand Down
2 changes: 1 addition & 1 deletion _posts/2015-09-18-delivering-at-devoxx.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ I offered a couple more pattern examples – the horror that was EJB 2.0 and my
The process of actually writing the conference speech was the real revelation for me. I had started with a title, and what ended up as five examples of “antipatterns”, and when I presented this to a demo audience it was clear that I needed more cohesion between my five examples. What was the link between them? What point could I make about the whole thing? I had to go back and drill down into my concept once again.
I emerged with a few opinions that I realised I’d been formulating my whole career.

It’s interesting to watch the evolution of software engineering because it’s such a new discipline. It’s only had time to go through a couple of oscillations through trends. It seems to me that there has been a general trend towards “do everything you can”, the apex of which I would say was EJB 2.0 with a specification so heavy it could not be lifted, let alone read and digested. This can be seen in many areas of software architecture – look at SAP, for example, and the merge of the concepts of a portal website, content management system, document management system that we see in Sharepoint and Vignette amongst others. We are well on the way back down that particular trend now, with “do-one-thing-and-do-it-well” microservice architectures becoming more and more popular. I can see that there are drivers behind these trends – sometimes social, sometimes driven by a particularly powerful company or a particularly well-defined global specification but often driven by the underlying hardware available for processing and networking, and the algorithms that support them. What would the point be in a microservice if your network latency is huge? But now we have optic fibre cables and broadband and near-global 4G wifi, we can rely on messages getting from A to B in a reasonable timeframe. Similarly, why have a wireless camera take a 20 megapixel photo if it doesn’t have the algorithm to compress that picture to be sent?
It’s interesting to watch the evolution of software engineering because it’s such a new discipline. It’s only had time to go through a couple of oscillations through trends. It seems to me that there has been a general trend towards “do everything you can”, the apex of which I would say was EJB 2.0 with a specification so heavy it could not be lifted, let alone read and digested. This can be seen in many areas of software architecture – look at SAP, for example, and the merge of the concepts of a portal website, content management system, document management system that we see in SharePoint and Vignette amongst others. We are well on the way back down that particular trend now, with “do-one-thing-and-do-it-well” microservice architectures becoming more and more popular. I can see that there are drivers behind these trends – sometimes social, sometimes driven by a particularly powerful company or a particularly well-defined global specification but often driven by the underlying hardware available for processing and networking, and the algorithms that support them. What would the point be in a microservice if your network latency is huge? But now we have optic fibre cables and broadband and near-global 4G wifi, we can rely on messages getting from A to B in a reasonable timeframe. Similarly, why have a wireless camera take a 20 megapixel photo if it doesn’t have the algorithm to compress that picture to be sent?

My five patterns all fit well into this angle of software evolution driven by hardware over time. The singleton pattern was important and useful back in the day when you had a single CPU and your entire program ran on one machine. It doesn’t fit so well in a message-based architecture... The Same Origin Policy was implemented in the brave new world of internet commerce, when thick client browser architectures were immature and there were so many open doors for hackers they were spoilt for choice and a quick implementation was more important than a long-lived design. SOAP was a good advancement on CORBA, and at the time was a real step forwards in cross platform architectures, but because the specification became too broad in the “do everything you can” trend there became too many points where underlying implementations could differ. And at the time that the SOAP spec was written, there weren’t really any mobile platforms so the relative size of an XML message didn’t constrain the hardware at either end of the transaction. It reminded me of the human appendix, and goosebumps – things that had a purpose at the time and kind of hung around because there wasn’t a strong enough drive to remove them from the gene pool.

Expand Down
4 changes: 2 additions & 2 deletions _posts/2020-05-18-cypress-testing-framework.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ However overall for me the benefits have outweighed the minor disadvantages. The
Being a NodeJS library Cypress is super easy to get started with. The JavaScript syntax is based off [Mocha](https://mochajs.org) so it is easy to read and already familiar to a lot of developers.

#### 1. Install with npm
{% highlight Javascript %}
{% highlight javascript %}
npm install cypress --save-dev
{% endhighlight %}

Expand All @@ -106,7 +106,7 @@ Launching the test runner has conveniently created the directory structure Cypre
#### 4. Write your first test
In your `test.spec.js` file enter the following:

{% highlight Javascript %}
{% highlight javascript %}
describe('My First Test', () => {
it('Runs a Google search', () => {
cy.visit('https://google.com');
Expand Down
10 changes: 5 additions & 5 deletions _posts/2023-01-06-pact-contract-testing-with-kafka.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ class PlayerContractListenerTest {
PactDslJsonBody jsonBody = new PactDslJsonBody();

jsonBody.stringType("documentType", "contract")
.stringType("firstName", "Lebron")
.stringType("firstName", "LeBron")
.stringType("lastName", "James")
.stringType("team", "LA Lakers")
.stringType("duration", "5 years")
Expand All @@ -96,7 +96,7 @@ class PlayerContractListenerTest {
void successfullyGenerateHeadlineGivenValidMessage(List<Message> messages) {
ContractDetails contractDetails = ContractDetails.builder()
.documentType("contract")
.firstName("Lebron")
.firstName("LeBron")
.lastName("James")
.team("LA Lakers")
.duration("5 years")
Expand Down Expand Up @@ -135,7 +135,7 @@ Once the test is run and the message was successfully processed by our consumer,
"contents": {
"documentType": "contract",
"duration": "5 years",
"firstName": "Lebron",
"firstName": "LeBron",
"lastName": "James",
"salary": "158 million USD",
"team": "LA Lakers"
Expand Down Expand Up @@ -277,7 +277,7 @@ class PlayerContractMapperTest {
.age(37)
.dateSigned(LocalDate.of(2022, 4, 3))
.documentType("contract")
.firstName("Lebron")
.firstName("LeBron")
.lastName("James")
.team("LA Lakers")
.position("Power Forward")
Expand Down Expand Up @@ -325,7 +325,7 @@ As a result the test run failed with the following error:
{
"documentType": "contract",
"duration": "5 years",
"firstName": "Lebron",
"firstName": "LeBron",
- "lastName": "James",
- "salary": "158 million USD",
- "team": "LA Lakers"
Expand Down
Loading

0 comments on commit de35cdf

Please sign in to comment.