当前位置: 首页 > 编程日记 > 正文

scala akka_如何对Scala和Akka HTTP应用程序进行Docker化-简单的方法

scala akka

by Miguel Lopez

由Miguel Lopez

如何对Scala和Akka HTTP应用程序进行Docker化-简单的方法 (How to Dockerise a Scala and Akka HTTP Application — the easy way)

Using Docker is a given nowadays. In this tutorial we will how to learn to dockerise our Scala and Akka HTTP applications without even creating a Dockerfile ourselves.

如今已经可以使用Docker。 在本教程中,我们将学习如何在自己甚至创建Dockerfile的情况下对Scala和Akka HTTP应用程序进行 Docker化。

For the purposes of this tutorial, we assume Docker is already installed on the machine. If it isn’t, please follow the official documentation.

就本教程而言,我们假设Docker已经安装在机器上。 如果不是,请遵循官方文档 。

To automate the creation of the Dockerfile for our project, we will use the sbt-native-packager plugin.

为了自动为我们的项目创建Dockerfile,我们将使用sbt-native-packager插件。

You can use any Scala or Akka HTTP project for this tutorial. We will be using the following repository, feel free to clone it and make sure to checkout the branch 6.5-testing-directives.

您可以在本教程中使用任何Scala或Akka HTTP项目。 我们将使用以下存储库 ,随时克隆它,并确保签出6.5-testing-directives分支。

添加插件 (Adding the plugin)

First, we need to add the plugin to our project in the project/plugins.sbt file. If the file doesn't exist, we need to create it, and then add the following line:

首先,我们需要在project/plugins.sbt文件中将插件添加到我们的项目中。 如果文件不存在,我们需要创建它,然后添加以下行:

addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.3.6")

Then we need to enable the plugin in our build.sbt file. Add the following line at the top:

然后,我们需要在build.sbt文件中启用该插件。 在顶部添加以下行:

enablePlugins(JavaAppPackaging)

Enabling this plugin also allows us to create an executable for our application. Run sbt stage in the project's root directory.

启用此插件还允许我们为应用程序创建可执行文件。 在项目的根目录中运行sbt stage

Now we can execute our application by running ./target/universal/stage/bin/akkahttp-quickstart. You should see a Success! message. If you send a GET request to localhost:9000/todos you'll get a couple of todos.

现在,我们可以通过运行./target/universal/stage/bin/akkahttp-quickstart来执行我们的应用程序。 您应该会看到Success! 信息。 如果您将GET请求发送到localhost:9000/todos您将获得几个待办事项。

Docker化我们的应用程序 (Dockerising our application)

It’s time to start toying around with Docker.

现在是时候开始研究Docker了。

Let’s start by generating the Dockerfile for our application. Run sbt docker:stage, then run cat target/docker/stage/Dockerfile to see its contents:

让我们从为我们的应用程序生成Dockerfile开始。 运行sbt docker:stage ,然后运行cat target/docker/stage/Dockerfile查看其内容:

FROM openjdk:latestWORKDIR /opt/dockerADD --chown=daemon:daemon opt /optUSER daemonENTRYPOINT ["/opt/docker/bin/akkahttp-quickstart"]CMD []

It’s quite simple. It ends up running a similar binary to the one we generated and ran earlier.

这很简单。 它最终运行与我们生成并运行较早的二进制文件相似的二进制文件。

We can build a Docker image using that Dockerfile manually, but there’s a more convenient way of doing so. Let’s run sbt docker:publishLocal. As its name suggests, it will publish a Docker image of our application to our local registry.

我们可以手动使用该Dockerfile来构建Docker映像,但是有一种更方便的方法。 让我们运行sbt docker:publishLocal. 顾名思义,它将把我们的应用程序的Docker映像发布到我们的本地注册表。

Run docker images and you should see the following entry:

运行docker images ,您应该看到以下条目:

