我现在已经研究了微服务的概念,并了解它们是什么以及为什么它们是必要的.
快速复习
简而言之,monolith应用程序被分解为独立的可部署单元,每个单元通常公开它自己的Web API并拥有自己的数据库.每项服务都履行一项责任并做得很好.这些服务通过REST或SOAP等同步Web服务进行通信,或者使用JMS等异步消息传递来协同处理某些请求.我们的整体应用程序已成为一个分布式系统.通常,所有这些细粒度的API都可以通过API网关或代理提供,它充当单点入口外观,执行安全性和监视相关任务.
适应微服务的主要原因是高可用性,零停机更新和通过特定服务的水平扩展实现的高性能,以及系统中更松散的耦合,这意味着更容易维护.此外,IDE功能,构建和部署过程将显着加快,并且更容易更改框架甚至语言.
微服务与集群和容器化技术(如Docker)密切相关.每个微服务都可以打包为docker容器,以便在任何平台上运行它.集群的主要概念是服务发现,复制,负载平衡和容错.Docker Swarm是一个集群工具,它协调这些容器化服务,将它们粘合在一起,并以声明方式处理所有这些任务,保持集群的所需状态.
理论上听起来既简单又简单,但我仍然不明白如何在实践中实现这一点,即使我非常了解Docker Swarm.让我们看一个具体的例子.
这是个问题
我正在使用Spring Boot构建一个简单的java应用程序,由MySQL数据库支持.我想构建一个系统,用户从服务A获取网页并提交表单.服务A将对数据进行一些操作并将其发送到服务B,后者将进一步操作数据,写入数据库,返回一些内容,最后将一些响应发送回用户.
现在的问题是,服务A不知道在哪里可以找到服务B,也不是服务B知道在哪里可以找到数据库(因为他们可以在集群中的任何节点部署),所以我不知道我应该如何配置Spring启动应用程序.我想到的第一件事是使用DNS,但我找不到如何在docker swarm中设置这样一个系统的教程.在Spring中为分布式云部署配置连接参数的正确方法是什么?我已经研究过Spring Cloud项目,但不明白它是否是这种困境的关键.
我也很困惑应该如何部署数据库.他们是否应该居住在集群中,与服务一起部署(可能借助于docker compose),还是以更传统的方式使用固定IP进行管理?
最后一个问题是关于负载平衡.如果每个服务应该有多个负载平衡器,或者只有一个主负载均衡器,我会感到困惑.负载均衡器是否具有映射到域名的静态IP,并且所有用户请求都以此负载均衡器为目标?如果负载均衡器出现故障怎么办呢?它是否会尽一切努力来扩展服务毫无意义?是否有必要使用Docker Swarm设置负载均衡器,因为它有自己的路由网格?哪个节点最终用户应该定位?
如何调试clojure?是否有像Eclipse调试器这样的类似工具,或者我是否必须使用REPL和print语句来追踪错误?
如果后者,我怀疑功能范式的好处是否优先于原始/缺乏工具?毕竟,使Java如此优秀的原因不是语言,而是帮助编码,重构和调试的出色工具.只有clojure显示模糊的Java堆栈跟踪而不是翻译的错误消息以发现问题的事实让我趾高气扬.
我不禁得到clojure生态系统不完整的印象,并且在生产中使用它会比收益更麻烦.想象一下,一个新手调试了其他人编写的clojure中的错误,没有适当的工具来介入代码.
我真的想学习这门语言,希望我的印象是错误的.语法方面,语言因其简单性和一致性而感觉舒适.
如何组织像Java包一样的Angular 2 app文件夹结构?
考虑以下项目布局:
app
|_model
|_component
|_service
Run Code Online (Sandbox Code Playgroud)
我想进口foo.service.ts从服务到bar.component.ts的组件.但据我所知,Angular 2导入仅支持相对路径/../service/,这似乎是非常笨重的解决方案.
有没有办法从根文件夹中引用带绝对浴的文件夹,就像使用Java包一样?
是否允许在this.state.foo = "bar"不调用setState的情况下分配反应组件状态的单个变量?我需要在多个地方更改部分状态,并且我无法使用对象扩展运算符和Object.assign太冗长.如何在不重新定义整个州的情况下改变国家的一部分?
在微服务架构中(更确切地说,在诸如docker swarm之类的分布式环境中)部署数据库的最佳实践是什么?微服务原则指出,每个服务都应该是无状态的以实现扩展。由于数据库显然处于一种状态,因此它应该位于集群外部的固定位置,在初始化集群之前进行部署和配置吗?
我很困惑,因为所有docker compose示例都在服务定义中包括了数据库容器。但是事情并不是那么简单。在准备使用数据库之前,通常需要对其进行大量配置。此外,码头工人在协调服务启动顺序方面也很费力。
如果将数据库与服务一起部署到docker swarm确实是一个好习惯,那么如何确保关键数据的一致性和持久性?
从Java生成和使用外部进程的流(IO)的正确方法是什么?据我所知,由于可能有限的缓冲区大小,java端输入流(进程输出)应该在与生成进程输入并行的线程中使用.
但我不确定我是否最终需要与这些消费者线程同步,或者只是等待进程退出waitFor方法,以确保所有进程输出实际消耗?IE是否可能,即使进程退出(关闭它的输出流),流的java端仍然有未读数据?请问该怎么waitFor当这个过程完成居然连知道吗?对于有问题的过程,EOF(关闭它的输入流的java端)表示它退出.
我目前处理流的解决方案如下
public class Application {
private static final StringBuffer output = new StringBuffer();
private static final StringBuffer errOutput = new StringBuffer();
private static final CountDownLatch latch = new CountDownLatch(2);
public static void main(String[] args) throws IOException, InterruptedException {
Process exec = Runtime.getRuntime().exec("/bin/cat");
OutputStream procIn = exec.getOutputStream();
InputStream procOut = exec.getInputStream();
InputStream procErrOut = exec.getErrorStream();
new Thread(new StreamConsumer(procOut, output)).start();
new Thread(new StreamConsumer(procErrOut, errOutput)).start();
PrintWriter printWriter = new PrintWriter(procIn);
printWriter.print("hello world");
printWriter.flush();
printWriter.close();
int …Run Code Online (Sandbox Code Playgroud) 我正在学习Clojure宏,并想知道为什么我们不能只使用函数进行元编程.
据我所知,宏和函数之间的区别在于宏的参数没有被计算,而是作为数据结构和符号传递,而返回值被计算(在调用宏的地方).Macro作为读者和评估者之间的代理,在评估发生之前以任意方式转换表单.在内部,他们可以使用所有语言功能,包括函数,特殊形式,文字,递归,其他宏等.
功能正好相反.在调用之前计算参数,返回值之后不返回值.但宏和函数的镜像特性让我想知道,我们不能通过引用它们的参数(表单),转换表单,在函数内部进行评估,最终返回它的值来使用函数作为宏.这在逻辑上不会产生相同的结果吗?当然这会很不方便,但从理论上讲,每个可能的宏都有相同的功能吗?
这是简单的中缀宏
(defmacro infix
"translate infix notation to clojure form"
[form]
(list (second form) (first form) (last form)))
(infix (6 + 6)) ;-> 12
Run Code Online (Sandbox Code Playgroud)
这是使用函数的相同逻辑
(defn infix-fn
"infix using a function"
[form]
((eval (second form)) (eval (first form)) (eval (last form))))
(infix-fn '(6 + 6)) ;-> 12
Run Code Online (Sandbox Code Playgroud)
现在,这种看法是否适用于所有情况,还是存在一些宏观无法超越的极端情况?最后,宏只是函数调用的语法糖吗?
我有以下docker-compose文件
version: '3'
services:
node1:
build: node1
container_name: node1
node2:
build: node2
container_name: node2
Run Code Online (Sandbox Code Playgroud)
这是node1的Dockerfile
FROM ubuntu
RUN apt-get update && apt-get install -y iputils-ping
COPY true.sh /var/
CMD ["/var/true.sh"]
Run Code Online (Sandbox Code Playgroud)
node2 Dockerfile 扩展 node1 如下
FROM node1
RUN apt-get update && apt-get install -y iputils-ping
COPY true.sh /var/
CMD ["/var/true.sh"]
Run Code Online (Sandbox Code Playgroud)
现在,当我使用 构建图像时docker-compose up -d --build,最初是空的本地图像存储库,我收到以下错误
ERROR: Service 'node2' failed to build: pull access denied for node1, repository does not exist or may require 'docker login'
Run Code Online (Sandbox Code Playgroud)
使用 …
我使用 Create-react-app 和npm start命令在开发服务器中为我的应用程序提供服务。默认情况下,应用程序由https://localhost:3000/提供服务。然而,我的应用程序使用需要特定上下文路径的cookie。如何从https://localhost:3000/app/提供应用程序?
在 GitLab 中似乎有某种构建缓存。
例如,我有一份构建和标记 docker 镜像的工作。作业成功并且构建日志看起来正常,但图像实际上并未在运行程序中创建。文件也是如此:写入文件,作业完成后该文件不存在。我怀疑构建使用了某种缓存,因为它在这些场景中执行得如此之快。
这种行为似乎最常出现在分离管道、标记管道以及管道通常通过不同引用指向相同提交时。
如何禁用作业缓存并强制发生副作用?
continuous-integration caching build continuous-delivery gitlab