azure服务器

It’s 2018 and I just wrote a title that contains the words “Serverless server”. Life has no meaning.

那是2018年,我刚刚写了一个标题,其中包含“无服务器服务器”一词。 生活没有意义。

Despite that utterly contradictory headline, in this article we’re going to explore a pretty nifty way to exploit SendGrid’s template functionality using Timer Triggers in Azure Functions to send out scheduled tabular reports. We are doing this because that’s what everyone wants in their inbox. A report. With numbers in it. And preferably some acronyms.

尽管标题完全矛盾,但在本文中,我们将探索一种非常漂亮的方法,即使用Azure Functions中的计时器触发器来利用SendGrid的模板功能来发送计划的表格报表。 我们这样做是因为每个人都希望在收件箱中。 一份报告。 里面有数字。 并且最好是一些缩写。

库存SKU报告 (The Inventory SKU Report)

First, let’s straw-man this project with a contrived application that looks sufficiently boring enough to warrant a report. I have just the thing. A site where we can adjust inventory levels. The word “inventory” is just begging for a report.

首先,让我们用一个人为设计的应用程序来研究这个项目,它看起来足够无聊,足以保证报告。 我有东西。 我们可以调整库存水平的站点。 “库存”一词只是乞求一份报告。

This application allows you to adjust the inventory quantity (last column). Let’s say that an executive somewhere has requested that we email them a report every night that contains a list of every SKU altered in the last 24 hours. Because of course, they would ask for that. In fact, I could swear I’ve built this report in real life in a past job. Or there’s a glitch in the matrix. Either way, we’re doing this.

此应用程序允许您调整库存数量(最后一列)。 假设某位高管要求我们每晚向他们发送一份报告,其中包含过去24小时内更改的每个SKU的列表。 当然,他们会要求这样做。 实际上,我可以保证我在过去的工作中已经在现实生活中构建了此报告。 或矩阵中出现故障。 无论哪种方式,我们都在这样做。

Here is what we’re going to be building…

这就是我们将要建造的……

Normally the way you would build this is with some sort of report server. Something like SQL Server Reporting Services or Business Objects or whatever other report servers are out there. Honestly, I don’t want to know. But if you don’t have a report server, this gets kind of tedious.

通常,构建此报表的方式是使用某种报表服务器。 诸如SQL Server报表服务或业务对象之类的东西或其他任何报表服务器都在那儿。 老实说,我不想知道。 但是,如果您没有报表服务器,这将变得很乏味。

Let’s go over what you have to do to make this happen…

让我们回顾一下实现此目标所需要做的工作……

  1. Run a job on some sort of timer (cron job)
    在某种计时器上运行作业(定时作业)
  2. Query a database
    查询数据库
  3. Iterate over records and format them for output to the screen
    遍历记录并将其格式化以输出到屏幕
  4. Email said report
    电子邮件说报告
  5. Update your resume and contact recruiters
    更新您的简历并联系招聘人员

This is the kind of thing that nobody wants to do. But I think this project can be a lot of fun, and we can use some interesting technology to pull it off. Starting with Serverless.

这是没人愿意做的事情。 但是我认为这个项目可能会很有趣,我们可以使用一些有趣的技术来实现它。 从无服务器开始。

无服务器计时器功能 (Serverless timer functions)

Serverless is a really good use case for one-off requests like this. In this case, we can use Azure Functions to create a Timer Trigger function.

对于这样的一次性请求,无服务器是一个非常好的用例。 在这种情况下,我们可以使用Azure Functions创建一个Timer Trigger函数。

To do that, I’m going to use the Azure Functions extension for VS Code. I’m going to use it for everything in fact. Why? Because I don’t know you, but I do know it’s highly likely that you are using VS Code. VS Code is great because it’s like a movie that all developer’s can universally agree is completely awesome. Sort of the opposite of “Children of Men”. That movie was terrible and you know it.

为此,我将对VS Code使用Azure Functions扩展。 实际上,我将用它来做所有事情。 为什么? 因为我不认识您,但我确实知道您很有可能正在使用VS Code。 VS Code很棒,因为它就像一部电影,所有开发人员都可以普遍认为这是一部很棒的电影。 有点像“男人的孩子”。 那部电影太可怕了,你知道的。