REPOSITORY            TAG     IMAGE ID       CREATED          SIZEakkahttp-quickstart   0.1     d03732dd0854   42 seconds ago   774MB

We can now run our application using Docker.

现在,我们可以使用Docker运行我们的应用程序。

Run docker run akkahttp-quickstart:0.1, you should see the Success! message once again.

运行docker run akkahttp-quickstart:0.1 ,您应该会看到Success! 消息再次。

But this time, if we try to query our application we’ll get an error:

但是这一次,如果我们尝试查询我们的应用程序,将会得到一个错误:

Let’s run docker ps to get some information about our running Docker process (output abbreviated):

让我们运行docker ps以获得一些有关我们正在运行的Docker进程的信息(输出缩写):

CONTAINER ID     IMAGE                       PORTS            NAMES9746162d4723     akkahttp-quickstart:0.1                      serene_agnesi

As we can see, there are no ports exposed, so there’s no way to communicate with our application.

如我们所见,没有暴露的端口,因此无法与我们的应用程序进行通信。

Applications in Docker run in their network by default. There are multiple ways to allow communication between Docker processes and the host machine. The simplest way is to expose a port.

Docker中的应用程序默认在其网络中运行。 有多种方法可以允许Docker进程与主机之间进行通信。 最简单的方法是公开端口。

Stop the running application, either by hitting Ctrl-C or by running docker stop $CONTAINER_ID.

通过Ctrl-C或运行docker stop $CONTAINER_ID停止正在运行的应用程序。

This time when we run it, we’ll expose the respective port as well:

这次运行它时,我们还将公开相应的端口:

docker run -p 9000:9000 akkahttp-quickstart:0.1

We’re now able to query our dockerised application:

现在,我们可以查询我们的dockerized应用程序:

自定义我们的设置 (Customising our setup)

There are several things that we might want to do with the current setup we have:

对于当前的设置,我们可能需要做几件事:

  • What if we want a different image name?

    如果我们想要一个不同的图像名称怎么办?
  • What if we want to use a different port?

    如果我们想使用其他端口怎么办?
  • Can we have a lighter image?

    我们可以得到一个较浅的图像吗?

Let’s explore these common use cases.

让我们探索这些常见的用例。

更改图像名称 (Changing the image name)

If we look into the plugin’s official documentation, we see that there are a number of options we can change.

如果我们查看插件的官方文档 ,我们会发现可以更改许多选项。

Give it a read and see what else you can customise.

读一读,看看还能自定义什么。

To change the image name we can modify the packageName property in our build.sbt file, add the following line after the scalaVersion property:

要更改映像名称,我们可以在build.sbt文件中修改packageName属性,在scalaVersion属性之后添加以下行:

packageName in Docker := "dockerised-akka-http"

Let’s publish the image again. Run sbt docker:publishLocal. We can check that we have a new image by running docker images:

让我们再次发布图像。 运行sbt docker:publishLocal 。 我们可以通过运行docker images来检查是否有新映像:

REPOSITORY            TAG   IMAGE ID       CREATED          SIZE akkahttp-quickstart   0.1   d03732dd0854   42 minutes ago   774MB dockerised-akka-http  0.1   d03732dd0854   42 minutes ago   774MB

Now we have two images, the original one and the new one. Awesome!

现在我们有两个图像,原始图像和新图像。 太棒了!

更改端口 (Changing the port)

We can’t change the port that our application is listening to without making code changes. The port is hardcoded in our application. Ideally, we would read it from an environment variable and maybe have one as default.

如果不进行代码更改,就无法更改应用程序正在侦听的端口。 该端口在我们的应用程序中进行了硬编码。 理想情况下,我们将从环境变量中读取它,并且可能将其作为默认值。

But that’s okay. Because our application is running in a different network, we can map a different port to the internal 9000 port.

但是没关系。 因为我们的应用程序在不同的网络中运行,所以我们可以将不同的端口映射到内部9000端口。

