mvp内粗泄露问题

by Yisroel Yakovson

通过伊斯洛尔·雅科夫森

如何在一天内从MVP转到生产服务器 (How to go from MVP to Production Server in a Day)

This article follows two others about creating Full Graph Stacks. Check out How To Build A Cutting Edge Server Now for a conceptual introduction to the approach. Launch Your MVP Server In An Hour guides you through building a stack of development quality. This article explains how to convert that stack to a robust, permanent application.

本文紧跟其他两个有关创建完整图栈的问题。 立即查看如何构建最先进的服务器 ,以对该方法进行概念性介绍。 一小时内启动MVP服务器将引导您构建一整套开发质量。 本文介绍了如何将堆栈转换为健壮的永久性应用程序。

开发堆栈有什么问题? (What’s Wrong with the Development Stack?)

The steps in the second article mirrored the GRANDstack video:

第二篇文章中的步骤反映了GRANDstack视频:

  • The database is a Neo4j Sandbox

    该数据库是Neo4j沙箱

  • The APIC server runs on Now.

    APIC服务器在Now上运行。

That’s enough for an MVP or for the initial prototyping, but you’ll have to move on soon. The biggest initial limitation is the database. The sandbox will live at most ten days.

对于MVP或初始原型来说,这已经足够了,但是您将不得不继续前进。 最大的初始限制是数据库。 沙盒最多可以使用十天。

Even after you spin up a permanent database, Now would make a difficult permanent home. In theory, it would be possible if you didn’t modify your server frequently. You could set up your permanent API with a separate host and alias it to your Now endpoint. The problem is that the Now endpoint changes each time you upload a revision. That means that you have to keep updating your alias.

即使您启动了永久数据库,Now也将成为一个困难的永久家园。 从理论上讲,如果您不经常修改服务器是有可能的。 您可以使用单独的主机设置永久性API,并将其别名为Now端点。 问题在于,每次上载修订时,Now端点都会更改。 这意味着您必须继续更新别名。

Security also poses a challenge. It’s common to create a white list of IPs permitted to access your database and to limit the list to your API server. So if that server IP changes frequently, you have to update the list with each revision. I don’t see a viable way to do that with Now as of this writing. (Please reach out to me if you do!)

安全也带来了挑战。 通常会创建一个允许访问数据库的IP白名单,并将该列表限制为您的API服务器。 因此,如果该服务器IP频繁更改,则必须使用每个修订版更新列表。 在撰写本文时,我还没有一种可行的方法来使用Now。 (如果愿意,请与我联系!)

So the question is, what’s the best approach to solve these limitations?

所以问题是,解决这些局限性的最佳方法是什么?

在最前沿 (On the Cutting Edge)

The truth is, this article has been on hold for a few weeks. The problem was that neo4j-graphql-js was not quite ready to support production. But in the past few weeks, that all changed. The team solved a few fundamental problems:

事实是,本文已搁置了几个星期。 问题在于neo4j-graphql-js尚未准备好支持生产。 但是在过去的几周中,这一切都改变了。 团队解决了一些基本问题:

  • Middleware became supportable two weeks ago. The team added to the generated reducers support for throwing middleware errors. That enables your server to run general authentication and authorization functionality as middleware.

    中间件在两周前开始受支持。 该团队在生成的reducers中添加了对引发中间件错误的支持。 这使您的服务器可以将常规身份验证和授权功能作为中间件运行。

  • Modification of mutations became possible a week ago. Until then, you were stuck with the generated mutations. Now you can add necessary business logic or side effects.

    一周前可以对突变进行修饰。 在此之前,您一直对产生的突变感到困惑。 现在,您可以添加必要的业务逻辑或副作用。

  • Autogenerated keys are becoming available. The team reported yesterday a new @autogenerate directive. Placing the directive after a key will result in an autogenerated UUID. Before, the front end had to pass values in for keys, which is most unusual for a production server.自动生成的密钥变得可用。 该团队昨天报告了一个新的@autogenerate指令。 将指令放在键之后将导致自动生成的UUID。 以前,前端必须传入键值,这对于生产服务器而言是最不常见的。