Make sure you install the Azure Functions extension.

确保安装Azure Functions扩展。

Azure Functions - Visual Studio MarketplaceExtension for Visual Studio Code - An Azure Functions extension for Visual Studio Code.marketplace.visualstudio.com

Azure功能 -Visual Studio代码的 Visual Studio市场 扩展-Visual Studio代码的Azure函数扩展。 marketplace.visualstudio.com

Now create a new Function App from within VS Code.

现在,从VS Code中创建一个新的Function App。

Then create a new Timer Trigger function. Timer Trigger functions are scheduled using standard Cron Expressions. You have likely not ever seen before because I had not seen one until a few months ago. And I’ve been in this industry for a LONG time. I am old, father William.

然后创建一个新的计时器触发功能。 计时器触发功能是使用标准Cron表达式安排的。 您可能以前从未见过,因为几个月前我才见过。 我在这个行业工作了很长时间。 我老了,父亲威廉。

Cron expressions look kind of scary cause they have asterisks in them. In the case below, I’m saying that when minutes is 0 and seconds is 0 and hours is evenly divisible by 24, fire the function. This would be midnight.

Cron表达式看起来有点吓人,因为它们中带有星号。 在以下情况下,我要说的是,当分钟为0且秒为0且小时可以被24整除时,触发该函数。 这将是午夜。

Now we can run this locally (F5). We’ll see in the embedded terminal the schedule on which our Function will be called; the next 5 occurrences.

现在我们可以在本地运行它(F5)。 我们将在嵌入式终端中看到将调用我们的Function的时间表; 接下来的5次。

It feels good, man.

感觉很好,伙计。

OK, now we need to get some data. I’m not going to drag you into the specifics of me querying SQL Server from this function because that’s not what this article is about, but here’s the code anyway.

好的,现在我们需要获取一些数据。 我不会把您拖到从该函数查询SQL Server的细节中,因为这与本文无关,但无论如何这里都是代码。

const { Connection, Request } = require('tedious');const options = {weekday: 'long',year: 'numeric',month: 'long',day: 'numeric'
};const config = {userName: process.env.SQL_USERNAME,password: process.env.SQL_PASSWORD,server: process.env.SQL_SERVER,options: {encrypt: true,database: process.env.SQL_DATABASE}
};module.exports = function(context, myTimer) {getChangedSkus().then(data => {if (data.length > 0) {sendEmail(context, data);} else {context.done();}}).catch(err => {context.log(`ERROR: ${err}`);});
};/*** Executes a query against the database for SKU's changed in the last 24 hours* @returns {Promise} Promise object contains result of query*/
function getChangedSkus() {return new Promise((resolve, reject) => {const connection = new Connection(config);const query = `SELECT Sku, Quantity, CONVERT(varchar, Modified, 0) as ModifiedFROM InventoryWHERE Modified >= dateadd(day, -1, getdate())`;connection.on('connect', err => {if (err) reject(err);let request = new Request(query, err => {if (err) {reject(err);}});const results = [];request.on('row', columns => {let result = {};columns.forEach(column => {result[column.metadata.colName] = column.value;});results.push(result);});request.on('doneProc', (rowCount, more) => {resolve(results);});connection.execSql(request);});});
}

I’m connecting to the database, doing a simple query and….wait a minute…did not I say I wasn’t going to get into specifics? You had me there for a minute, but I’m onto your game!

我正在连接到数据库,进行简单的查询,然后……等一下……不是我说我打算讲细节吗? 你在那儿呆了我一分钟,但是我正在玩你的游戏!

So this pulls in data and we get it in a JavaScript object that we can pass as JSON. If we were to JSON.stringify this, we will see the data set that we need to send in the report.

因此,这会提取数据,并将其获取到我们可以作为JSON传递JavaScript对象中。 如果要使用JSON.stringify ,我们将在报告中看到需要发送的数据集。