When we specify the flag -p 9000:9000 we are saying that the port 9000 in the host machine will map to the port 9000 in our process' network. Let's try changing that.

当我们指定标志-p 9000:9000 ,就是说主机中的端口9000将映射到我们进程的网络中的端口9000。 让我们尝试更改它。

Run docker run -p 5000:9000 dockerised-akka-http:0.1 to run our new image with a different port.

运行docker run -p 5000:9000 dockerised-akka-http:0.1以使用其他端口运行我们的新映像。

We can query the todos to make sure it works as expected:

我们可以查询todos以确保它能按预期工作:

使我们的图像更亮 (Making our image lighter)

For our last experiment, we will try to make our image lighter. At this point it uses over 700MB.

对于我们的上一个实验,我们将尝试使图像更亮。 此时,它使用了700MB以上。

First, let’s increase the version so we get a different tag and can compare them. Then add dockerBaseImage := "openjdk:8-jre-alpine" above where we change the packageName . Our build.sbt now looks like:

首先,让我们增加版本,以便获得一个不同的标签并可以对其进行比较。 然后在我们更改packageName上方添加dockerBaseImage := "openjdk:8-jre-alpine" 。 我们的build.sbt现在看起来像:

enablePlugins(JavaAppPackaging)
name := "akkahttp-quickstart"version := "0.2"scalaVersion := "2.12.6"
dockerBaseImage := "openjdk:8-jre-alpine"packageName in Docker := "dockerised-akka-http"
val akkaVersion = "2.5.13"val akkaHttpVersion = "10.1.3"val circeVersion = "0.9.3"
libraryDependencies ++= Seq(  "com.typesafe.akka" %% "akka-actor" % akkaVersion,  "com.typesafe.akka" %% "akka-testkit" % akkaVersion % Test,  "com.typesafe.akka" %% "akka-stream" % akkaVersion,  "com.typesafe.akka" %% "akka-stream-testkit" % akkaVersion % Test,  "com.typesafe.akka" %% "akka-http" % akkaHttpVersion,  "com.typesafe.akka" %% "akka-http-testkit" % akkaHttpVersion % Test,  "io.circe" %% "circe-core" % circeVersion,  "io.circe" %% "circe-generic" % circeVersion,  "io.circe" %% "circe-parser" % circeVersion,  "de.heikoseeberger" %% "akka-http-circe" % "1.21.0",  "org.scalatest" %% "scalatest" % "3.0.5" % Test)

We are using a different tag of the openjdk base image to specify that we want to use alpine, which is a lightweight Linux distribution.

我们使用openjdk基本映像的不同标记来指定我们要使用alpine ,这是轻量级的Linux发行版。

Publish the image by running sbt docker:publishLocal. Get the images with docker images . We can see that the image is lighter now:

通过运行sbt docker:publishLocal发布映像。 使用docker images获取docker images 。 我们可以看到图像现在变亮了:

REPOSITORY             TAG   IMAGE ID       CREATED          SIZE dockerised-akka-http   0.2   4688366e70bb   32 seconds ago   119MB akkahttp-quickstart    0.1   d03732dd0854   2 hours ago      774MBdockerised-akka-http   0.1   d03732dd0854   2 hours ago      774MB

Let’s make sure that it still works.

让我们确保它仍然有效。

Run docker run -p 5000:9000 dockerised-akka-http:0.2, minding the tag number. It's not working, ad we get the following error:

运行docker run -p 5000:9000 dockerised-akka-http:0.2 ,注意标记号。 它不起作用,并且出现以下错误:

env: can't execute 'bash': No such file or directory

Apparently, our dockerised application needs bash to run. Reading the plugin’s documentation, we can tell that it generates a bash script that executes our application.

显然,我们的dockerized应用程序需要运行bash 。 阅读插件的文档 ,我们可以知道它生成了一个执行我们的应用程序的bash脚本。

So let’s install bash in our image and try again.

因此,让我们在映像中安装bash并重试。

Add the following lines below where we change the packageName in our build.sbt file:

在更改build.sbt文件中的packageName位置以下添加以下行:

import com.typesafe.sbt.packager.docker._dockerCommands ++= Seq(  Cmd("USER", "root"),  ExecCmd("RUN", "apk", "add", "--no-cache", "bash"))

We are adding some extra commands to our Dockefile. We are changing the user to root to install the package, and then we install bash.

我们在Dockefile中添加了一些额外的命令。 我们将用户更改为root来安装软件包,然后安装bash。

Let’s try running the application again, docker run -p 5000:9000 dockerised-akka-http:0.2. And it's working now, great!

让我们尝试再次运行该应用程序, docker run -p 5000:9000 dockerised-akka-http:0.2 。 现在就可以了,太好了!

If we check the images again, the alpine-based one is a bit bigger, like 10MB. That’s nothing compared to the roughly 770MB of the others.

如果我们再次检查图像,则基于阿尔卑斯的图像会更大一些,例如10MB。 与其他大约770MB的存储空间相比,这没什么。

Installing bash in alpine isn’t the worst thing in the world. Some people end up adding it anyway due to their preference and for debugging.

高山上安装bash并不是世界上最糟糕的事情。 某些人由于偏好和调试而最终还是添加了它。

生成与Ash兼容的可执行文件 (Generating an Ash-compatible executable)

Installing bash on our image is a bit of a workaround. Let’s use an additional plugin to generate an executable that is compatible with Alpine. Thanks to Muki Seller for letting us know about this solution!

在我们的映像上安装bash有点解决方法。 让我们使用一个附加插件来生成与Alpine兼容的可执行文件。 感谢Muki Seller让我们知道此解决方案!

According to the official documentation, we need to enable the extra plugin AshScriptPlugin.

根据官方文档 ,我们需要启用额外的插件AshScriptPlugin

Modify the build.sbt file to enable both plugins, and remove the previous workaround:

修改build.sbt文件以启用两个插件,并删除以前的解决方法:

enablePlugins(JavaAppPackaging, AshScriptPlugin)
name := "akkahttp-quickstart"version := "0.3"scalaVersion := "2.12.6"
dockerBaseImage := "openjdk:8-jre-alpine"packageName in Docker := "dockerised-akka-http"
val akkaVersion = "2.5.13"val akkaHttpVersion = "10.1.3"val circeVersion = "0.9.3"
libraryDependencies ++= Seq(  "com.typesafe.akka" %% "akka-actor" % akkaVersion,  "com.typesafe.akka" %% "akka-testkit" % akkaVersion % Test,  "com.typesafe.akka" %% "akka-stream" % akkaVersion,  "com.typesafe.akka" %% "akka-stream-testkit" % akkaVersion % Test,  "com.typesafe.akka" %% "akka-http" % akkaHttpVersion,  "com.typesafe.akka" %% "akka-http-testkit" % akkaHttpVersion % Test,
"io.circe" %% "circe-core" % circeVersion,  "io.circe" %% "circe-generic" % circeVersion,  "io.circe" %% "circe-parser" % circeVersion,  "de.heikoseeberger" %% "akka-http-circe" % "1.21.0",
"org.scalatest" %% "scalatest" % "3.0.5" % Test)

We also increased the version so we can compare and avoid overriding the previous one.

我们还增加了版本,以便我们可以比较并避免覆盖上一个版本。

Run sbt docker:publishLocal, and then docker run dockerised-akka-http:0.3.

运行sbt docker:publishLocal ,然后docker run dockerised-akka-http:0.3

You should see the success message and, if you query for the todos, you should see them as well. Great!

您应该看到成功消息,并且,如果您查询待办事项,那么您也应该看到它们。 大!

结论 (Conclusion)

In this tutorial we dockerised a Scala and Akka HTTP application. There was nothing done specifically for this application which means that the setup will work pretty much as it is.