This writing, on August 19, 2018, comes in the midst of many other expected fixes. Of particular interest, the team plans to release some directives to simplify auth. Also, I hope that we will soon see nested mutations. Much of what I write here will soon become outdated. But I’ve decided that it’s worth describing this package now, because it’s already useful. Please post updates or corrections below as comments.

这篇撰写于2018年8月19日的文字来自其他许多预期的修复程序中。 特别感兴趣的是,该团队计划发布一些指令以简化auth。 另外,我希望我们很快会看到嵌套的突变 。 我在这里写的大部分内容很快就会过时。 但是我认为现在值得描述这个软件包,因为它已经很有用了。 请在下面发布更新或更正作为评论。

选件 (Options)

When you leave the world of sandboxes, you have choices. I think that the general rule is that today most are fine. The important thing is to move forward.

当您离开沙箱世界时,您将有选择。 我认为一般规则是今天大多数情况都很好。 重要的是要前进。

But the three basic steps that I discuss below are probably universal needs. They may be all that you need for your back end.

但是我下面讨论的三个基本步骤可能是普遍需要。 它们可能是您后端所需的全部。

Two introductory observations:

两个介绍性观察:

  • You don’t need to get things perfect from day 1. There was a time when decisions like the size of your machine or your host had long-term significance. Today any sensible team works in the cloud. Most decisions are reversible. Auth may an exception, but even that may be changing. Get something live and start pivoting!从第一天起,您就不需要使事情变得完美。有时候,诸如机器大小或主机大小之类的决策具有长期意义。 今天,任何明智的团队都可以在云中工作。 大多数决定都是可逆的。 Auth可能是一个例外,但即使这样也可能正在发生变化。 现场直播并开始旋转!
  • If you followed the steps in Launch Your MVP Server In An Hour, you have an amazingly small back end. You will need three components: your tiny server app, your database, and an auth service. You don’t even have to store them with the same host.

    如果按照“ 在一小时内启动MVP服务器”中的步骤进行操作,则后端将非常小。 您将需要三个组件:小型服务器应用程序,数据库和身份验证服务。 您甚至不必将它们存储在同一主机上。

内容 (Contents)

  1. Set up Auth

    设置身份验证

  2. Spin your Database

    旋转数据库

  3. Create Your Server

    创建您的服务器

设置身份验证 (Set up Auth)

Every project’s auth needs are different, but some basics have emerged. You need two things:

每个项目的身份验证需求都是不同的,但是已经出现了一些基础知识。 您需要两件事:

  1. En external authentication service. Two common choices are Cognito and Auth0.启用外部身份验证服务。 两种常见的选择是Cognito和Auth0。
  2. Most servers also need authorization, or access control. You have to decide whether a particular user is allowed to do something.大多数服务器还需要授权或访问控制。 您必须决定是否允许特定用户做某事。

设置中间件功能 (Setting up Middleware Capability)

The preferred way to handle Auth is through middleware or directives. As of the current writing, auth is not included in the GRANDstack starter.

处理Auth的首选方法是通过中间件或指令。 截至目前,auth未包含在GRANDstack启动器中。

The server used in api/src/index.jx in the starter package is currently ApolloServer. But you can replace that with graphalExpress from apollo-server-express.

入门包中api/src/index.jx中使用的服务器当前是ApolloServer 。 但是您可以使用apollo-server-express graphalExpress替换它。

You will have to change 2 files:

您将必须更改2个文件:

  • api/src/index.js

    api/src/index.js

  • api/package.json

    api/package.json

You should also add an auth.js file.

您还应该添加一个auth.js文件。

Here’s a version of index.js that currently works with middleware:

这是当前可与中间件一起使用的index.js版本:

import express from 'express';import { graphqlExpress, graphiqlExpress } from 'apollo-server-express';import cors from 'cors';import { makeExecutableSchema } from 'graphql-tools'import expressPlayground from 'graphql-playground-middleware-express';import bodyParser from 'body-parser';require('dotenv').config();import { v1 as neo4j } from "neo4j-driver";import { augmentSchema } from "neo4j-graphql-js";import { typeDefs, resolvers } from "./graphql-schema";import { authenticateUser, authorize } from './auth';// augmentSchema will add autogenerated mutations based on types in schemaconst schema = makeExecutableSchema({  typeDefs,  resolvers});const augmentedSchema = augmentSchema(schema);const driver = neo4j.driver(  process.env.NEO4J_URI,  neo4j.auth.basic(    process.env.NEO4J_USER,    process.env.NEO4J_PASSWORD  ));const app = express();app.use(bodyParser.json()); // support json encoded bodiesapp.use(cors());app.use('/graphql i apollo-server-expressql', graphiqlExpress({  endpointURL: '/graphql'}));app.get('/', expressPlayground({ endpoint: '/graphql' }));// app.use('/', authenticateUser, authorize);app.use('/graphql', bodyParser.json(), graphqlExpress(req => {  return {    context:  {      auth: req.auth,      driver    },    endpointURL: '/graphql',    schema: augmentedSchema  }}));app.listen(process.env.GRAPHQL_LISTEN_PORT, '0.0.0.0');console.log(`GraphQL Playground at ${process.env.GRAPHQL_LISTEN_PORT}`);

Note that:

注意:

  1. We are using apollo-server-express, which supports middleware我们正在使用支持中间件的apollo-server-express
  2. Two functions are called as middleware: authenticateUser and authorize. Both definitions appear in auth.js.有两个功能称为中间件:authenticateUser和authorize。 这两个定义都出现在auth.js中。
  3. I also added cors, which we needed to resolve some CORS issues.我还添加了cors,我们需要它解决一些CORS问题。

The project.json file must contain the proper dependencies. As of this writing, here are the versions I’m using:

project.json文件必须包含适当的依赖项。 在撰写本文时,这是我正在使用的版本:

{  "name": "grand-stack-express",  "version": "0.0.1",  "description": "API app for GRANDstack with express",  "main": "src/index.js",  "license": "MIT",  "dependencies": {    "apollo-server-express": "^1.3.6",    "babel-cli": "^6.26.0",    "babel-core": "^6.26.3",    "babel-polyfill": "^6.26.0",    "babel-preset-env": "^1.7.0",    "babel-preset-stage-0": "^6.24.1",    "babel-watch": "^2.0.7",    "body-parser": "^1.18.3",    "cors": "^2.8.4",    "dotenv": "^6.0.0",    "express": "^4.16.3",    "express-graphql": "^0.6.12",    "graphql-playground-middleware-express": "^1.7.1",    "graphql-tag": "^2.9.2",    "graphql-tools": "^3.0.4",    "neo4j-driver": "^1.6.3",    "neo4j-graphql-js": "^0.1.32",    "node-fetch": "^2.1.2",    "nodemon": "^1.17.5"  },  "resolutions": {    "neo4j-graphql-js/graphql": "v14.0.0-rc.2"  },  "scripts": {    "test": "echo \"Error: no test specified\" && exit 1",    "dev": "babel-watch --exec babel-node --presets env,stage-0 src/index.js",    "start": "nodemon --exec babel-node --presets env,stage-0 src/index.js"  },  "devDependencies": {    "nodemon": "^1.17.5"  }}

Here’s a starter auth.js file to add to your project and complete:

这是要添加到您的项目并完成的入门auth.js文件:

import gql from 'graphql-tag'import { v1 as neo4j } from 'neo4j-driver';import { INSPECT_MAX_BYTES } from 'buffer';require('dotenv').config();const driver = neo4j.driver(  process.env.NEO4J_URI,  neo4j.auth.basic(    process.env.NEO4J_USER,    process.env.NEO4J_PASSWORD  ));const resolveUser = () => {  //a placeholder  return 0;}/* * middleware functions follow */export const authenticateUser = async (req, res, next) => {  req.auth={};  try {    const response = await resolveUser();    req.auth.user=response  } catch(err) {    req.error=err.message  }  next();}export const authorize = async (req, res, next) => {  if (req.error) {    console.log(req.error);    next();    return;  }  // placeholder, allows every authenticated request  next();}
  1. start by committing your old version to git and probably creating a new branch. git add . then git commit -m "works without auth" and then git checkout -b auth. You will then see a response of

    首先将旧版本提交到git并可能创建一个新分支。 git add . 然后git commit -m "works without auth" ,然后git checkout -b auth 。 然后,您将看到对

    start by committing your old version to git and probably creating a new branch. git add . then git commit -m "works without auth" and then git checkout -b auth. You will then see a response of Switched to a new branch ‘auth’

    首先将旧版本提交到git并可能创建一个新分支。 git add . 然后git commit -m "works without auth" ,然后git checkout -b auth 。 然后,您将看到Switched to a new branch 'auth'的响应

  2. replace your api/src/index.js and api/project.json files with the versions above, and add the auth.js file to api/src.

    api/src/index.jsapi/project.json文件替换为上述版本,然后将auth.js文件添加到api/src

  3. move your current node_modules: mv node_modules node_modules.old

    移动当前的node_modules: mv node_modules node_modules.old

  4. run npm install again, then npm start. Make sure that it works by running a query.

    再次运行npm install ,然后再npm start 。 通过运行查询确保它可以工作。

添加您的身份验证服务 (Add Your Authentication Service)

You can fill in the details based on the SDK for whatever auth software you use.

您可以根据使用的任何身份验证软件的SDK填写详细信息。

You may have to study up on using async/await functions in an express app, but it’s not too difficult to learn.

您可能需要研究在快速应用程序中使用异步/等待功能 ,但是学习起来并不难。

  1. Uncomment the line app.use(‘/’, authenticateUser, authorize); in index.js.

    取消注释行app.use('/', authenticateUser, authorize);index.js

  2. Install the proper Node js SDK for your Authentication service. Then add the needed code and rewrite the function authenticateUser in auth.js to call it. Remember to set req.error to an appropriate error message when authentication fails.

    为您的身份验证服务安装正确的Node js SDK。 然后添加所需的代码,并在auth.js重写函数authenticateUser进行调用。 当身份验证失败时,请记住将req.error设置为适当的错误消息。

  3. Practice by adding a valid token to the HTTP Header. Note that in Playground the HTTP HEADERS panel makes this quite simple.通过将有效令牌添加到HTTP标头进行练习。 请注意,在Playground中,HTTP HEADERS面板使这一过程变得非常简单。

添加授权 (Add Authorization)

The file auth.js includes a database driver. The driver supports querying to determine a user’s access rights to specific data. For instance, your database could store read/write privileges for data. Whenever a request fails your test, you can specify what failed by setting req.error. The neo4jgraphql resolver function will return the error message.

文件auth.js包含数据库驱动程序。 该驱动程序支持查询以确定用户对特定数据的访问权限。 例如,您的数据库可以存储数据的读/写特权。 每当请求测试失败时,您都可以通过设置req.error来指定失败的req.errorneo4jgraphql解析器函数将返回错误消息。

Note that you can add more functions to the middleware. For instance, you might add a check whether the current user is fully paid.

请注意,您可以向中间件添加更多功能。 例如,您可以添加检查当前用户是否已全额付款。

增强AugmentSchema (Enhancing AugmentSchema)

The call to augmentSchema in the index.js file generates the mutations in your schema. As stated above, a recent enhancement lets you add mutations. You can also overwrite the generated ones.

index.js文件中对augmentSchema的调用会在您的模式中生成突变。 如上所述,最近的增强使您可以添加突变。 您也可以覆盖生成的内容。

One simple way is with the @cypher directive in your mutation declaration:

一种简单的方法是在您的突变声明中使用@cypher指令:

type Mutation { UpdateFoo(id: ID, name: String): Foo @cypher(statement:”MATCH (f:Foo {id: $id}) SET f.name = $name”}

Then, for the resolver just use neo4jgraphql:

然后,对于解析器,只需使用neo4jgraphql

Mutation: { UpdateFoo: neo4jgraphql}

数据库托管 (Database Hosting)

You have some options. First, there are some hosting services. I wasn’t so impressed, because it’s not that hard to create a database server yourself. But, the cost is a drop in the bucket compared to your team’s time. If you pay a few hundred dollars a month to get something up and running, and you have no worries, you could do a lot worse.

您有一些选择。 首先,有一些托管服务 。 我没有那么印象深刻,因为自己创建数据库服务器并不难。 但是,与您团队的时间相比,成本简直是九牛一毛。 如果您每个月花费几百美元来启动和运行某项产品,并且没有后顾之忧,则可能会做得更糟。

基本托管 (Basic Hosting)

I decided to spin up an AWS EC2 instance instead. I’m going to write what I did there.

我决定改为启动一个AWS EC2实例。 我要写在那里做的事。

  1. Decide your region. Might not matter much, but if you are centered somewhere then go for it.确定您的地区。 可能无关紧要,但是如果您位于某个地方的中心,那就去吧。
  2. Get the AWS CLI working working on your computer.使AWS CLI在您的计算机上正常工作。
  3. Get hold of an appropriate AMI. You can search on the AWS store, or check out what’s available.掌握适当的AMI。 您可以在AWS商店中搜索,或查看可用的内容。
  4. Do the steps (until the last one) here. Make sure to save your key file, as you’ll need it for setting up APOC.

    在这里执行步骤(直到最后一个步骤)。 确保保存密钥文件,因为设置APOC时将需要它。

  5. Then you need to go to the page, log in and change the password. But which port to go to and what password might not be the same as there. For my AMI, the password was “neo4j” (like the user name). I had to go to https://[IP]:7473/browser/ (not http as in the example given on the page, and not 7434).

    然后,您需要转到该页面,登录并更改密码。 但是,要转到哪个端口,什么密码可能与那里的密码不同。 对于我的AMI,密码为“ neo4j”(类似于用户名)。 我必须转到https:// [IP]:7473 / browser / (不是页面上给出的示例中的http,而不是7434)。

  6. Change your code on your local to be sure that you can connect to it. Check it on your localhost:4000.在本地更改代码,以确保可以连接到它。 在您的本地主机上检查它:4000。

设置APOC (Setting up APOC)

To use @cypher directives, or any of the APOC functions, you’ll have to to install the APOC jar file on the server itself. You’ll need to ssh in to your database server. As of 2 months ago, it wasn’t included in the AMIs.

要使用@cypher指令或任何APOC函数,您必须在服务器本身上安装APOC jar文件。 您需要ssh进入数据库服务器。 截至2个月前,它尚未包含在AMI中。

  1. You’ll need to use the command shown at Hosting Neo4j on EC2 on AWS: ssh -i $KEY_NAME.pem ubuntu@[PublicDnsName]

    您需要使用在AWS上的EC2上托管Neo4j上显示的命令: ssh -i $KEY_NAME.pem ubuntu@[PublicDnsName]

  2. You’ll have to add the jar file to the neo4j plugins directory. Follow the manual instructions to find the latest release and figure out where to insert it.

    您必须将jar文件添加到neo4j插件目录中。 请按照手册中的说明查找最新版本,并找出在何处插入。

  3. You also need to find your neo4j.conf file and insert into it permission to call the functions. The following works: dbms.security.procedures.unrestricted=apoc.*

    您还需要找到neo4j.conf文件,并在其中插入调用这些函数的权限。 以下工作: dbms.security.procedures.unrestricted=apoc.*

  4. Then you’ll have to restart: sudo systemctl restart neo4j.

    然后,您必须重新启动: sudo systemctl restart neo4j.

API部署 (API Deployment)

You can deploy on any system that supports a NODE js app. I used AWS Elastic Beanstalk:

您可以在支持NODE js应用程序的任何系统上进行部署。 我使用了AWS Elastic Beanstalk :

  1. Run the command zip -r api.zip . -x node_modules/**\*in the api directory. That creates a zip without the directory itself and without the node_modules.

    运行命令zip -r api.zip . -x node_modules/**\* api目录中的zip -r api.zip . -x node_modules/**\* 。 这将创建一个没有目录本身且没有node_modules的zip。

  2. Go to AWS Elastic Beanstalk in the console and make sure you’re in your region of choice.

    在控制台中转到AWS Elastic Beanstalk ,并确保您位于选择的区域中。

  3. If you can get to the welcome page, I find it the easiest. You click on Get Started, and follow the instructions. They set me up right away with what I needed. You just upload the file that you zipped above.

    如果可以访问欢迎页面,我觉得这是最简单的。 您单击开始 ,然后按照说明进行操作。 他们立即根据我的需要设置了我。 您只需上传压缩过的文件即可。

  4. nder Configuration for the Elastic Beanstalk environment, go to Modify Software. Enter Container Options, and set Node Command to npm start.

    在“ Elastic Beanstalk环境”的“ 配置”下 ,转到“ 修改软件” 。 输入Container Options ,然后将Node Command设置为npm start

  5. After about 10 minutes, it’s ready. You can click on the endpoint URL to see it.

    大约10分钟后,它准备就绪。 您可以单击端点URL来查看它。

  6. Use Route53 to alias your own api domain to the Elastic Beanstalk endpoint, and you’re all set.使用Route53将您自己的api域别名为Elastic Beanstalk端点,一切就绪。

结论 (Conclusions)

If you’ve followed this far, congratulations. You know more about how to build a full graph stack than many seasoned back end designers.

如果您遵循了这一步,那么恭喜。 与许多经验丰富的后端设计师相比,您对如何构建完整的图形堆栈了解更多。

The process described in these articles might take an hour for someone who has done them a few times. For anyone else, these articles hopefully minimize the extra time to research. The development time should fall even more as these tools improve.

这些文章中描述的过程可能需要花费一个小时来完成几次。 对于其他任何人,这些文章都希望将额外的研究时间减至最少。 随着这些工具的改进,开发时间应进一步减少。

But simplicity and ease are just one benefit. The full graph stack is also technologically sound.

但是,简单和轻松只是好处之一。 完整的图形堆栈在技术上也很合理。

  • The server created here is robust.此处创建的服务器功能强大。
  • A graph database in general scales brilliantly.一般而言,图形数据库具有出色的伸缩性。
  • The stack uses very few resources.堆栈使用很少的资源。
  • You can port the back end to different hosts or services, reducing lock-in and fees.您可以将后端移植到不同的主机或服务,从而减少锁定和费用。

Let us work together to keep this technology moving. Please leave comments or reach out with other improvements. Good luck with your own projects!

让我们共同努力,使这项技术不断发展。 请发表评论或进行其他改进。 祝您自己的项目好运!

翻译自: https://www.freecodecamp.org/news/making-your-full-graph-stack-production-quality-ec231a938551/

mvp内粗泄露问题

mvp内粗泄露问题_如何在一天内从MVP转到生产服务器相关推荐

  1. mvp内粗泄露问题_如何在一小时内启动MVP服务器

    mvp内粗泄露问题 by Yisroel Yakovson 通过伊斯洛尔·雅科夫森 如何在一小时内启动MVP服务器 (How to Launch Your MVP Server in an Hour) ...

  2. 内网异地备份_用批处理实现局域网内的异地备份

    用批处理实现局域网内的异地备份 Post by 晨曦之家 , 2011-1-19, Views:121 我们平时在服务器上会用备份软件或者数据库维护计划来备份我们的数据库, 在重装系统或 者数据库损坏 ...

  3. mvp中的m作用_将M放入MVP

    mvp中的m作用 by Howard Lo 霍华德·罗 将M放入MVP (Putting the M in MVP) Years ago, I thought I knew what my minim ...

  4. 机器学习算法如何应用于控制_将机器学习算法应用于NBA MVP数据

    机器学习算法如何应用于控制 A step-by-step tutorial in R R中的分步教程 1引言 (1 Introduction) This blog makes up the Machi ...

  5. mysql内连接部门平均值_详解MySql基本查询、连接查询、子查询、正则表达查询_MySQL...

    查询数据指从数据库中获取所需要的数据.查询数据是数据库操作中最常用,也是最重要的操作.用户可以根据自己对数据的需求,使用不同的查询方式.通过不同的查询方式,可以获得不同的数据.MySQL中是使用SEL ...

  6. 登录时判断用户还是管理员_高低温试验仪器出现内漏时如何判断是高压还是低压内漏?...

    高低温试验仪器出现内漏时,首先要断定是高压内漏仍是低压内漏.有关资料介绍用切割加表试漏的方法,对于微漏则需求较长的查询时间,且操作较凌乱,现介绍一种简略的区分方法: 我们都知道,高低温试验仪器内漏的具 ...

  7. php中表单输出成绩,js内置对象处理_打印学生成绩单的简单实现

    任务: 1.通过js的内置对象得到当前日期 var date=new Date(); var year=date.toString().slice(11,15); document.write(yea ...

  8. tomcat 热部署 生产环境_屋顶隔热改善舍内热环境及生产性能

    鸡舍屋顶夏季所接收辐射热最多,屋顶内表面与舍内空气对流换热作用较强,舍内垂直温差加剧,造成局部热应激影响蛋鸡生产性能. 为探究屋顶隔热对蛋鸡舍内热环境及蛋鸡生产性能的影响,对比研究试验舍(100mm  ...

  9. 7怎样设置禁网_怎样才能提升网站内页的收录?

    1.提高网站的内容质量,文章尽可能的原创.搜索引擎蜘蛛更喜爱原创的高质量内容,能够缩短网站的审核期. 2.良好的网站结构,继续搜索引擎的匍匐与抓取.现在一般都是div+css的结构,不要运用table ...

最新文章

  1. webpack 项目使用 html-webpack-plugin(3)
  2. Unity 2D游戏开发快速入门(内部资料)
  3. Eclipse集成Tomcat:6个常见的”how to”问题
  4. 学习笔记(二)——CSS基础
  5. spring boot热部署devtools
  6. zoj2271 Chance to Encounter a Girl(DP)
  7. LSTM 与 Bilstm介绍(包含代码实现、Python)
  8. BZOJ 1486 最小圈(二分+判负环)
  9. shell脚本中if流程控制语句的应用
  10. 多通道卷积的参数数量计算
  11. 解决ASP.NET中Redis 每小时6000次访问请求的问题
  12. 第七次作业 numpy统计分布显示
  13. 【基础知识】【模块介绍】8位8段数码管(74HC595)【硬件部分】
  14. 【斯坦福大学公开课CS224W——图机器学习】六、图神经网络1:GNN模型
  15. I2C协议---I2C时序图解析
  16. 医疗APP有哪些功能
  17. 云服务器gitlab,云服务器CentOS7.4下搭建GitLab
  18. html锚点链接怎么互点,通过优化网页核心关键词快速提升排名
  19. 处理Account locked due to 217 failed logins的问题
  20. 证书管理机构——CA(Certificate Authority)

热门文章

  1. 时间等待 c# 1614006220
  2. 综合演练 实现登陆功能 1124
  3. mysql数据库创建带-的数据库名
  4. iOS 推送通知及推送扩展
  5. 2015 年出现的十大流行 Python 库
  6. 《Web异步与实时交互——iframe AJAX WebSocket开发实战》—— 1.4 内容安排
  7. python logging简单使用
  8. android post、get请求数据
  9. 整合mybatis3.2.2跟spring3.0.1
  10. MFC调用Qt生成的dll