[{ "Sku": "1", "Quantity": 65, "Modified": "Nov  6 2018 10:14PM" },{ "Sku": "10", "Quantity": 89, "Modified": "Nov  2 2018  8:18PM" },{ "Sku": "11", "Quantity": 39, "Modified": "Nov  2 2018  8:18PM" },{ "Sku": "12", "Quantity": 2, "Modified": "Nov  2 2018  8:18PM" },{ "Sku": "13", "Quantity": 75, "Modified": "Nov  2 2018  8:18PM" },{ "Sku": "14", "Quantity": 85, "Modified": "Nov  2 2018  8:18PM" },{ "Sku": "15", "Quantity": 58, "Modified": "Nov  2 2018  8:18PM" },{ "Sku": "16", "Quantity": 2, "Modified": "Nov  2 2018  8:18PM" },{ "Sku": "17", "Quantity": 48, "Modified": "Nov  2 2018  8:18PM" },{ "Sku": "18", "Quantity": 68, "Modified": "Nov  2 2018  8:18PM" },{ "Sku": "19", "Quantity": 67, "Modified": "Nov  2 2018  8:18PM" },{ "Sku": "2", "Quantity": 5, "Modified": "Nov  6 2018 11:18PM" },{ "Sku": "20", "Quantity": 37, "Modified": "Nov  2 2018  8:18PM" },{ "Sku": "21", "Quantity": 54, "Modified": "Nov  2 2018  8:18PM" },{ "Sku": "22", "Quantity": 21, "Modified": "Nov  2 2018  8:18PM" },{ "Sku": "23", "Quantity": 46, "Modified": "Nov  2 2018  8:18PM" },{ "Sku": "24", "Quantity": 55, "Modified": "Nov  2 2018  8:18PM" },{ "Sku": "25", "Quantity": 21, "Modified": "Nov  2 2018  8:18PM" },{ "Sku": "26", "Quantity": 42, "Modified": "Nov  2 2018  8:18PM" },{ "Sku": "27", "Quantity": 65, "Modified": "Nov  2 2018  8:18PM" },{ "Sku": "28", "Quantity": 74, "Modified": "Nov  2 2018  8:18PM" },{ "Sku": "29", "Quantity": 33, "Modified": "Nov  2 2018  8:18PM" },{ "Sku": "3", "Quantity": 51, "Modified": "Nov  2 2018  8:18PM" },{ "Sku": "4", "Quantity": 96, "Modified": "Nov  2 2018  8:18PM" },{ "Sku": "5", "Quantity": 27, "Modified": "Nov  6 2018 11:18PM" },{ "Sku": "6", "Quantity": 13, "Modified": "Nov  2 2018  8:18PM" },{ "Sku": "7", "Quantity": 54, "Modified": "Nov  2 2018  8:18PM" },{ "Sku": "8", "Quantity": 89, "Modified": "Nov  2 2018  8:18PM" },{ "Sku": "9", "Quantity": 56, "Modified": "Nov  2 2018  8:18PM" }
]

OK! We’ve got data, now we just need to make it pretty and email it to someone we don’t like. How are we going to do that? With SendGrid!

好! 我们有数据,现在只需要使其漂亮,然后通过电子邮件将其发送给我们不喜欢的人即可。 我们该怎么做? 使用SendGrid!

SendGrid设置 (SendGrid setup)

SendGrid is a nifty service with a really nice dashboard. You will like it. Or you won’t. Either way, you have to use it to get through this blog post.

SendGrid是一个很棒的服务,具有非常好的仪表板。 你会喜欢它。 否则你不会。 无论哪种方式,您都必须使用它来浏览此博客文章。

You can create a free account if you don’t already have one. That’s plenty for what we’re doing here today.

如果您还没有免费帐户,则可以创建一个免费帐户。 对于我们今天在这里所做的事情来说,这已经足够了。

Once you create a report, SendGrid is going to drop you into your “dashboard”. From this dashboard, you need to create a new API Application and get the key.

创建报告后,SendGrid将使您进入“仪表板”。 从此仪表板,您需要创建一个新的API应用程序并获取密钥。

Make sure you copy your API key when it gives it to you. You can’t ever get back to it and you’ll have to do this all over again. Let’s face it: it was kinda boring the first time around.

确保将API密钥提供给您时将其复制。 您再也无法恢复原状,您将不得不重新做一遍。 让我们面对现实:这是第一次很无聊。

