588 lines
26 KiB
TeX
588 lines
26 KiB
TeX
% ! TeX program = lualatex
|
|
\documentclass[a4paper,11pt]{article}
|
|
% packages
|
|
\usepackage{censor}
|
|
\StopCensoring
|
|
\usepackage{fontspec}
|
|
\setmainfont{EB Garamond}
|
|
% for tironian et fallback
|
|
% % \directlua{luaotfload.add_fallback
|
|
% % ("emojifallback",
|
|
% % {"Noto Serif:mode=harf"}
|
|
% % )}
|
|
% % \setmainfont{EB Garamond}[RawFeature={fallback=emojifallback}]
|
|
|
|
\setmonofont[Scale=MatchLowercase]{Deja Vu Sans Mono}
|
|
\usepackage[a4paper,left=2cm,right=2cm,top=\dimexpr15mm+1.5\baselineskip,bottom=2cm]{geometry}
|
|
\setlength{\parindent}{0pt}
|
|
|
|
\usepackage{fancyhdr} % Headers and footers
|
|
\fancyhead[R]{\normalfont \leftmark}
|
|
\fancyhead[L]{}
|
|
\pagestyle{fancy}
|
|
|
|
\usepackage{microtype} % Slightly tweak font spacing for aesthetics
|
|
\usepackage[english]{babel} % Language hyphenation and typographical rules
|
|
\usepackage{xcolor}
|
|
\definecolor{linkblue}{RGB}{0, 64, 128}
|
|
\usepackage[final, colorlinks = false, urlcolor = linkblue]{hyperref}
|
|
% \newcommand{\secref}[1]{\textbf{§~\nameref{#1}}}
|
|
\newcommand{\secref}[1]{\textbf{§\ref{#1}~\nameref{#1}}}
|
|
|
|
\usepackage{changepage} % adjust margins on the fly
|
|
\usepackage{amsmath,amssymb}
|
|
|
|
\usepackage{minted}
|
|
\usemintedstyle{algol_nu}
|
|
|
|
\usepackage{pgfplots}
|
|
\pgfplotsset{width=\textwidth,compat=1.9}
|
|
|
|
\usepackage{caption}
|
|
\newenvironment{code}{\captionsetup{type=listing}}{}
|
|
\captionsetup[listing]{skip=0pt}
|
|
\setlength{\abovecaptionskip}{5pt}
|
|
\setlength{\belowcaptionskip}{5pt}
|
|
|
|
\usepackage[yyyymmdd]{datetime}
|
|
\renewcommand{\dateseparator}{--}
|
|
|
|
\usepackage{enumitem}
|
|
|
|
\usepackage{titlesec}
|
|
|
|
\author{Andrew Hayes}
|
|
|
|
\begin{document}
|
|
\begin{titlepage}
|
|
\begin{center}
|
|
\hrule
|
|
\vspace*{0.6cm}
|
|
\Huge \textsc{ct414}
|
|
\vspace*{0.6cm}
|
|
\hrule
|
|
\LARGE
|
|
\vspace{0.5cm}
|
|
Distributed Systems \& Co-Operative Computing
|
|
\vspace{0.5cm}
|
|
\hrule
|
|
|
|
\vfill
|
|
|
|
\hrule
|
|
\begin{minipage}{0.495\textwidth}
|
|
\vspace{0.4em}
|
|
\raggedright
|
|
\normalsize
|
|
\begin{tabular}{@{}l l}
|
|
Name: & Andrew Hayes \\
|
|
Student ID: & 21321503 \\
|
|
E-mail: & \href{mailto://a.hayes18@universityofgalway.ie}{a.hayes18@universityofgalway.ie} \\
|
|
\end{tabular}
|
|
\end{minipage}
|
|
\begin{minipage}{0.495\textwidth}
|
|
\raggedleft
|
|
\vspace*{0.8cm}
|
|
\Large
|
|
\today
|
|
\vspace*{0.6cm}
|
|
\end{minipage}
|
|
\medskip\hrule
|
|
\end{center}
|
|
\end{titlepage}
|
|
|
|
\pagenumbering{roman}
|
|
\newpage
|
|
\tableofcontents
|
|
\newpage
|
|
\setcounter{page}{1}
|
|
\pagenumbering{arabic}
|
|
|
|
\section{Introduction}
|
|
\subsection{Client-Server Architectures}
|
|
\subsubsection{Two-Tier Architectures}
|
|
A \textbf{two-tier client-server architecture} is a client-server architecture wherein a client talks directly to a server, with no intervening server.
|
|
It is typically used in small environments ($\lesssim$ 50 users).
|
|
\\\\
|
|
A common development error is to prototype an application in a small, two-tier environment, and then scale up by simply adding more users to the server:
|
|
this approach will usually result in an ineffective system, as the server becomes overwhelmed.
|
|
To properly scale to hundreds or thousands of users, it is usually necessary to move to a three-tier architecture.
|
|
|
|
\begin{figure}[H]
|
|
\centering
|
|
\includegraphics[width=0.7\textwidth]{./images/client-server-tcpip.png}
|
|
\caption{
|
|
Client \& server using TCP/IP protocols to communicate.
|
|
Information can flow in either or both directions.
|
|
The client \& server can interact with a transport layer protocols.
|
|
}
|
|
\end{figure}
|
|
|
|
\subsection{Three-Tier Architecture}
|
|
A \textbf{three-tier client-server architecture} introduces a server or \textbf{agent} (or \textbf{load-balancer}) between the client \& the server.
|
|
The agent has many roles:
|
|
\begin{itemize}
|
|
\item Translation services: such as adapting a legacy application on a mainframe to a client-server environment.
|
|
\item Metering services: such as acting as a transaction monitor to limit the number of simultaneous requests to a given server.
|
|
\item Intelligent agent services: as in mapping a request to a number of different servers, collating the results, and returning a single response to the client.
|
|
\end{itemize}
|
|
|
|
\subsection{Network Programming Paradigms}
|
|
Practically all network programming is based on a client-server model; the only real difference in paradigms is the \textbf{level} at which the programmer operates.
|
|
The sockets API provides direct access to the available transport layer protocols.
|
|
RPC is a higher-level abstraction that hides some of the lower-level complexities.
|
|
Other approaches are also possible:
|
|
\begin{itemize}
|
|
\item Sockets are probably the best-known and most widely-used paradigm.
|
|
However, problems of data incompatibility across platforms can arise.
|
|
|
|
\item RPC libraries aim to solve some of the basic problems with sockets and provide a level of transport independence.
|
|
|
|
\item Neither approach works very well with modern applications (Java RMI and other mdoern technologies, e.g., web services are better).
|
|
\end{itemize}
|
|
|
|
\section{Java RMI}
|
|
\textbf{Remote Method Invocation (RMI)} is a Java-based mechanism for distributed object computing.
|
|
RMI enables the distribution of work to other Java objects residing in other processes or on other machines.
|
|
The objects in one Java Virtual Machine (JVM) are allowed to seamlessly invoke methods on objects in a remote JVM.
|
|
To call a method of a remote object, we must first get a reference to that object, which can be obtained from the registry name facility or by receiving the reference as an argument or return value of a method call.
|
|
Clients can call a remote object in a server that itself is a client of another server.
|
|
Parameters of method calls are passed as serialised objects:
|
|
\begin{itemize}
|
|
\item types are not truncated, and therefore, object-oriented polymorphism is supported;
|
|
\item parameters are passed by value (deep copy) and therefore object behaviour can be passed.
|
|
\end{itemize}
|
|
|
|
The Java Object Model is still supported with distributed (remote) objects.
|
|
A reference to a remote object can be passed to or returned from local \& remote objects.
|
|
Remote object references are passed by reference: therefore, the whole object is not always downloaded.
|
|
Objects that implement the \mintinline{java}{Remote} interface are passed as a remote reference, while other objects are passed by value (using object serialisation).
|
|
|
|
\begin{figure}[H]
|
|
\centering
|
|
\includegraphics[width=0.8\textwidth]{./images/javarmi.png}
|
|
\caption{Java RMI Architecture}
|
|
\end{figure}
|
|
|
|
The client obtains a reference for a remote object by calling \mintinline{java}{Naming.lookup(//URL/registered_name)} which is a method which returns a reference to another remote object.
|
|
Methods of the remote object may then be called by the client.
|
|
This call is actually to the \textbf{stub} which represents the remote object.
|
|
The stub packages the arguments (\textbf{marshalling}) into a data stream (to be sent across the network).
|
|
On the implementation side, the skeleton unmarshals the argument, calls the method, marshals the return value, and sends it back.
|
|
The stub unmarshals the return value and returns it to the caller.
|
|
The RMI layer sits on top of the JVM and this allows it to use Java Garbage Collection of remote objects, Java Security (a security manager may be set for the server, now deprecated), and Java class loading.
|
|
|
|
\subsection{Steps to Creating an RMI Application}
|
|
\begin{enumerate}
|
|
\item Define the interfaces to your remote objects.
|
|
\item Implement the remote object classes.
|
|
\item Write the main client \& server programs.
|
|
\item Create the stub \& skeleton classes by running the \textit{rmic} compiler on the remote implementation classes. (No longer needed in later Java versions).
|
|
\item Start the \textit{rmiregistry} (if not already started).
|
|
\item Start the server application.
|
|
\item Start the client (which contains some initial object references).
|
|
\item The client application/applet may then call object methods in the remote (server) program.
|
|
\end{enumerate}
|
|
|
|
\subsection{Example Java RMI Program}
|
|
\begin{code}
|
|
\begin{minted}[linenos, breaklines, frame=single]{java}
|
|
// Remote Object has a single method that is passed
|
|
// the name of a country and returns the capital city.
|
|
import java.rmi.*;
|
|
|
|
public interface CityServer extends Remote
|
|
{
|
|
String getCapital(String Country) throws
|
|
RemoteException;
|
|
}
|
|
\end{minted}
|
|
\caption{Example Java RMI Program}
|
|
\end{code}
|
|
|
|
\begin{code}
|
|
\begin{minted}[linenos, breaklines, frame=single]{java}
|
|
import java.rmi.*;
|
|
import java.rmi.server.*;
|
|
|
|
public class CityServerImpl
|
|
extends UnicastRemoteObject
|
|
implements CityServer
|
|
{
|
|
// constructor is required in RMI
|
|
CityServerImpl() throws RemoteException
|
|
{
|
|
super(); // call the parent constructor
|
|
}
|
|
|
|
// Remote method we are implementing!
|
|
public String getCapital(String country) throws
|
|
RemoteException
|
|
{
|
|
System.out.println("Sending return string now - country requested: " + country);
|
|
if (country.toLowerCase().compareTo("usa") == 0)
|
|
return "Washington";
|
|
else if (country.toLowerCase().compareTo("ireland") == 0)
|
|
return "Dublin";
|
|
else if (country.toLowerCase().compareTo("france") == 0)
|
|
return "Paris";
|
|
return "Don't know that one!";
|
|
}
|
|
|
|
// main is required because the server is standalone
|
|
public static void main(String args[])
|
|
{
|
|
try
|
|
{
|
|
// First reset our Security manager
|
|
System.setSecurityManager(new RMISecurityManager());
|
|
System.out.println("Security manager set");
|
|
|
|
// Create an instance of the local object
|
|
CityServerImpl cityServer = new CityServerImpl();
|
|
System.out.println("Instance of City Server created");
|
|
|
|
// Put the server object into the Registry
|
|
Naming.rebind("Capitals", cityServer);
|
|
System.out.println("Name rebind completed");
|
|
System.out.println("Server ready for requests!");
|
|
} catch(Exception exc)
|
|
{
|
|
System.out.println("Error in main - " + exc.toString());
|
|
}
|
|
}
|
|
}
|
|
\end{minted}
|
|
\caption{Example Server Implementation}
|
|
\end{code}
|
|
|
|
\begin{code}
|
|
\begin{minted}[linenos, breaklines, frame=single]{java}
|
|
public class CityClient
|
|
{
|
|
public static void main (String args[])
|
|
{
|
|
CityServer cities = (CityServer) Naming.lookup("//localhost/Capitals");
|
|
try {
|
|
String capital = cities.getCapital("USA");
|
|
System.out.println(capital);
|
|
} catch (Exception e) {}
|
|
}
|
|
}
|
|
\end{minted}
|
|
\caption{Example Client Implementation}
|
|
\end{code}
|
|
|
|
No distributed system can mask communication failures: method semantics should include failure possibilities.
|
|
Every RMI remote method must declare the exception \mintinline{java}{RemoteException} in its \mintinline{java}{throw} clause.
|
|
This exception is thrown when method invocation or return fails.
|
|
The Java compiler requires the failures to be handled.
|
|
\\\\
|
|
When implementing a remote object, the implementation class usually extends the RMI class \mintinline{java}{UnicastRemoteObject}: this indicates that the implementation class is used to create a single (non-replicated) remote object that uses RMI's default sockets-based transport for communication.
|
|
If you choose to extend a remote object from a non-remote class, you need to explicitly export the remote object by calling the method \mintinline{java}{UnicastRemoteObject.exportObject()}.
|
|
\\\\
|
|
The main method of the service first needs to create \& install a \textbf{security manager}, either the \mintinline{java}{RMISecurityManager} or one that you have defined yourself.
|
|
A security manager needs to be running so that it can guarantee that the classes loaded do not perform ``sensitive'' operations.
|
|
If no security manager is specified, no class loading for RMI classes is allowed, local or otherwise.
|
|
\\\\
|
|
TO make classes available via a web server (or your classpath), copy them into your public HTML directory.
|
|
Alternatively, you could have compiled your files directly into your public HTML directory:
|
|
\begin{minted}[linenos, breaklines, frame=single]{shell}
|
|
javac -d ~/project_dir/public_html City*.java
|
|
rmic -d ~/project_dir/public_html CityServerImpl
|
|
\end{minted}
|
|
|
|
The files generated by \mintinline{shell}{rmic} (in this case) are: \verb|CityServerImpl_Stub.class| \& \verb|CityServerImpl_Skel.class|.
|
|
\\\\
|
|
\textbf{Polymorphic distributed computing} is the ability to recognise (at runtime) the actual implementation type of a particular interface.
|
|
We will use the example of a remote object that is used to computer arbitrary tasks:
|
|
\begin{itemize}
|
|
\item Client sends task object to compute server.
|
|
\item Compute server runs task and returns result.
|
|
\item RMI loads task code dynamically in the server.
|
|
\end{itemize}
|
|
This example shows polymorphism on the server, but it also works on the client, for example the server returns a particular interface implementation.
|
|
\\\\
|
|
Our example task will be a simple interface that defines an arbitrary task to compute:
|
|
\begin{code}
|
|
\begin{minted}[linenos, breaklines, frame=single]{java}
|
|
public interface Task extends Serializable
|
|
{
|
|
Object run();
|
|
}
|
|
\end{minted}
|
|
\caption{Simple \mintinline{java}{Task} interface}
|
|
\end{code}
|
|
|
|
We will also define a \mintinline{java}{Remote} interface:
|
|
\begin{code}
|
|
\begin{minted}[linenos, breaklines, frame=single]{java}
|
|
import java.rmi.*;
|
|
|
|
public interface Compute extends Remote
|
|
{
|
|
Object runTask(Task t) throws RemoteException;
|
|
}
|
|
\end{minted}
|
|
\caption{Simple \mintinline{java}{Task} interface}
|
|
\end{code}
|
|
|
|
A task may create a \mintinline{java}{Remote} object on the server and return a reference to that object; the \mintinline{java}{Remote} object will be garbage-collected when the returned reference is dropped (assuming that no-one else is given a copy of the reference).
|
|
A task may create a \mintinline{java}{Serializable} object and return a copy of that object; the original object will be locally garbage-collected when the \mintinline{java}{Task} ends.
|
|
If the \mintinline{java}{Task} creates an object that is neither a \mintinline{java}{Remote} nor a \mintinline{java}{Serializable} object, a marshalling exception will be thrown.
|
|
|
|
\begin{code}
|
|
\begin{minted}[linenos, breaklines, frame=single]{java}
|
|
import java.rmi.*;
|
|
import java.rmi.server.*;
|
|
|
|
public class ComputeServer extends UnicastRemoteObject implements Compute
|
|
{
|
|
public ComputeServer() throws RemoteException {}
|
|
|
|
public Object runTask(Task t)
|
|
{
|
|
return t.run();
|
|
}
|
|
}
|
|
\end{minted}
|
|
\caption{Compute server implementation}
|
|
\end{code}
|
|
|
|
\begin{code}
|
|
\begin{minted}[linenos, breaklines, frame=single]{java}
|
|
public static void main(String args[])
|
|
{
|
|
System.setSecurityManager(new RMISecurityManager());
|
|
try
|
|
{
|
|
ComputeServer cs = new ComputeServer();
|
|
Naming.rebind("Computer", cs);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
// Exception handling
|
|
}
|
|
}
|
|
\end{minted}
|
|
\caption{Compute server implementation}
|
|
\end{code}
|
|
|
|
\begin{code}
|
|
\begin{minted}[linenos, breaklines, frame=single]{java}
|
|
public class Pi implements Task
|
|
{
|
|
private int places;
|
|
|
|
public Pi (int places)
|
|
{
|
|
this.places = places;
|
|
}
|
|
|
|
public Object run()
|
|
{
|
|
// Compute Pi
|
|
return result;
|
|
}
|
|
}
|
|
\end{minted}
|
|
\caption{Task to compute $\pi$}
|
|
\end{code}
|
|
|
|
\begin{code}
|
|
\begin{minted}[linenos, breaklines, frame=single]{java}
|
|
Compute comp = (Compute) Naming.Lookup("//www.t.nuigalway.ie/Computer");
|
|
|
|
Pi pi = new Pi(100);
|
|
Object piResult = comp.runTask(pi);
|
|
|
|
// print results
|
|
\end{minted}
|
|
\caption{The client}
|
|
\end{code}
|
|
|
|
In conclusion, RMI is flexible and allows us to pass objects (both \mintinline{java}{Remote} \& \mintinline{java}{Serializable}) by exact type rather than declared type and download code to introduce extended functionality in both client \& server.
|
|
However, it is Java-only and has been superseded by SOAP \& REST as the de-facto standards for communicating with remote services.
|
|
Nonetheless, RMI is still worth learning to help understand concepts around distributed objects \& distributed systems architecture.
|
|
|
|
\section{Enterprise Java Beans}
|
|
\subsection{Distributed System Scenario}
|
|
Imagine a worldwide financial company with 10,000 online customers that wants to add a new currency converter software component that is heavily used with 1,0000 hits/second.
|
|
The design will consist of the business logic and the distributed infrastructure.
|
|
The distributed infrastructure includes security, load-balancing, transaction management, \& object-relational mapping; Enterprise Java Beans takes care of this, and provides an API \& framework.
|
|
|
|
\begin{figure}[H]
|
|
\centering
|
|
\includegraphics[width=0.7\textwidth]{./images/distributed_system_scenario.png}
|
|
\caption{
|
|
Business logic, distribute the object, add security manager, add load balancing agent.
|
|
}
|
|
\end{figure}
|
|
|
|
\subsection{EJB}
|
|
\textbf{Enterprise Java Beans (EJB)} is a server-side component architecture that enables and simplifies the process of building enterprise-class distributed object applications in Java.
|
|
It allows you to write scalable, reliable, and secure applications without writing your own complex distributed object frameworks.
|
|
EJB is a \textit{specification}.
|
|
|
|
\begin{figure}[H]
|
|
\centering
|
|
\includegraphics[width=0.7\textwidth]{./images/the_ejb_proces.png}
|
|
\caption{
|
|
The EJB process
|
|
}
|
|
\end{figure}
|
|
|
|
The \textbf{EJB Container} is where the EJBs run and is responsible for managing EJBs.
|
|
The \textbf{EJB Server} is a runtime environment for container(s) that manages the low-level system resources.
|
|
|
|
\begin{figure}[H]
|
|
\centering
|
|
\includegraphics[width=0.7\textwidth]{./images/ejb_server_and_container.png}
|
|
\caption{ The EJB server \& containers }
|
|
\end{figure}
|
|
|
|
\begin{figure}[H]
|
|
\centering
|
|
\includegraphics[width=0.7\textwidth]{./images/ejb_bean_types.png}
|
|
\caption{ EJ Bean types }
|
|
\end{figure}
|
|
|
|
\textbf{Session beans} are ``business process objects'' (e.g., price quoting, order entry, video compression, stock trades, etc.) and live for as long as the client's session.
|
|
They are usable by 1 client at a time and are \textit{not} shared.
|
|
The EJB server manages the lifetime of beans.
|
|
\textbf{Stateless session beans} are single request with no state kept, e.g., currency converter, compression utility, or credit card verification.
|
|
\\\\
|
|
\textbf{Entity beans / JPA} represent persistent data.
|
|
They are the object-oriented in-memory view of data in an underlying data store.
|
|
They are long-lasting and have shared access.
|
|
Sub-types of entity beans include: bean-managed persisted entity beans and container-manager persistent entity beans.
|
|
\textbf{Bean-managed persistence} must be persisted manually and must look after saving, loading, \& finding.
|
|
They make use of a persistence API such as JDBC or SQL/J.
|
|
\textbf{Container-managed persistence} is automatic persistence wherein the container/server looks after the loading, saving, \& finding of component data.
|
|
You must describe what you want persisted.
|
|
Deployment tools provide support for defining simple object-relational mappings.
|
|
\\\\
|
|
The client never invokes the bean instance, instead it invokes the \textbf{EJB object} by an invocation that is intercepted by the container, delegated to the bean instance.
|
|
The EJB object is a surrogate, network-aware wrapper object that serves as a layer of indirection between the client \& the bean; it is essentially the glue between the client \& the bean.
|
|
EJB objects must clone every business method that your bean class exposes, specified in the remote interface.
|
|
All remote interfaces derive from \mintinline{java}{javax.ejb.EJBObject}.
|
|
|
|
\begin{figure}[H]
|
|
\centering
|
|
\includegraphics[width=0.7\textwidth]{./images/ejb_objets.png}
|
|
\caption{ EJB Objects }
|
|
\end{figure}
|
|
|
|
The \textbf{session bean interface} is implemented by all session beans and specifies lifecycle methods that may be implemented inn the bean such as \mintinline{java}{setSessionContext}, \mintinline{java}{ejbCreate}, \mintinline{java}{ejbRemove}, \mintinline{java}{ejbPassivate}, \& \mintinline{java}{ejbActivate}.
|
|
\\\\
|
|
The \textbf{Java Naming \& Directory Interface} is used to find an object.
|
|
The resource (e.g., a bean) is associated with a nickname when deploying; clients of this bean can then use this nickname to look up the resource across a deployment.
|
|
The client code looks up the reference in JNDI and calls business methods on the EJB object.
|
|
|
|
\subsubsection{Entity EJBs}
|
|
\textbf{Entity EJBs} are object-based representations of information-tier data such as data stored in a relational database.
|
|
They represent a particular unit of data, e.g., a record in a database.
|
|
There are two types of entity EJB:
|
|
\begin{itemize}
|
|
\item Bean-managed persistence;
|
|
\item Container-managed persistence.
|
|
\end{itemize}
|
|
|
|
\section{NodeJS}
|
|
\textbf{NodeJS} is a JavaScript runtime environment that runs Google Chrome's V8 engine.
|
|
It is a server-side solution for JavaScript which compiles JavaScript, making it quite fast.
|
|
It was created in 2009 and designed for high concurrency, without threads or new processes.
|
|
It has evented I/O for JavaScript, and never blocks, not even for I/O.
|
|
It's goal is to provide an easy way to build scalable network programs.
|
|
It provides a JavaScript API to access the network \& file system and instead of threads, node uses an event loop with a stack which alleviates the overhead of context switching.
|
|
\begin{itemize}
|
|
\item JavaScript on the server-side ensures that communication between the client and the server will happen in the same language, with native JSON objects on both sides.
|
|
\item Servers are normally thread-based, but Node is \textbf{event-based}; Node serves each request in an evented loop that can handle simultaneous requests.
|
|
\item Node is a platform for writing JavaScript applications outside web browser, and is therefore not quite the same as the JavaScript we are familiar with in web browser: there is no DOM built-in to Node, nor any other browser capability.
|
|
\item Node doesn't run in a GUI, but runs in the terminal or as a background process.
|
|
\end{itemize}
|
|
|
|
\begin{table}[H]
|
|
\centering
|
|
\begin{tabular}{|p{0.5\textwidth}|p{0.5\textwidth}|}
|
|
\hline
|
|
\textbf{Threads} & \textbf{Event-Driven} \\
|
|
\hline
|
|
Lock application / request with listener-workers threads. & Only one thread, which repeatedly fetches an event. \\
|
|
\hline
|
|
Uses incoming-request model. & Uses queue and then process it. \\
|
|
\hline
|
|
Multi-threaded server might block the request which might involve multiple events. & Manually saves the state and then goes on to process the next event. \\
|
|
\hline
|
|
Uses context switching. & No contention and no context switches.\\
|
|
\hline
|
|
Uses multi-threading environments where the listener \& worker threads are used frequently to take an incoming-request lock & Uses asynchronous I/O facilities (callbacks, nor poll/select or \verb|O_NONBLOCK| environments).\\
|
|
\hline
|
|
\end{tabular}
|
|
\caption{Threads versus asynchronous event-driven}
|
|
\end{table}
|
|
|
|
Ordinarily, a webserver waits for server-side I/O operations to complete while processing a web client request, thus \textbf{blocking} the next request to be processed.
|
|
Servers generally do nothing but I/O, and scripts waiting on I/O requests degrades performance.
|
|
Node processes each request as an event, it doesn't wait for the I/O operation to complete, making it \textbf{non-blocking}; it can therefore handle other requests at the same time.
|
|
When the I/O operation of the first request is completed, it will callback the server to complete the request.
|
|
To avoid blocking, Node makes use of the event-driven nature of JavaScript by attaching callbacks to I/O requests.
|
|
Scripts waiting on I/O waste no space because they get popped off the stack when their non-I/O related code finishes executing.
|
|
|
|
\subsection{MEAN}
|
|
\textbf{MEAN} is a full stack solution consisting of MongoDB, Express, Angular, \& node.
|
|
|
|
\begin{figure}[H]
|
|
\centering
|
|
\includegraphics[width=0.7\textwidth]{./images/mean.png}
|
|
\caption{ MEAN stack }
|
|
\end{figure}
|
|
|
|
\section{Virtualisation}
|
|
KVM stuff
|
|
\\\\
|
|
\textbf{QEMU (Quick Emulator)} is an open-source hosted hypervisor that performs hardware virtualisation.
|
|
It emulates CPUs through dynamic binary translation and provides a set of device models, enabling it to run a variety of unmodified guest operating systems.
|
|
It uses KVM Hosting mode in Proxmox where QEMU deals with the setting-up and migration of KVM images.
|
|
It is still involved in the emulation of hardware, but the execution of the guest is done by the KVM as requested by QEMU.
|
|
It uses the KVM to run virtual machines at near-native speed (requiring hardware virtualisation extensions on x86 machines).
|
|
When the target architecture is the same as the host architecture, QEMU can make use of KVM particular features, such as acceleration.
|
|
\\\\
|
|
\textbf{LXC (Linux Containers)} is an operating-system-level virtualisation method for running multiple isolated Linux systems (containers) on a control host using a single Linux kernel.
|
|
The Linux kernel provides the cgroups (control groups) functionality that allows limitation \& prioritisation of resources (CPU, memory, block I/O, network, etc.) without the need for starting any virtual machines.
|
|
It provides namespace isolation functionality that allows complete isolation of an application's view of the operating environment, including process tress, networking, user IDs, and mounted file systems.
|
|
LXC combines the kernel's cgroups and support for isolated namespaces to provide an isolated environment for applications.
|
|
Docker can also use LXC as one of its execution drivers, enabling image management and providing deployment services.
|
|
\\\\
|
|
\textbf{Ceph} is a storage platform that implements object storage on a single distributed computer cluster, and provides interfaces for object-level, block-level, \& file-level storage.
|
|
Ceph aims for completely distributed operation without a single point of failure, scalable to the exabyte level.
|
|
Ceph's software libraries provide client applications with direct access to the Reliable Autonomic Distributed Object Store (RADOS) object-based storage system.
|
|
Ceph replicates data and makes it fault-tolerant, using commodity hardware and requiring no specific hardware support.
|
|
As a result of its design, the system is both self-healing and self-managing, aiming to minimise administration time and other costs.
|
|
When an application writes data to Ceph using a block device, Ceph automatically striped and replicates the data across the cluster.
|
|
It works well with the KVM.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
\end{document}
|