Sunday, September 13, 2020

Install Docker on CentOS

Docker (container engine)


What is Docker?

Docker Engine is an open-source containerization technology for building and containerizing your applications. More details on docker here.

Let's get familiarized with few terminologies before we get started with installing docker.

  1. Layer:  A layer represents an instruction in the image’s Dockerfile. Each layer except the very last one is read-only.
  2. Image: A Docker image is built up from a series of layers. A read-only layer that is the base of your container. An image may have a parent image.
  3. Container: A runnable instance of the image that includes everything needed to run an application. Each container is an image readable/writable layers on top of a set of read-only layer
  4. Docker Hub: Central place where images live. It's a service provided by docker to create, manage, and distribute container applications.
  5. Docker machine: A tool to run Docker containers (Linux does this natively).
  6. Docker compose: A tool for defining and running multi-container docker applications.

Install Docker Engine on CentOS

The docker installation for CentOS 7 and 8 is similar. Although, we will use CentOS 8 to show the installation steps here.

Prerequisites to install Docker

To check the Linux distro you have use the following command.
[user@abhishekumrao ~]$ cat /etc/redhat-release
CentOS Linux release 8.2.2004 (Core)
If you are not running on a CentOS v7 box, ensure that your kernel is running version 3.10 or better by running the uname -r command:
[user@abhishekumrao ~]$ uname -r
3.10.0-862.9.1.el7.x86_64

Install the required packages.

  • yum-utils package provides the yum-config-manger utility used to add docker repo.
  • devicemapper requires the lvm2 and device-mapper-persistent-data packages to be installed.
  • Device Mapper is a kernel-based framework that underpins many advanced volume management technologies on Linux.
[user@abhishekumrao ~]$ sudo yum install -y yum-utils device-mapper-persistent-data lvm2
[sudo] password for user:
Last metadata expiration check: 0:04:41 ago on Sun 13 Sep 2020 07:37:49 AM UTC. Package yum-utils-4.0.12-3.el8.noarch is already installed. Package device-mapper-persistent-data-0.8.5-3.el8.x86_64 is already installed. Package lvm2-8:2.03.08-3.el8.x86_64 is already installed. Dependencies resolved. Nothing to do. Complete!

Setting up the Repository

Add the docker repository to your server to ensure that you have the latest version using the following command.

[user@abhishekumrao ~]$ sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
[sudo] password for user:
Adding repo from: https://download.docker.com/linux/centos/docker-ce.repo

Install Docker community edition.

Install docker with the yum install command:

[user@abhishekumrao ~]$ sudo yum install docker-ce

This goes fine in CentOS 7, but in CentOS 8 you may get an error like this

The latest docker engine at the time of writing this guide is 3:19.03.12-3.el7.x86_64 which requires containerd.io >= 1.2.2-3. Since this package is not available we would use --nobest flag to install the best available package of docker which doesn't require containerd.io >= 1.2.2-3. See below terminal output

Now enable docker service
[user@abhishekumrao ~]$ sudo systemctl enable docker
[sudo] password for user:
Created symlink /etc/systemd/system/multi-user.target.wants/docker.service → /usr/lib/systemd/system/docker.service.

Start Docker with the systemctl start command:

[user@abhishekumrao ~]$ sudo systemctl start docker

You can verify the service status by using the following command

[user@abhishekumrao ~]$ systemctl status docker
[sudo] password for user:
● docker.service - Docker Application Container Engine
   Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled)
   Active: active (running) since Sun 2020-09-13 10:49:40 UTC; 35s ago
     Docs: https://docs.docker.com
 Main PID: 39526 (dockerd)
    Tasks: 22
   Memory: 49.1M
   CGroup: /system.slice/docker.service
           ├─39526 /usr/bin/dockerd -H fd://
           └─39536 containerd --config /var/run/docker/containerd/containerd.toml --log-level info


We can now verify the docker installation by running a small container hello-world using the docker run command:

[user@abhishekumrao ~]$ sudo docker run hello-world
[sudo] password for user:
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
0e03bdcc26d7: Pull complete
Digest: sha256:4cf9c47f86df71d48364001ede3a4fcd85ae80ce02ebad74156906caff5378bc
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

For best practices, we should avoid using root. Instead, you can add your user to the Docker group. For example, to user abhishek use the below command:

[user@abhishekumrao ~]$ sudo usermod -a -G docker abhishek

[sudo] password for user:

[user@abhishekumrao ~]$

Confirm the change with the grep command:

[user@abhishekumrao ~]$ cat /etc/group | grep docker
docker:x:973:abhishek

Once finished, log out and then log back in for changes to take effect.

Sunday, December 22, 2019

Caching in Java ecosystem

What is Caching?

Caching refers to storing a copy of or reference to information that an application may reuse at some later point in time, thus alleviating the cost to re-access or re-create it.

It is often assumed that information from a database is being cached. This however is not a
a requirement of caching. Fundamentally any information that is expensive or time-consuming to
produce or access can be stored in a cache. Some common use cases are:
  •  client-side caching of Web service calls
  •  caching of expensive computations such as rendered images
  •  caching of data
  •  servlet response caching
  •  caching of domain object graphs


Benefits

  • Performance
  • Reduce calls to expensive or non-scalable parts of the system
  • Scale (Up/Down)


JCache or JSR 107

JSR 107 also called JCache is the specification that describes the objectives and functionality of the Java Caching Application Programming Interface (“API”).
JCache is the standard caching API for Java.

Note: Unlike other reference implementations, it’s not recommended to use JCache Reference Implementation in production since it causes some concurrency issues.

You can take a look at the JSR here.

Questions to ask when selecting a cache framework

  • What type of cache do you need? Is it a shared cache in a single node or distributed on multiple nodes?
  • What kind of data do you want to store and its size? Like Objects, static data, simple key-value pairs, or in-memory data structures?
  • What type of licensing or support are you looking for? Example open-source, commercial, or framework-provided cache solutions?
  • What kind of performance, reliability, scalability, and availability you want to get from caching?
  • What are your cache replication and distribution requirements?
  • What is the permissible trade-off between consistency and latency? Do you want your cache to support transactions?


Caching Solutions


Provider Software Products Open-Source PaaS offering
Alachisoft Ncache(native .NET)
TayzGrid (native Java)
Yes No
Amazon Web Services No memcached ElastiCache
Fujitsu Interstage eXtreme Transaction Processing Server No No
Gigaspaces Technologies Gigaspaces XAP Premium and
Platinum Editions
Gigaspaces XAP Open
Source Edition
No
GridGain GridGain Professional Edition
GridGain Enterprise Edition
Apache Ignite No
Hazelcast Hazelcast Professional
Hazelcast Enterprise
Hazelcast Open
Source
No
Hitachi Hitachi Elastic Application Data
Store
No No
IBM WebSphere eXtreme Scale No IBM Bluemix Data Cache
and Session Cache
Oracle Oracle Coherence No Oracle Java Cloud
Service (feature)
Pivotal Pivotal Gemfire (component of the
Pivotal Big Data Suite)
Apache Geode No
Red Hat Red Hat JBoss Data Grid Infinispan Red Hat OpenShift Online
JBoss xPaaS (feature)
Redis Labs No Memcached Memcached Cloud
ScaleOut Software ScaleOut StateServer No No
Software AG Terracotta BigMemory Terracotta Server,
Ehcache
No
TIBCO TIBCO ActiveSpaces No No
TmaxSoft TmaxSoft InfiniCache No No


Popular Open Source caching solutions

1. Hazelcast

Open Source In-Memory Data Grid 
JCache Provider 
Apache 2 License
Small JAR with Minimal Dependencies
Embedded or Client Server
API with Multiple Language Clients
Paid support is available

2.  Infinispan

Infinispan is a distributed in-memory key/value data store with optional schema, available under the Apache License 2.0.

Available as an embedded Java library or as a language-independent service accessed remotely over a variety of protocols (Hot Rod, REST, Memcached)
Use it as a cache or a data grid.
Advanced functionality such as persistence, transactions, events, querying, distributed processing, off-heap and geographical failover.
Monitor and manage it through JMX, a CLI, and a web-based console.
Integrates with JPA, JCache, Spring, Spark, and many more.
Works on bare-metal, containerized, and virtualized environments.
Works on AWS, Azure, Google Cloud, Kubernetes, and OpenShift.

3. Redis

Redis is an open-source (BSD licensed), in-memory data structure store, used as a database, cache, and message broker. It supports data structures such as strings, hashes, lists, sets, sorted sets with range queries, bitmaps, hyperloglogs, geospatial indexes with radius queries and streams. Redis has built-in replication, Lua scripting, LRU eviction, transactions, and different levels of on-disk persistence, and provides high availability via Redis Sentinel and automatic partitioning with Redis Cluster.