在本教程中,我们泊坞了Scala和Akka HTTP应用程序。 没有为该应用程序专门做任何事情,这意味着安装程序将按原样工作。

Then we looked at how to accomplish some common use cases by customising our Dockerfile through the plugin.

然后,我们研究了如何通过插件自定义Dockerfile来完成一些常见用例。

We even managed to reduce the image size by nearly seven times!

我们甚至设法将图像尺寸减小了近七倍!

Amazing, isn’t it?

太神奇了,不是吗?

If you liked this tutorial and want to learn how to build an API for a todo application, check out our new free course! ???

如果您喜欢本教程,并且想学习如何为todo应用程序构建API,请查看我们的新免费课程 ! ???

Originally published at www.codemunity.io.

最初在www.codemunity.io上发布。

翻译自: https://www.freecodecamp.org/news/how-to-dockerise-a-scala-and-akka-http-application-the-easy-way-23310fc880fa/

scala akka

相关文章:

Freemarker详细解释

A概念 最经常使用的概念1、 scalars&#xff1a;存储单值字符串&#xff1a;简单文本由单或双引號括起来。数字&#xff1a;直接使用数值。日期&#xff1a;通常从数据模型获得布尔值&#xff1a;true或false&#xff0c;通常在<#if …>标记中使用2、 hashes&#xff1a;…

洛谷P1057 传球游戏(记忆化搜索)

点我进入题目题目大意&#xff1a;n个小孩围一圈传球&#xff0c;每个人可以给左边的人或右边的人传球&#xff0c;1号小孩开始&#xff0c;一共传m次&#xff0c;请问有多少种可能的路径使球回到1号小孩。 输入输出&#xff1a;输入n&#xff0c;m&#xff0c;输出路径的数量。…

微信小程序 自定义导航栏,只保留右上角胶囊按钮

微信小程序开发交流qq群 173683895 承接微信小程序开发。扫码加微信。 navigationStyle 导航栏样式&#xff0c;仅支持以下值&#xff1a;default 默认样式custom 自定义导航栏&#xff0c;只保留右上角胶囊按钮 在 app.json 的 window 加上 "navigationStyle":…

azure多功能成像好用吗_如何使用Azure功能处理高吞吐量消息

azure多功能成像好用吗Authored with Steef-Jan Wiggers, Azure MVP.由Azure MVP Steef-Jan Wiggers撰写。 With Microsoft Azure, customers will push all types of workloads to its services. Workloads are ranging from datasets for Machine Learning purposes to a la…

document.all使用

document.all 一个. document.all它是在页面中的所有元素的集合。例如&#xff1a; document.all(0)一个元素 二. document.all能够推断浏览器是否是IE if(document.all) { alert("is IE!"); } 三. 也能够通过给某个元素设置id属性&#xff08;id…

微信小程序动画无限循环 掉花

微信小程序开发交流qq群 173683895 承接微信小程序开发。扫码加微信。 动画效果 源码 <!-- 动画 --><block wx:if"{{donghua}}"><view classdonghua><image bindtaphua styleleft:{{left1}}px animation"{{animationData1}}" clas…

程序员远程办公_如何从办公室变成远程程序员

程序员远程办公by James Quinlan詹姆斯昆兰(James Quinlan) My name is James, and I’m a Software Engineer at a company called Yesware, based in Boston. Yesware is the fourth job I’ve had in which I’m paid to write code, but it’s the third time now that I’…

从头学起androidlt;AutoCompleteTextView文章提示文本框.十九.gt;

文章提示可以很好的帮助用户输入信息&#xff0c;以方便。在Android它也设置有类似特征&#xff0c;而要实现这个功能需要依靠android.widget.AutoCompleteTextView完毕&#xff0c;此类的继承结构例如以下&#xff1a; java.lang.Object↳ android.view.View↳ android.widget…

微信小程序动态设置 tabBar