Copy that key into your Azure Functions project. Put it in the local.settings.json file so you can access it as a Node.js environment variable later.

将该密钥复制到您的Azure Functions项目中。 将其放在local.settings.json文件中,以便以后可以将其作为Node.js环境变量进行访问。

{"IsEncrypted": false,"Values": {"AzureWebJobsStorage": "DefaultEndpointsProtocol=https;AccountName=reporttimerstorage;AccountKey=OJVYCHI0GhtIm5XZdsDzGZFraJD/v/rfPwMSu4B72Kf5/O7oCrOQKNAFkQ==","FUNCTIONS_WORKER_RUNTIME": "node","SENDGRID_API_KEY": "SG.rlpDOy3EQNOTChnzpa1COPYg.G4MYlEYhwHk0RyvuGcY_xKEYbhQoFTtPB9A9-5ZaYQ"}
}

Now we are going to create a template in SendGrid. That’s what we will use to design our report. SendGrid has something called “Transactional Templates”. I have no idea why they are called that, but we are going to be needing one.

现在,我们将在SendGrid中创建一个模板。 这就是我们将用来设计报告的内容。 SendGrid有一个称为“事务模板”的东西。 我不知道为什么要这样称呼他们,但我们将需要一个。

Once you create a new one, you have to create a new “version”. I had a hilariously hard time figuring this out. But then again, my brain is tad on the smallish side of little.

创建新版本后,您必须创建一个新的“版本”。 我很难解决这个问题。 但是话又说回来,我的大脑在小小的一面。

Choose to design your template with the Code Editor. You don’t need no freakin’ Designer Editor!

选择使用代码编辑器设计模板。 您不需要任何freakin'Designer编辑器!

SendGrid support handlebars, which is a template syntax that’s so easy, even I can do it. In the Code Editor, you can paste the JSON data into the “Test Data” tab…

SendGrid支持把手,这是一个模板语法,非常简单,即使我也可以做到。 在代码编辑器中,您可以将JSON数据粘贴到“测试数据”标签中…

Now iterate over the data using its key name from the JSON…

现在,使用来自JSON的键名遍历数据…

It’s BEAUTIFUL! I’m crying. Ship it.

真漂亮! 我在哭 装运它。

ALRIGHT. Fine. We’ll make it a little nicer on the old eyeballs. Here is a style that I shamelessly ripped off of the gorgeous Bulma CSS framework.

好的。 精细。 我们将在旧的眼球上使它更好一点。 这是我从华丽的Bulma CSS框架中毫不客气地撕下的样式 。