4. Ehcache and Terracota

Ehcache is an open-source Java distributed cache for general purpose caching, Java EE, and light-weight containers. Ehcache is available under an Apache open source license. 
In 2009, the project was purchased by Terracotta, who provides paid support.

After the merger, Ehcache added support for distribution into a coherent distributed cache using the Terracotta Server Array. Plus you get some really useful tools to help you see what's happening inside the cache, manage cache policies like eviction, TTL, etc., and generally tune the application much more easily.


5. Memcached

Free & open-source, high-performance, distributed memory object caching system, generic in nature, but intended for use in speeding up dynamic web applications by alleviating database load.

Memcached is an in-memory key-value store for small chunks of arbitrary data (strings, objects) from results of database calls, API calls, or page rendering.

Memcached is simple yet powerful. Its simple design promotes quick deployment, ease of development, and solves many problems facing large data caches. Its API is available for most popular languages.


Open source caching frameworks: A comparison





Spring Supported Cache Providers

Spring's cache abstraction does not provide an actual store and relies on abstraction materialized by the org.springframework.cache.Cache and org.springframework.cache.CacheManager abstraction.
If you have not defined a bean of type CacheManager or a CacheResolver named cacheResolver 
(see CachingConfigurer), Spring Boot tries to detect the following providers (in the indicated order):

1. Generic
2. JCache (JSR-107) (EhCache 3, Hazelcast, Infinispan, and others)
3. EhCache 2.x
4. Hazelcast
5. Infinispan
6. Couchbase
7. Redis
8. Caffeine
9. Simple

Monday, September 10, 2018

Design Principles

For writing efficient and maintainable code, there are few principles that a programmer should keep in mind, these would become second nature with time. These design principles give way to more concrete and refined implementation for solving specific use cases called design patterns. A must to build reliable system that are also easy to maintain.

I am listing down some of these principle here:

  • Identify the aspects of your code that vary and separate them from what stays the same.   
         "Encapsulate what varies"
          If some aspect of the code is changing, that's a sign you should pull it out and separate it. By                            separating out the parts of your code that vary, you can extend or alter them
          without affecting the rest of the code.

  • Program to an interface, not an implementation.
  • Favour composition over inheritance.
  • Strive for loosely coupled designs between objects that interact.
  • Classes should be open for extension but closed for modification (The open-closed principle)
  • A class should have only one reason to change.
These were from one of the lectures by Eric Freeman, the author of Head First Design Patterns. I would recommend checking out the book for detailed take on design pattern or one of his courses on software design or programming..



Sunday, July 8, 2018

Aspect Oriented Programming and Spring

In almost every application you develop there are scenarios which when solved using Aspect Oriented programming (AOP) can result in a low code, efficient and elegant solution. I will be giving a basic outline of AOP in spring and in which scenarios it can be useful. When used properly AOP will be a powerful tool in you software development kit.

Aspect-Oriented Programming is a programming paradigm like Object-Oriented Programming (OOP). In OOP the key unit of modularity is the class, whereas in AOP the unit of modularity is the aspect.

What are Aspects?

  • Reusable blocks of code that are injected into applications code in runtime
  • Powerful tools for adding behaviour
  • Solve cross cutting concerns in one place
What is a cross cutting concern?
  • Evaluate business requirements and look for words like every or always
  • Look for system level requirements that apply to multiple business requirements
When?

   Few examples
  • In a logging routine that applies to every service method
  • Transaction management is a good example of a crosscutting concern in J2EE applications.
  • Specialized exception handlers or message translators used throughout the application
Why?
  • Avoid code duplication
  • Mixing of concerns
  • Maintain application logic