微信小程序开发交流qq群 173683895 承接微信小程序开发。扫码加微信。 使用微信提供的API wx.setTabBarItem(Object object) 动态设置 tabBar 某一项的内容 参数 Object object 属性类型默认值必填说明indexnumber 是tabBar 的哪一项&#xff0c;从左边算起textstring 否…

NodeJS入门--环境搭建 IntelliJ IDEA

NodeJS入门–环境搭建 IntelliJ IDEA 本人也刚开始学习NodeJS&#xff0c;所以以此做个笔记&#xff0c;欢迎大家提出意见。 1、首先 下载安装NodeJS&#xff0c;下载安装IntelliJ IDEA2、接下来我们详细介绍在IDEA中配置NodeJS 默认安装好了IDEA&#xff0c;在IDEA的file ->…

如何使用React.js和Heroku快速实现从想法到URL的转变

by Tom Schweers由汤姆史威士(Tom Schweers) 如何使用React.js和Heroku快速实现从想法到URL的转变 (How to go from idea to URL quickly with React.js and Heroku) When I was first starting out as a developer, the one thing that I wanted to do was get a web applica…

F - Count the Colors - zoj 1610(区间覆盖)

有一块很长的画布&#xff0c;现在想在这块画布上画一些颜色&#xff0c;不过后面画的颜色会把前面画的颜色覆盖掉&#xff0c;现在想知道画完后这块画布的颜色分布&#xff0c;比如 1号颜色有几块&#xff0c;2号颜色有几块。。。。*****************************************…

小程序弹窗并移动放大图片的动画效果

微信小程序开发交流qq群 173683895 承接微信小程序开发。扫码加微信。 效果图 触发条件 <block wx:if{{bg_hui_show}}> <view classbg_hui catchtaphide_bg_hui></view> <image classanimation animationData1 bindtapto_hed mode"widthFix&quo…

代码片段管理工具_VS代码片段:提高编码效率的最强大工具

代码片段管理工具by Sam Williams通过山姆威廉姆斯 VS代码片段&#xff1a;提高编码效率的最强大工具 (VS Code snippets: the most powerful tool to boost your coding productivity) 用更少的按键编写更多的代码 (Write more code with fewer keystrokes) Everyone wants t…

我的C++笔记(数据的共享与保护)

*数据的共享与保护&#xff1a; * 1.作用域&#xff1a; * 作用域是一个标识符在程序正文中有效的区域。C中标识符的作用域有函数原型作用域、局部作用域(块作用域)、类作用域和命名空间作用域。 * (1).函数原型作用域&#xff1a; * 函数原型作用域是C中最小的作用域&#xff…

最新Java中Date类型详解

一、Date类型的初始化 1、 Date(int year, int month, int date); 直接写入年份是得不到正确的结果的。 因为java中Date是从1900年开始算的&#xff0c;所以前面的第一个参数只要填入从1900年后过了多少年就是你想要得到的年份。 月需要减1&#xff0c;日可以直接插入。 这种方…

ES6 常用的特性整理

微信小程序开发交流qq群 173683895 承接微信小程序开发。扫码加微信。 1.默认参数 2.模板对象-反引号 3.多行字符串-反引号 4.解构赋值-对象&#xff0c;数组 5.增强的对象字面量- 直接给对象里面的属性赋值给变量 6.给对象的属性赋值的时候可以直接给一个参数&#xf…

crontab 最小间隔_今天我间隔了:如何找到不在数组中的最小数字

crontab 最小间隔by Marin Abernethy通过Marin Abernethy 今天我间隔了&#xff1a;如何找到不在数组中的最小数字 (Today I Spaced: how to find the smallest number that is not in the array) TIS在我的第一次技术采访中。 这是我学到的。 (TIS in my first technical int…

计算起点地址和终点地址的最短驾车距离和驾车时间

微信小程序开发交流qq群 173683895 承接微信小程序开发。扫码加微信。 需求&#xff1a; 在一个excel的xlsx表格中有很多起点的地址和终点的地址&#xff0c;要批量计算两个地址之间的距离和驾车时间&#xff0c;按照百度地图的最短距离计算。最后把得出的行驶距离和驾车时…