<style>table {border-collapse: collapse;border-spacing: 0;background-color: white;color: #363636;}.table td,.table th {border: 1px solid #dbdbdb;border-width: 0 0 1px;padding: 0.5em 0.75em;vertical-align: top;}.table th {color: #363636;text-align: left;}.table thead td,.table thead th {border-width: 0 0 2px;color: #363636;}.table tbody tr:last-child td,.table tbody tr:last-child th {border-bottom-width: 0;}.table.is-bordered td,.table.is-bordered th {border-width: 1px;}.table.is-bordered tr:last-child td,.table.is-bordered tr:last-child th {border-bottom-width: 1px;}.table.is-fullwidth {width: 100%;}.container {margin: 0 auto;position: relative;max-width: 960px;padding-top: 20px;font-family: helvetica, sans-serif;}
</style><div class="container"><h1>Modified SKUs</h1><p>The following SKU's were modified in the last 24 hours</p><table class="table is-fullwidth"><thead><tr><th>Sku</th><th>Quantity</th><th>Last Modified</th></tr></thead><tbody>{{#each Skus}}<tr><td>{{Sku}}</td><td>{{Quantity}}</td><td>{{Modified}}</td></tr>{{/each}}</tbody></table>
</div>

It’s ok at this point for you to be audibly impressed.

此时,可以给您留下深刻的印象。

Now you might have noticed that the Subject of the email is missing. How do we fill that in? Well, after another embarrassing period of failure followed by introspection, I figured out that it’s behind the “Settings” icon on the left. You just have to pass a value in your JSON for “Subject”.

现在您可能已经注意到电子邮件的主题丢失。 我们如何填写呢? 好吧,在经历了令人尴尬的失败和自省之后,我发现它位于左侧的“设置”图标后面。 您只需要在JSON中为“主题”传递一个值。

Now we need to get the template ID and add it to our Azure Functions project. Save this template and select the ID from the main template screen.

现在,我们需要获取模板ID,并将其添加到我们的Azure Functions项目中。 保存此模板,然后从主模板屏幕中选择ID。

Drop it in the trusty local.settings.json file right underneath your SendGrid API key.

将其放置在SendGrid API密钥下方的可信任的local.settings.json文件中。

{"IsEncrypted": false,"Values": {"AzureWebJobsStorage": "DefaultEndpointsProtocol=https;AccountName=reporttimerstorage;AccountKey=OJVYCHI0GhtIm5XZdsDzGZFraJD/v/rfPwMSu4B72Kf5/O7oCrOQKNAFkQ==","FUNCTIONS_WORKER_RUNTIME": "node","SENDGRID_API_KEY": "SG.rlpDOy3EQNOTChnzpa1COPYg.G4MYlEYhwHk0RyvuGcY_xKEYbhQoFTtPB9A9-5ZaYQ""SENDGRID_TEMPLATE_ID": "d-3e33c1453cf7457fb06e6d30519bd422"}
}

Now we are ready to pass our data from our Azure Function to SendGrid and send out this incredible work of business art.

现在,我们准备将数据从Azure功能传递到SendGrid,并发送这种令人难以置信的商业艺术品。

Azure函数的SendGrid绑定 (SendGrid bindings for Azure Functions)

Azure Functions provides a binding for SendGrid. If you create a function through the Azure Portal, it will create this binding for you when you select the “SendGrid” template. If you are doing it locally like I am, you have to add it yourself.

Azure Functions为SendGrid提供了绑定。 如果通过Azure门户创建函数,则在选择“ SendGrid”模板时将为您创建此绑定。 如果您像我一样在本地进行操作,则必须自己添加。

First you need to open the function.json file for the CreateReport function and add in the SendGrid binding.

首先,您需要打开CreateReport函数的function.json文件,并添加SendGrid绑定。

{"type": "sendGrid","name": "message","apiKey": "SENDGRID_API_KEY","to": "youremail@company.com","from": "hahabusiness@businesstime.com","direction": "out"
}

The SendGrid binding comes as an extension for Azure Functions. Run the following command in the terminal to install it.

SendGrid绑定是Azure功能的扩展。 在终端中运行以下命令进行安装。

Microsoft.Azure.WebJobs.Extensions.SendGrid -Version 3.0.0

When you run this command, VS Code will ask you to restore some dependencies. You can click restore. Nothing bad will happen…OR WILL IT?!

当您运行此命令时,VS Code将要求您还原一些依赖项。 您可以单击还原。 不会发生任何坏事...或者会吗?

One other thing you need to do is tweak your extensions.csproj file to reference the latest SendGrid library. This is required to use dynamic templates.

您需要做的另一件事是调整extensions.csproj文件以引用最新的SendGrid库。 这是使用动态模板所必需的。

<PackageReference Include="Sendgrid" Version="9.10.0" />

When you add that, VS Code will prompt you to restore again and yes, you definitely need to do it this time. VS Code needs to build these binaries and the restore does that.

添加后,VS Code会提示您再次还原,是的,您这次肯定需要这样做。 VS Code需要构建这些二进制文件,然后还原即可完成。

OK! Now we’re ready to send an email via our SendGrid template. Here is the code to do it. It’s depressingly simple. I know after all this you were hoping for enough code to choke a cat (what? you’ve never heard that metaphor before?), but this is all it takes.

好! 现在,我们准备通过我们的SendGrid模板发送电子邮件。 这是执行此操作的代码。 令人沮丧的简单。 我知道所有这些之后,您希望有足够的代码来扼杀猫(这是什么?您以前从未听说过这种隐喻吗?),但这就是全部。

function sendEmail(context, data) {context.done(null, {message: {/* you can override the to/from settings from function.json here if you would liketo: 'someone@someplace.com',from: 'someone@anotherplace.com'*/personalizations: [{dynamic_template_data: {Subject: `Tailwind SKU Report For ${new Date().toLocaleDateString('en-US',options)}`,Skus: data}}],template_id: process.env.SENDGRID_TEMPLATE_ID}});
}

The items of note are me passing in a Subject as part of the JSON. As well as the fact that you can override to/from addresses specified in the function.json file here.

注意事项是我传入了Subject作为JSON的一部分。 以及您可以覆盖此处/来自function.json文件中指定的地址的事实。

Now you can run your function and wait 24 hours to test it!

现在,您可以运行您的函数并等待24小时进行测试!

No but seriously — how do you manually test a Timer Trigger without constantly modifying the damn Cron Job?

不,但是很认真-您如何在不不断修改该死的Cron Job的情况下手动测试计时器触发器?

I’ll show you how I do it and then you can figure out a better way.

我将向您展示如何做到这一点,然后您可以找出一种更好的方法。

使用http触发器测试计时器触发器 (Testing timer triggers with http triggers)

I create an Http Trigger in the same project and call it “RunCreateReport”. In that function, I just import and call the timer function.

我在同一项目中创建一个Http触发器,并将其称为“ RunCreateReport”。 在该函数中,我只是导入并调用timer函数。

const index = require('../CreateReport/index');module.exports = function(context, req) {// This is a tester function that manually executes the CreateReport timer functionindex(context);
};

The only drawback to this is that you have to repeat your SendGrid binding settings from function.json in the “CreateReport” over in the “RunCreateReport” function.json. But other than that, this works just fine. Now you can run this thing, fire up a browser and hit the URL which will call the timer function immediately. You can test without having to touch that icky old Cron expression.

这样做的唯一缺点是,必须在“ RunCreateReport” function.json的“ CreateReport”中重复执行function.json中的SendGrid绑定设置。 除此之外,这还行得通。 现在您可以运行该程序,启动浏览器并单击URL,该URL将立即调用timer函数。 您可以进行测试,而无需触碰那个令人讨厌的Cron旧表达式。

哈哈业务 (HAHA business)

Now go check your email and bask in the glory of the report. Note that you don’t have to own an email address to send from SendGrid. You can literally send from any address. Seriously. Go ahead and try. JUST THINK OF WHAT YOU CAN DO WITH THIS POWER.

现在,请检查您的电子邮件,并仔细阅读报告的内容。 请注意,您不必拥有要从SendGrid发送的电子邮件地址。 您可以从任何地址直接发送。 说真的 继续尝试。 只需考虑一下您可以使用此功能做什么。

Here’s what my inbox looks like. Heads up, it does go to junk. Probably because I don’t own the sender email address.

这是我的收件箱的样子。 抬起头,它确实会变成垃圾。 可能是因为我没有发件人的电子邮件地址。

WHAT? There’s a “Business Resilience Conference”? OMG so much business. I bet those people get a LOT of reports.

什么? 有“业务弹性会议”吗? OMG生意这么好。 我敢打赌那些人会得到很多报道。

You can get this project from Github.

您可以从Github获得该项目。

burkeholland/serverless-sendgrid-reportContribute to burkeholland/serverless-sendgrid-report development by creating an account on GitHub.github.com

burkeholland / serverless- sendgrid-report通过在GitHub上创建一个帐户来为burkeholland / serverless-sendgrid-report开发做出贡献。 github.com

Here are a few other Azure Functions resources to keep you busy.

这是其他一些Azure Functions资源,可让您保持忙碌。

  • Deploy to Azure using Azure Functions

    使用Azure Functions部署到Azure

  • Azure Functions JavaScript developer guide

    Azure Functions JavaScript开发人员指南

  • Migrating a Mongo DB API to Azure Functions

    将Mongo DB API迁移到Azure函数

翻译自: https://www.freecodecamp.org/news/how-to-build-a-serverless-report-server-with-azure-functions-and-sendgrid-3c063a51f963/

azure服务器

azure服务器_如何使用Azure Functions和SendGrid构建无服务器报表服务器相关推荐

  1. minecraft服务器_如何使用Minecraft领域设置简单的无压力Minecraft服务器

    minecraft服务器 There are a lot of ways to go about hosting a Minecraft game but it's tough to beat the ...

  2. sql azure 语法_如何使用Azure门户,Cloud Shell和T-SQL复制Azure SQL数据库

    sql azure 语法 This article will provide an overview covering programmatically moving databases on the ...

  3. sql azure 语法_什么是Azure SQL Cosmos DB?

    sql azure 语法 介绍 (Introduction) In the Azure Portal, you will find the option to install Azure SQL Co ...

  4. sql azure 语法_深入了解Azure Data Studio:扩展和Azure SQL DB开发

    sql azure 语法 In the previous articles listed below, we went through the Azure Data Studio tool, star ...

  5. azure 使用_如何使用Azure的托管MariaDB

    azure 使用 如果微软要成功使Azure成为未来,就需要将开发人员带到其云平台. 如果我们回到PC的早期,那仍然很容易,那时仍可以构建和锁定生态系统. 但是我们生活在一个开发人员可以选择的世界中, ...

  6. azure机器学习_如何在Azure机器学习中使用JSON数据

    azure机器学习 Azure Machine Learning (also known as Azure ML) is cloud-based machine learning solution o ...

  7. aws lambda使用_如何使用AWS Lambda和S3构建无服务器URL缩短器

    aws lambda使用 by Daniel Ireson 丹尼尔·埃里森(Daniel Ireson) 如何使用AWS Lambda和S3构建无服务器URL缩短器 (How to build a S ...

  8. 华为ac配置radius认证服务器_合作生态 | 升腾威讯云系统与华为泰山服务器完成产品互认证...

    近日,福建升腾资讯有限公司与华为技术有限公司共同进行了升腾威讯云系统与华为泰山的产品测试认证. 测试结果表明:升腾威讯云系统V6在华为TaiShan 100平台上顺利安装.运行良好,且整体系统运行稳定 ...

  9. 配置iscsi服务器_在Windows Server 2016上安装和配置iSCSI目标服务器

    配置iscsi服务器 In this article, I am going to explain how we can install and configure the iSCSI Target ...

最新文章

  1. 13个对Android开发者有帮助的工具和资源(转自android吧(www.and8.com))
  2. C++AVL树(自平衡二叉查找树)(附完整源码)
  3. excel随机抽取_简单随机抽样及其进阶分层随机抽样方法展示
  4. 为什么别人学python比你快?那是因为你没掌握这几点,多注意哦~
  5. 李佳琦、薇娅联手“封杀”巴黎欧莱雅:暂停与其一切合作
  6. bootstrap table 光标_第三章之Bootstrap 表格与按钮功能
  7. 记录一次被DDOS攻击,攻击类型:UDPFLOOD
  8. Express 4.x Node.js的Web框架----《转载》
  9. 【人脸识别】基于matlab ksvd字典学习人脸表情识别【含Matlab源码 460期】
  10. linux centos7 配置ftp,Linux Centos7配置ftp服务器
  11. L298N电机驱动模块详解
  12. 基于Python的信用评分卡模型分析(强烈推荐)
  13. csv文件转为shp文件
  14. 重庆北大青鸟【学员心声】:转行是痛苦的,但决定是正确的!
  15. 食用卵磷脂市场现状及未来发展趋势
  16. 19深度探秘搜索技术_基于slop参数实现近似匹配以及原理剖析和相关实验
  17. openChannelsActivity:fail getChannelsLiveInfo:fail
  18. react修改webpack配置,添加别名
  19. 【Bilibili视频嵌入技巧】如何嵌入720PBilibili视频
  20. 文件未上传成功再次点击上传报错问题处理

热门文章

  1. C语言(谭浩强版本,主讲人:小甲鱼)P41-P49
  2. 用Python搓一个太阳系
  3. 一些好用的Linux命令工具
  4. elementPlus使用icon图标不显示解决方法
  5. 鸿蒙系统荣耀新机,鸿蒙系统要来了?网传荣耀新机搭载麒麟9000+鸿蒙OS
  6. thrift 技术分享待续
  7. 淘丞相将微博链接转为淘宝直达是怎么实现的?
  8. 【转】表情识别(一)--传统方法概述
  9. 他们为什么离开微软? 创业热情驱动
  10. EndNote实现章节后插入参考文献的方法