Spring Aspects
  • Leverages AspectJ for aspecting.
  • Byte code modification (Run time interweaving).
  • Dynamic proxy bases (That's why every spring manages bean has at least a proxy). In the Spring Framework, an AOP proxy will be a JDK dynamic proxy or a CGLIB proxy.

Parts of Spring Aspect

  • Joint point is a point in code of a program where execution of an aspect is targeted towards. This is your method or line of code where your annotation that the aspect is going to target.
  • Pointcut is the expression that identifies that join point through some sort of regular expression matching.
  • Advice is the code that you actually execute at a join point that was selected by the point cut. It is the cross cutting concern routine that we are applying to, a join point in our application.
  • Aspect is a module that contains all the pointcuts as well as advice that is injected at runtime.
  • Weaving: Linking aspects with other application types or objects to create an advised object. This can be done at compile time (using the AspectJ compiler, for example), load time, or at runtime. Spring AOP, like other pure Java AOP frameworks, performs weaving at runtime.


    You can use either xml based or annotation based configuration to setup you pointcut and advice.

    Types of advice
    • Before advice: Advice that executes before a join point, but which does not have the ability to prevent execution flow proceeding to the join point (unless it throws an exception).
    • After returning advice: Advice to be executed after a join point completes normally.
    • After throwing advice: Advice to be executed if a method exits by throwing an exception.
    • After (finally) advice: Advice to be executed regardless of the means by which a join point exits (normal or exceptional return).
    • Around advice: Advice that surrounds a join point such as a method invocation. This is the most powerful kind of advice. Around advice can perform custom behavior before and after the method invocation. It is also responsible for choosing whether to proceed to the join point or to shortcut the advised method execution by returning its own return value or throwing an exception.
    Common Designators
    • execution: expression for matching execution
    • within: expression for matching within certain types
    • target: expression for matching specific type
    • @annotation: expression for matching a specific annotation

    References:
    • I found course Spring: Framework In Depth by Frank P. Moley III very useful not only for AOP but in general. It filled some holes in my knowledge and has nice examples and insights. 
    • Spring framework documentation is also very good.

    Tuesday, September 5, 2017

    Composed Message Processing using Apache Camel Splitter and Aggregator


    The Composed Message Processor is an EIP(Enterprise Integration Pattern) which allows us to process a composite message by splitting it up for individul processing, routing the sub-messages to appropriate destinations and the aggregating the responses back into a single message.

    Apache Camel™ is one of the most popular open source integration framework that allows conditional routing in any of defined domain-specific languages, be it Java, XML or Scala. A Route contains flow and integration logic using a specific DSL.

    Composed Message Processor
    Composed Message Processing







    Sample Route with a dynamic content based router, which on arrival of composite request splits it into the request of the applicable system System 1, 2 and 3, aggreagates response from all three systems and sends it to another system, from where the result is sent back to requester.
    The same can also be implemented for returning aggregated response to requester by simply sending the response back without redirecting to another service url.

    Below is sample Apache Camel route in Spring DSL.

    Sample Route with a dynamic content based router, which on arrival of composite request splits it using custom splitting stategy defined in bean customSplitter. Here the three sytems are invoked in parallel aand the responses are aggregated on the go using custom aggregation strategy defined in bean customAggregator.
    Here,  Element: split
    Breaks a single message into many sub-messages. Here is an example of how a splitter can be implemented.

    The request is split into three sub mesagges and directed to separate routes namely
    routeSystem1, routeSystem2 and routeSystem3. The responses from these route are then passed into the aggregator for combining them.

    Attribute : strategyRef
    Sets a reference to the AggregationStrategy to be used to assemble the replies from the splitted messages.Here we are using a POJO as the AggregationStrategy. Here is an example of how an aggregator can be implemented.


    The aggregator supports two main features of parallel processing and stopping the route on exception as explained below.
    Here we are processing requests parallely instead of sequentially. So, the aggregator should be thread safe and there should be no dependency between the Systems 1, 2 and 3.

    Attribute : parallelProcessing
    If enabled then processing each splitted messages occurs concurrently. Note the caller thread will still wait until all messages has been fully processed, before it continues. Its only processing the sub messages from the splitter which happens concurrently.
    Default value: false

    Attribute : stopOnException
    Will stop further processing if an exception or failure occurred during processing of an org.apache.camel.Exchange and the caused exception will be thrown. Will also stop if processing the exchange failed (has a fault message) or an exception was thrown and handled by the error handler (such as using onException). In all situations the splitter will stop further processing.
     Default value: false

    The route doesn't end here as you can see this aggregated response is sent to the final web service, and the response received from there is forwarded to serviceProcessor  bean if in case you want any processing on the incoming response after that the response will be redirected to the caller. As we can see, the interaction with 4 different systems with complex route design can be achieved very easily with the help of Apache camel. One thing to keep in mind is that the code handling bulk requests should have robust logging and error handling.
    Also, do keep in mind the timeouts of various systems and transaction handling if required.

    Featured Post

    Install Docker on CentOS

    What is Docker? Docker Engine is an open-source containerization technology for building and containerizing your applications. More details ...

    Most viewd