jmeter测试工具

jmeter的下载&#xff1a; http://jmeter.apache.org/download_jmeter.cgi 1.打开链接选择 Binaries 下.zip下载 下载完后解压 2.然后再下载java中jdk, 配置java的环境变量 JAVA_HOME 和path JAVA_HOME值中加jdk的安装目录 path后面加;%JAVA_HOME%\bin; 3.在jmeter解压目录中…

余数定理_如何用Java实现余数定理

余数定理by Anuj Pahade由Anuj Pahade 如何用Java实现余数定理 (How to implement the Chinese Remainder Theorem in Java) This post assumes that you know what Chinese Remainder Theorem (CRT) is and focuses on its implementation in Java. If you don’t, I’d reco…

C#如何根据DataTable生成泛型List或者动态类型list

背景&#xff1a;在项目中&#xff0c;sql语句检索返回DataTable&#xff0c;然后根据检索结果做进一步的操作&#xff0c;本篇文章即是介绍如何将DataTable快速生成泛型List返回。 假设存在如下学生类&#xff1a; 1 public class student 2 { 3 public int I…

Easyui combobox下拉框默认选中第一项

var val $(#cc).combobox("getData");for (var item in val[0]) { if (item "groupName") { $(this).combobox("select", val[0][item]); }}转载于:https://www.cnblogs.com/AmbiguousMiao/p/7094589.html

js 获取当前时间 随记

微信小程序开发交流qq群 581478349 承接微信小程序开发。扫码加微信。 获取当前时间 new Date().toTimeString().split( )[0];console.log(dete, date) //dete 11:39:46

使用Typescript的巧妙React上下文技巧-不是Redux

by Bill Girten比尔吉尔滕(Bill Girten) 使用Typescript的巧妙React上下文技巧- 不是 Redux (Clever React context tricks using Typescript — not Redux) by Bill Girten, Martin Maza, and Alison Stuart由Bill Girten &#xff0c;Martin Maza和Alison Stuart 撰写 TLDR…

vagrant 介绍,安装与使用

可以帮你统一团队成员的开发环境。如果你或者你的伙伴创建了一个Vagrantfile&#xff0c;那么你只需要执行vagrant up就行了&#xff0c;所有的软件都会安装并且配置好。团队成员可以通过相同的Vagrantfile来创建他们的开发环境&#xff0c;无论他们是在Linux, Mac OS X, 或者W…

HTML元素的基本特性

1&#xff0c;Disabled 特性&#xff1a; 1 //Disabled 设置元素不可用&#xff1a; 2 3 $(this).attr("disabled","disabled") 4 5 //移除push元素的diasble特性&#xff1a; 6 7 $("#push").removeAttr(disabled) 2&#xff0c;z-index 特性…

js base64 解码

微信小程序开发交流qq群 173683895 承接微信小程序开发。扫码加微信。 解码函数 function base64_decode (input) { // 解码&#xff0c;配合decodeURIComponent使用var base64EncodeChars "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789/";…

esl8266开发之旅_从ESL老师到越南软件开发人员的旅程

esl8266开发之旅by alberto montalesi通过阿尔贝托蒙塔莱西 从ESL老师到越南软件开发人员的旅程 (My Journey from an ESL Teacher to Software Developer in Vietnam) 介绍 (Introduction) Hi, my name is Alberto, and this is the story of how I learned to code, wrote a…

洛谷P2429 制杖题 [2017年6月计划 数论10]

P2429 制杖题 题目描述 求不大于 m 的、 质因数集与给定质数集有交集的自然数之和。 输入输出格式 输入格式&#xff1a;第一行二个整数 n&#xff0c;m。 第二行 n 个整数&#xff0c;表示质数集内的元素 p[i]。 输出格式&#xff1a;一个整数&#xff0c;表示答案&#xff0c…